* [PATCH 1/1] BaseTools: Add FMMT Tool
@ 2021-12-01 1:29 Yuwei Chen
2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming
0 siblings, 1 reply; 6+ messages in thread
From: Yuwei Chen @ 2021-12-01 1:29 UTC (permalink / raw)
To: devel; +Cc: Bob Feng, Liming Gao
The FMMT python tool is used for firmware files operation, which has
the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function:
1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files)
2.Add a new FFS into a FV file (both included in a FD file or not)
3.Replace an FFS in a FV file with a new FFS file
4.Delete an FFS in a FV file (both included in a FD file or not)
5.Extract the FFS from a FV file (both included in a FD file or not)
Currently the FMMT C tool is saved in edk2-staging repo, but its
quality and coding style can't meet the Edk2 quality, which is hard to
maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
The new Python version keeps same functions with origin C version. It
has higher quality and better coding style, and it is much easier to
extend new functions and to maintain.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847
PR Link: https://github.com/tianocore/edk2-basetools/pull/12
RFC Link: https://edk2.groups.io/g/devel/message/82877
Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
---
V4 fixed the Linux file format issue and known bugs.
BaseTools/BinWrappers/PosixLike/FMMT | 14 +
BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 +
.../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
.../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes
BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
| 66 +++
| 112 ++++
| 110 ++++
BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
BaseTools/Source/Python/FMMT/README.md | 180 ++++++
BaseTools/Source/Python/FMMT/__init__.py | 0
.../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++
.../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
.../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
.../Source/Python/FMMT/core/FMMTParser.py | 86 +++
.../Source/Python/FMMT/core/FvHandler.py | 521 ++++++++++++++++++
.../Source/Python/FMMT/core/GuidTools.py | 152 +++++
.../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
.../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
22 files changed, 2432 insertions(+)
create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
create mode 100644 BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
create mode 100644 BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
create mode 100644 BaseTools/Source/Python/FMMT/README.md
create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTOperation.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
create mode 100644 BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
diff --git a/BaseTools/BinWrappers/PosixLike/FMMT b/BaseTools/BinWrappers/PosixLike/FMMT
new file mode 100644
index 000000000000..5f5519e1e1b6
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/FMMT
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#python `dirname $0`/RunToolFromSource.py `basename $0` $*
+
+# If a ${PYTHON_COMMAND} command is available, use it in preference to python
+if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
+ python_exe=${PYTHON_COMMAND}
+fi
+
+full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
+dir=$(dirname "$full_cmd")
+cmd=${full_cmd##*/}
+
+export PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
+exec "${python_exe:-python}" -m $cmd.$cmd "$@"
diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
new file mode 100644
index 000000000000..f0551c4ac54a
--- /dev/null
+++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
@@ -0,0 +1,4 @@
+@setlocal
+@set ToolName=%~n0%
+@set PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BASE_TOOLS_PATH%\Source\Python\FMMT
+@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
diff --git a/BaseTools/Source/Python/FMMT/FMMT.py b/BaseTools/Source/Python/FMMT/FMMT.py
new file mode 100644
index 000000000000..5028d8446ee0
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/FMMT.py
@@ -0,0 +1,117 @@
+# @file
+# Firmware Module Management Tool.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+# Import Modules
+#
+import argparse
+import sys
+from core.FMMTOperation import *
+
+parser = argparse.ArgumentParser(description='''
+View the Binary Structure of FD/FV/Ffs/Section, and Delete/Extract/Add/Replace a Ffs from/into a FV.
+''')
+parser.add_argument("--version", action="version", version='%(prog)s Version 1.0',
+ help="Print debug information.")
+parser.add_argument("-v", "--View", dest="View", nargs='+',
+ help="View each FV and the named files within each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
+parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
+ help="Delete a Ffs from FV: '-d inputfile TargetFfsName outputfile TargetFvName(Optional,\
+ If not given, wil delete all the existed target Ffs)'")
+parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
+ help="Extract a Ffs Info: '-e inputfile TargetFfsName outputfile'")
+parser.add_argument("-a", "--Add", dest="Add", nargs='+',
+ help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'")
+parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
+ help="Replace a Ffs in a FV: '-r inputfile TargetFfsName newffsfile outputfile TargetFvName(Optional,\
+ If not given, wil replace all the existed target Ffs with new Ffs file)'")
+parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
+ help="The format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future")
+
+def print_banner():
+ print("")
+
+class FMMT():
+ def __init__(self) -> None:
+ self.firmware_packet = {}
+
+ def CheckFfsName(self, FfsName:str) -> str:
+ try:
+ return uuid.UUID(FfsName)
+ except:
+ return FfsName
+
+ def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None) -> None:
+ # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
+ filetype = os.path.splitext(inputfile)[1].lower()
+ if filetype == '.fd':
+ ROOT_TYPE = ROOT_TREE
+ elif filetype == '.fv':
+ ROOT_TYPE = ROOT_FV_TREE
+ elif filetype == '.ffs':
+ ROOT_TYPE = ROOT_FFS_TREE
+ elif filetype == '.sec':
+ ROOT_TYPE = ROOT_SECTION_TREE
+ else:
+ ROOT_TYPE = ROOT_TREE
+ ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
+
+ def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
+ if Fv_name:
+ DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile, uuid.UUID(Fv_name))
+ else:
+ DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile)
+
+ def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None:
+ ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
+
+ def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
+ AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, outputfile)
+
+ def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
+ if Fv_name:
+ ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile, uuid.UUID(Fv_name))
+ else:
+ ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)
+
+
+def main():
+ args=parser.parse_args()
+ status=0
+
+ try:
+ fmmt=FMMT()
+ if args.View:
+ if args.LogFileType:
+ fmmt.View(args.View[0], args.LogFileType[0])
+ else:
+ fmmt.View(args.View[0])
+ if args.Delete:
+ if len(args.Delete) == 4:
+ fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
+ else:
+ fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
+ if args.Extract:
+ fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
+ if args.Add:
+ fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
+ if args.Replace:
+ if len(args.Replace) == 5:
+ fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3],args.Replace[4])
+ else:
+ fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])
+ # TODO:
+ '''Do the main work'''
+ except Exception as e:
+ print(e)
+
+ return status
+
+
+if __name__ == "__main__":
+ exit(main())
diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
new file mode 100644
index 000000000000..aa2444f11b38
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
@@ -0,0 +1,11 @@
+## @file
+# This file is used to define the FMMT dependent external tool guid.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
+ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
+fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
+d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
+3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
new file mode 100644
index 0000000000000000000000000000000000000000..7cc806a0133413a4aa037f1d43d80000546a5246
GIT binary patch
literal 29515
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
literal 0
HcmV?d00001
diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
new file mode 100644
index 0000000000000000000000000000000000000000..6335653ece1605cd0c53bd2cc2bc21d57d213dae
GIT binary patch
literal 79906
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
RBat2OV|2<CTVmi8`9DHIo&o>>
literal 0
HcmV?d00001
diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py b/BaseTools/Source/Python/FMMT/PI/Common.py
new file mode 100644
index 000000000000..efab874ee08b
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/Common.py
@@ -0,0 +1,81 @@
+## @file
+# This file is used to define the common C struct and functions.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from ctypes import *
+import uuid
+
+# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
+# EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
+# EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
+# EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
+
+EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
+EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
+# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
+EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
+# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
+EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
+EFI_SYSTEM_NVDATA_FV_GUID = uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
+EFI_SYSTEM_NVDATA_FV_GUID_BYTE = b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
+EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
+EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
+ZEROVECTOR_BYTE = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
+FVH_SIGNATURE = b'_FVH'
+
+class GUID(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Guid1', c_uint32),
+ ('Guid2', c_uint16),
+ ('Guid3', c_uint16),
+ ('Guid4', ARRAY(c_uint8, 8)),
+ ]
+
+ def from_list(self, listformat: list) -> None:
+ self.Guid1 = listformat[0]
+ self.Guid2 = listformat[1]
+ self.Guid3 = listformat[2]
+ for i in range(8):
+ self.Guid4[i] = listformat[i+3]
+
+ def __cmp__(self, otherguid) -> bool:
+ if not isinstance(otherguid, GUID):
+ return 'Input is not the GUID instance!'
+ rt = False
+ if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2 and self.Guid3 == otherguid.Guid3:
+ rt = True
+ for i in range(8):
+ rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
+ return rt
+
+def ModifyGuidFormat(target_guid: str) -> GUID:
+ target_guid = target_guid.replace('-', '')
+ target_list = []
+ start = [0,8,12,16,18,20,22,24,26,28,30]
+ end = [8,12,16,18,20,22,24,26,28,30,32]
+ num = len(start)
+ for pos in range(num):
+ new_value = int(target_guid[start[pos]:end[pos]], 16)
+ target_list.append(new_value)
+ new_format = GUID()
+ new_format.from_list(target_list)
+ return new_format
+
+
+# Get data from ctypes to bytes.
+def struct2stream(s) -> bytes:
+ length = sizeof(s)
+ p = cast(pointer(s), POINTER(c_char * length))
+ return p.contents.raw
+
+
+
+def GetPadSize(Size: int, alignment: int) -> int:
+ if Size % alignment == 0:
+ return 0
+ Pad_Size = alignment - Size % alignment
+ return Pad_Size
diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
new file mode 100644
index 000000000000..33c49ffb50bc
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
@@ -0,0 +1,66 @@
+## @file
+# This file is used to define the Ffs Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+EFI_FFS_FILE_HEADER_LEN = 24
+EFI_FFS_FILE_HEADER2_LEN = 32
+
+class CHECK_SUM(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Header', c_uint8),
+ ('File', c_uint8),
+ ]
+
+class EFI_FFS_INTEGRITY_CHECK(Union):
+ _pack_ = 1
+ _fields_ = [
+ ('Checksum', CHECK_SUM),
+ ('Checksum16', c_uint16),
+ ]
+
+
+class EFI_FFS_FILE_HEADER(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Name', GUID),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', ARRAY(c_uint8, 3)),
+ ('State', c_uint8),
+ ]
+
+ @property
+ def FFS_FILE_SIZE(self) -> int:
+ return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
+
+ @property
+ def HeaderLength(self) -> int:
+ return 24
+
+class EFI_FFS_FILE_HEADER2(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Name', GUID),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', ARRAY(c_uint8, 3)),
+ ('State', c_uint8),
+ ('ExtendedSize', c_uint64),
+ ]
+
+ @property
+ def FFS_FILE_SIZE(self) -> int:
+ return self.ExtendedSize
+
+ @property
+ def HeaderLength(self) -> int:
+ return 32
--git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
new file mode 100644
index 000000000000..aae2feae844a
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
@@ -0,0 +1,112 @@
+## @file
+# This file is used to define the FV Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from ast import Str
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+class EFI_FV_BLOCK_MAP_ENTRY(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('NumBlocks', c_uint32),
+ ('Length', c_uint32),
+ ]
+
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', GUID),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8),
+ ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, 1)),
+ ]
+
+def Refine_FV_Header(nums):
+ class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', GUID),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8),
+ ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
+ ]
+ return EFI_FIRMWARE_VOLUME_HEADER
+
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
+ _fields_ = [
+ ('FvName', GUID),
+ ('ExtHeaderSize', c_uint32)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
+ _fields_ = [
+ ('ExtEntrySize', c_uint16),
+ ('ExtEntryType', c_uint16)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32),
+ ('Types', ARRAY(GUID, 1))
+ ]
+
+def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
+ class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32),
+ ('Types', ARRAY(GUID, nums))
+ ]
+ return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID),
+ ('Data', ARRAY(c_uint8, 1))
+ ]
+
+def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
+ class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID),
+ ('Data', ARRAY(c_uint8, nums))
+ ]
+ return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('UsedSize', c_uint32)
+ ]
diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
new file mode 100644
index 000000000000..c2cc8e0172fb
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
@@ -0,0 +1,110 @@
+## @file
+# This file is used to define the Section Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+EFI_COMMON_SECTION_HEADER_LEN = 4
+EFI_COMMON_SECTION_HEADER2_LEN = 8
+
+class EFI_COMMON_SECTION_HEADER(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Size', ARRAY(c_uint8, 3)),
+ ('Type', c_uint8),
+ ]
+
+ @property
+ def SECTION_SIZE(self) -> int:
+ return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
+
+ def Common_Header_Size(self) -> int:
+ return 4
+
+class EFI_COMMON_SECTION_HEADER2(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Size', ARRAY(c_uint8, 3)),
+ ('Type', c_uint8),
+ ('ExtendedSize', c_uint32),
+ ]
+
+ @property
+ def SECTION_SIZE(self) -> int:
+ return self.ExtendedSize
+
+ def Common_Header_Size(self) -> int:
+ return 8
+
+class EFI_COMPRESSION_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('UncompressedLength', c_uint32),
+ ('CompressionType', c_uint8),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 5
+
+class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SubTypeGuid', GUID),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 16
+
+class EFI_GUID_DEFINED_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SectionDefinitionGuid', GUID),
+ ('DataOffset', c_uint16),
+ ('Attributes', c_uint16),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 20
+
+def Get_USER_INTERFACE_Header(nums: int):
+ class EFI_SECTION_USER_INTERFACE(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('FileNameString', ARRAY(c_uint16, nums)),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 2 * nums
+
+ def GetUiString(self) -> str:
+ UiString = ''
+ for i in range(nums):
+ if self.FileNameString[i]:
+ UiString += chr(self.FileNameString[i])
+ return UiString
+
+ return EFI_SECTION_USER_INTERFACE
+
+def Get_VERSION_Header(nums: int):
+ class EFI_SECTION_VERSION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('BuildNumber', c_uint16),
+ ('VersionString', ARRAY(c_uint16, nums)),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 2 * (nums+1)
+
+ def GetVersionString(self) -> str:
+ VersionString = ''
+ for i in range(nums):
+ if self.VersionString[i]:
+ VersionString += chr(self.VersionString[i])
+ return VersionString
+
+ return EFI_SECTION_VERSION
diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py b/BaseTools/Source/Python/FMMT/PI/__init__.py
new file mode 100644
index 000000000000..4e8296fad1ba
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
@@ -0,0 +1,6 @@
+## @file
+# This file is used to define the FMMT dependent external tool management class.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/README.md b/BaseTools/Source/Python/FMMT/README.md
new file mode 100644
index 000000000000..e14dfa34ea66
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/README.md
@@ -0,0 +1,180 @@
+# FMMT
+## Overview
+This FMMT tool is the python implementation of the edk2 FMMT tool which locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
+This implementation has the same usage as the edk2 FMMT, but it's more readable and relaiable.
+
+# FMMT User Guide
+
+#### Last updated October 13, 2021
+
+Important Changes and Updates:
+
+- Oct 13, 2021 Initial Draft of FMMT Python Tool
+
+#### Note:
+
+- FMMT Python Tool keeps same function with origin FMMT C Tool. It is much easier to maintain and extend other functions.
+
+
+
+# 1. Introduction
+
+## 1.1 Overview
+
+The Firmware Device is a persistent physical repository that contains firmware code and/or data. The firmware code and/or data stored in Firmware Volumes. Detail layout of Firmware Volumes is described in ?Figure 1. The Firmware Volume Format?.
+
+![](Img/FirmwareVolumeFormat.png)
+
+<center>Figure 1. The Firmware Volume Format</center>
+
+In firmware development, binary file has its firmware layout following the Platform-Initialization Specification. Thus, operation on FV file / FFS file (Firmware File) is an efficient and convenient way for firmware function testing and developing. FMMT Python tool is used for firmware files operation.
+
+## 1.2 Tool Capabilities
+
+The FMMT tool is capable of:
+
+- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware Files)
+
+- Add a new FFS into a FV file (both included in a FD file or not)
+
+- Replace an FFS in a FV file with a new FFS file
+
+- Delete an FFS in a FV file (both included in a FD file or not)
+
+- Extract the FFS from a FV file (both includ-v < Inputfile > < Outputfile >ed in a FD file or not)
+
+## 1.3 References
+
+| Document |
+| ------------------------------------------------ |
+| UEFI Platform Initialization (PI) Specification |
+
+
+
+# 2. FMMT Python Tool Usage
+
+## 2.1 Required Files
+
+### 2.1.1 Independent use
+
+When independent use the FMMT Python Tool, the following files and settings are required:
+
+- GuidTool executable files used for Decompress/Compress Firmware data.
+
+- Environment variables path with GuidTool path setting.
+
+### 2.1.2 Use with Build System
+
+When use the FMMT Python Tool with Build System:
+
+- If only use Edk2 based GuidTool, do not need other preparation.
+
+- If use other customized GuidTool, need prepare the config file with GuidTool info. The syntax for GuidTool definition shown as follow:
+
+ ***ToolsGuid ShortName Command***
+
+ -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress***
+
+## 2.2 Syntax
+
+### 2.2.1 Syntax for Parse file
+
+***-v < Inputfile > < Outputfile > -l < LogFileType >***
+
+- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is optional, if inputs, the *Inputfile* will be encapsulated into *Outputfile* following the parsed firmware layout. *"-l LogFileType"* is optional, it decides the format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future.
+
+### 2.2.2 Syntax for Add a new FFS
+
+***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >***
+
+- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
+
+### 2.2.3 Syntax for Delete an FFS
+
+***-d < Inputfile > < TargetFfsName > < Outputfile > < TargetFvName/TargetFvGuid >***
+
+- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
+
+### 2.2.4 Syntax for Replace an FFS
+
+***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < TargetFvName/TargetFvGuid >***
+
+- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
+
+### 2.2.5 Syntax for Extract an FFS
+
+***-e < Inputfile > < TargetFfsName > < Outputfile >***
+
+- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs which will be extracted.
+
+
+
+# 3. FMMT Python Tool Design
+
+FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each Node have its Data field, which saves the FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the parse/add/delete/replace/extract operations are based on the NodeTree (adjusting the layout and data).
+
+## 3.1 NodeTree
+
+A whole NodeTree saves all the Firmware info.
+
+- Parent & Child relationship figured out the Firmware layout.
+
+- Each Node have several fields. ?Data? field saves an FirmwareClass instance which contains all the data info of the info.
+
+### 3.1.1 NodeTree Format
+
+The NodeTree will be created with parse function. When parse a file, a Root Node will be initialized firstly. The Data split and Tree construction process is described with an FD file shown as ?Figure 2. The NodeTree format?:
+
+- A Root Node is initialized.
+
+- Use the ?FV Signature? as FV key to split Whole FD Data. ?FV0?, ?FV1?, ?FV2?? Node created.
+
+- After FV level Node created, use the ?Ffs Data Size? as FFS key to split each FV Data. ?Ffs0?...Node created.
+
+- After FFS level Node created, use the ?Section Data Size? as Section key to split each Ffs Data. ?Section0?...Node created.
+
+- If some of Section includes other Sections, continue use the ?Section Data Size? as Section key to split each Section Data.
+
+- After all Node created, the whole NodeTree saves all the info. (Can be used in other functions or print the whole firmware layout into log file)
+
+![](Img/NodeTreeFormat.png)
+
+<center>Figure 2. The NodeTree format</center>
+
+### 3.1.2 Node Factory and Product
+
+As 3.1.1, Each Node is created by data split and recognition. To extend the NodeTree usage, Factory pattern is used in Node created process.
+
+Each Node have its Factory to create Product and use Product ParserData function to deal with the data.
+
+## 3.2 GuidTool
+
+There are two ways to set the GuidTool. One from Config file, another from environment variables.
+
+Current GuidTool first check if has Config file.
+
+- If have, load the config GuidTool Information.
+
+- Else get from environment variables.
+
+### 3.2.1 Get from Config file
+
+- Config file should in same folder with FMMT.py or the path in environment variables.
+
+- Content should follow the format:
+
+ ***ToolsGuid ShortName Command***
+
+### 3.2.2 Get from Environment Variables
+
+- The GuidTool Command used must be set in environment variables.
+
+### 3.2.3 Edk2 Based GuidTool
+
+| ***Guid*** | ***ShortName*** | ***Command*** |
+| ------------------------------------------ | --------------- | --------------------- |
+| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | ***TianoCompress*** |
+| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | ***LzmaCompress*** |
+| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | ***GenCrc32*** |
+| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | ***LzmaF86Compress*** |
+| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | ***BrotliCompress*** |
diff --git a/BaseTools/Source/Python/FMMT/__init__.py b/BaseTools/Source/Python/FMMT/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
new file mode 100644
index 000000000000..33ffe73cab27
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
@@ -0,0 +1,371 @@
+## @file
+# This file is used to implement of the various bianry parser.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from re import T
+import copy
+import os
+from PI.Common import *
+from core.BiosTreeNode import *
+from core.BiosTree import *
+from core.GuidTools import *
+
+ROOT_TREE = 'ROOT'
+ROOT_FV_TREE = 'ROOT_FV_TREE'
+ROOT_FFS_TREE = 'ROOT_FFS_TREE'
+ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+
+FV_TREE = 'FV'
+DATA_FV_TREE = 'DATA_FV'
+FFS_TREE = 'FFS'
+FFS_PAD = 'FFS_PAD'
+FFS_FREE_SPACE = 'FFS_FREE_SPACE'
+SECTION_TREE = 'SECTION'
+SEC_FV_TREE = 'SEC_FV_IMAGE'
+BINARY_DATA = 'BINARY'
+Fv_count = 0
+
+## Abstract factory
+class BinaryFactory():
+ type:list = []
+
+ def Create_Product():
+ pass
+
+class BinaryProduct():
+ ## Use GuidTool to decompress data.
+ def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
+ ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
+ DecompressedData = guidtool.unpack(Section_Data)
+ return DecompressedData
+
+ def ParserData():
+ pass
+
+class SectionFactory(BinaryFactory):
+ type = [SECTION_TREE]
+
+ def Create_Product():
+ return SectionProduct()
+
+class FfsFactory(BinaryFactory):
+ type = [ROOT_SECTION_TREE, FFS_TREE]
+
+ def Create_Product():
+ return FfsProduct()
+
+class FvFactory(BinaryFactory):
+ type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
+
+ def Create_Product():
+ return FvProduct()
+
+class FdFactory(BinaryFactory):
+ type = [ROOT_FV_TREE, ROOT_TREE]
+
+ def Create_Product():
+ return FdProduct()
+
+class SectionProduct(BinaryProduct):
+ ## Decompress the compressed section.
+ def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ if Section_Tree.Data.Type == 0x01:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ self.ParserFfs(Section_Tree, b'')
+ # Guided Define Section
+ elif Section_Tree.Data.Type == 0x02:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ DeCompressGuidTool = Section_Tree.Data.ExtHeader.SectionDefinitionGuid
+ Section_Tree.Data.Data = self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
+ Section_Tree.Data.Size = len(Section_Tree.Data.Data) + Section_Tree.Data.HeaderLength
+ self.ParserFfs(Section_Tree, b'')
+ elif Section_Tree.Data.Type == 0x03:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ self.ParserFfs(Section_Tree, b'')
+ # SEC_FV Section
+ elif Section_Tree.Data.Type == 0x17:
+ global Fv_count
+ Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
+ Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
+ Sec_Fv_Tree.type = SEC_FV_TREE
+ Sec_Fv_Tree.Data = Sec_Fv_Info
+ Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
+ Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + Sec_Fv_Tree.Data.Header.HeaderLength
+ Sec_Fv_Tree.Data.Data = Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
+ Section_Tree.insertChild(Sec_Fv_Tree)
+ Fv_count += 1
+
+ def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Rel_Offset = 0
+ Section_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Section_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Section recorded in its Parent Section.
+ while Rel_Offset < Data_Size:
+ # Create a SectionNode and set it as the SectionTree's Data
+ Section_Info = SectionNode(Whole_Data[Rel_Offset:])
+ Section_Tree = BIOSTREE(Section_Info.Name)
+ Section_Tree.type = SECTION_TREE
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
+ Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
+ Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
+ Section_Info.ROffset = Rel_Offset
+ if Section_Info.Header.Type == 0:
+ break
+ # The final Section in parent Section does not need to add padding, else must be 4-bytes align with parent Section start offset
+ Pad_Size = 0
+ if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Section_Info.Size, 4)
+ Section_Info.PadData = Pad_Size * b'\x00'
+ if Section_Info.Header.Type == 0x02:
+ Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size]
+ if Section_Info.Header.Type == 0x14:
+ ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
+ if Section_Info.Header.Type == 0x15:
+ ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
+ Section_Offset += Section_Info.Size + Pad_Size
+ Rel_Offset += Section_Info.Size + Pad_Size
+ Section_Tree.Data = Section_Info
+ ParTree.insertChild(Section_Tree)
+
+class FfsProduct(BinaryProduct):
+ # ParserFFs / GetSection
+ def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Rel_Offset = 0
+ Section_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Section_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Section recorded in Ffs.
+ while Rel_Offset < Data_Size:
+ # Create a SectionNode and set it as the SectionTree's Data
+ Section_Info = SectionNode(Whole_Data[Rel_Offset:])
+ Section_Tree = BIOSTREE(Section_Info.Name)
+ Section_Tree.type = SECTION_TREE
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
+ Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
+ Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
+ Section_Info.ROffset = Rel_Offset
+ if Section_Info.Header.Type == 0:
+ break
+ # The final Section in Ffs does not need to add padding, else must be 4-bytes align with Ffs start offset
+ Pad_Size = 0
+ if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Section_Info.Size, 4)
+ Section_Info.PadData = Pad_Size * b'\x00'
+ if Section_Info.Header.Type == 0x02:
+ Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size]
+ # If Section is Version or UI type, it saves the version and UI info of its parent Ffs.
+ if Section_Info.Header.Type == 0x14:
+ ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
+ if Section_Info.Header.Type == 0x15:
+ ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
+ Section_Offset += Section_Info.Size + Pad_Size
+ Rel_Offset += Section_Info.Size + Pad_Size
+ Section_Tree.Data = Section_Info
+ ParTree.insertChild(Section_Tree)
+
+class FvProduct(BinaryProduct):
+ ## ParserFv / GetFfs
+ def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Ffs_Offset = 0
+ Rel_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Ffs_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Ffs recorded in Fv.
+ while Rel_Offset < Data_Size:
+ # Create a FfsNode and set it as the FFsTree's Data
+ if Data_Size - Rel_Offset < 24:
+ Ffs_Tree = BIOSTREE('Free_Space')
+ Ffs_Tree.type = FFS_FREE_SPACE
+ Ffs_Tree.Data = FreeSpaceNode(Whole_Data[Rel_Offset:])
+ Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
+ Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
+ ParTree.Data.Free_Space = Data_Size - Rel_Offset
+ ParTree.insertChild(Ffs_Tree)
+ Rel_Offset = Data_Size
+ else:
+ Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
+ Ffs_Tree = BIOSTREE(Ffs_Info.Name)
+ Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
+ Ffs_Info.DOffset = Ffs_Offset + Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
+ Ffs_Info.ROffset = Rel_Offset
+ if Ffs_Info.Name == PADVECTOR:
+ Ffs_Tree.type = FFS_PAD
+ Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
+ Ffs_Info.Size = len(Ffs_Info.Data) + Ffs_Info.Header.HeaderLength
+ # if current Ffs is the final ffs of Fv and full of b'\xff', define it with Free_Space
+ if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') == b'':
+ Ffs_Tree.type = FFS_FREE_SPACE
+ Ffs_Info.Data = Whole_Data[Rel_Offset:]
+ Ffs_Info.Size = len(Ffs_Info.Data)
+ ParTree.Data.Free_Space = Ffs_Info.Size
+ else:
+ Ffs_Tree.type = FFS_TREE
+ Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
+ # The final Ffs in Fv does not need to add padding, else must be 8-bytes align with Fv start offset
+ Pad_Size = 0
+ if Ffs_Tree.type != FFS_FREE_SPACE and (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Ffs_Info.Size, 8)
+ Ffs_Info.PadData = Pad_Size * b'\xff'
+ Ffs_Offset += Ffs_Info.Size + Pad_Size
+ Rel_Offset += Ffs_Info.Size + Pad_Size
+ Ffs_Tree.Data = Ffs_Info
+ ParTree.insertChild(Ffs_Tree)
+
+class FdProduct(BinaryProduct):
+ type = [ROOT_FV_TREE, ROOT_TREE]
+
+ ## Create DataTree with first level /fv Info, then parser each Fv.
+ def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0) -> None:
+ # Get all Fv image in Fd with offset and length
+ Fd_Struct = self.GetFvFromFd(whole_data)
+ data_size = len(whole_data)
+ Binary_count = 0
+ global Fv_count
+ # If the first Fv image is the Binary Fv, add it into the tree.
+ if Fd_Struct[0][1] != 0:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = 0 + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+ # Add the first collected Fv image into the tree.
+ Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
+ Cur_node.type = Fd_Struct[0][0]
+ Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
+ Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
+ Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
+ Cur_node.Data.Data = whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[0][1]+Cur_node.Data.Size]
+ WholeFvTree.insertChild(Cur_node)
+ Fv_count += 1
+ Fv_num = len(Fd_Struct)
+ # Add all the collected Fv image and the Binary Fv image between them into the tree.
+ for i in range(Fv_num-1):
+ if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+ Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
+ Cur_node.type = Fd_Struct[i+1][0]
+ Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
+ Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
+ Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
+ Cur_node.Data.Data = whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[i+1][1]+Cur_node.Data.Size]
+ WholeFvTree.insertChild(Cur_node)
+ Fv_count += 1
+ # If the final Fv image is the Binary Fv, add it into the tree
+ if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+
+ ## Get the first level Fv from Fd file.
+ def GetFvFromFd(self, whole_data: bytes=b'') -> list:
+ Fd_Struct = []
+ data_size = len(whole_data)
+ cur_index = 0
+ # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ cur_index = 0
+ # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ cur_index = 0
+ # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([DATA_FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ # Sort all the collect Fv image with offset.
+ Fd_Struct.sort(key=lambda x:x[1])
+ tmp_struct = copy.deepcopy(Fd_Struct)
+ tmp_index = 0
+ Fv_num = len(Fd_Struct)
+ # Remove the Fv image included in another Fv image.
+ for i in range(1,Fv_num):
+ if tmp_struct[i][1]+tmp_struct[i][2][0] < tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
+ Fd_Struct.remove(Fd_Struct[i-tmp_index])
+ tmp_index += 1
+ return Fd_Struct
+
+class ParserEntry():
+ FactoryTable:dict = {
+ SECTION_TREE: SectionFactory,
+ ROOT_SECTION_TREE: FfsFactory,
+ FFS_TREE: FfsFactory,
+ ROOT_FFS_TREE: FvFactory,
+ FV_TREE: FvFactory,
+ SEC_FV_TREE: FvFactory,
+ ROOT_FV_TREE: FdFactory,
+ ROOT_TREE: FdFactory,
+ }
+
+ def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
+ if Tree_type in self.FactoryTable:
+ return self.FactoryTable[Tree_type]
+
+ def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: bytes, Offset: int) -> None:
+ New_Product = TargetFactory.Create_Product()
+ New_Product.ParserData(Tree, Data, Offset)
+
+ def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
+ TargetFactory = self.GetTargetFactory(Tree.type)
+ if TargetFactory:
+ self.Generate_Product(TargetFactory, Tree, Data, Offset)
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py
new file mode 100644
index 000000000000..0b6252ecc1bb
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
@@ -0,0 +1,198 @@
+## @file
+# This file is used to define the Bios layout tree structure and related operations.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import collections
+from PI.Common import *
+
+ROOT_TREE = 'ROOT'
+ROOT_FV_TREE = 'ROOT_FV_TREE'
+ROOT_FFS_TREE = 'ROOT_FFS_TREE'
+ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+
+FV_TREE = 'FV'
+DATA_FV_TREE = 'DATA_FV'
+FFS_TREE = 'FFS'
+FFS_PAD = 'FFS_PAD'
+FFS_FREE_SPACE = 'FFS_FREE_SPACE'
+SECTION_TREE = 'SECTION'
+SEC_FV_TREE = 'SEC_FV_IMAGE'
+BINARY_DATA = 'BINARY'
+
+RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE]
+FvType = [FV_TREE, SEC_FV_TREE]
+FfsType = FFS_TREE
+SecType = SECTION_TREE
+
+class BIOSTREE:
+ def __init__(self, NodeName: str) -> None:
+ self.key = NodeName
+ self.type = None
+ self.Data = None
+ self.Child = []
+ self.Findlist = []
+ self.Parent = None
+ self.NextRel = None
+ self.LastRel = None
+
+ def HasChild(self) -> bool:
+ if self.Child == []:
+ return False
+ else:
+ return True
+
+ def isFinalChild(self) -> bool:
+ ParTree = self.Parent
+ if ParTree:
+ if ParTree.Child[-1] == self:
+ return True
+ return False
+
+ # FvTree.insertChild()
+ def insertChild(self, newNode, pos: int=None) -> None:
+ if len(self.Child) == 0:
+ self.Child.append(newNode)
+ else:
+ if not pos:
+ LastTree = self.Child[-1]
+ self.Child.append(newNode)
+ LastTree.NextRel = newNode
+ newNode.LastRel = LastTree
+ else:
+ newNode.NextRel = self.Child[pos-1].NextRel
+ newNode.LastRel = self.Child[pos].LastRel
+ self.Child[pos-1].NextRel = newNode
+ self.Child[pos].LastRel = newNode
+ self.Child.insert(pos, newNode)
+ newNode.Parent = self
+
+ # lastNode.insertRel(newNode)
+ def insertRel(self, newNode) -> None:
+ if self.Parent:
+ parentTree = self.Parent
+ new_index = parentTree.Child.index(self) + 1
+ parentTree.Child.insert(new_index, newNode)
+ self.NextRel = newNode
+ newNode.LastRel = self
+
+ def deleteNode(self, deletekey: str) -> None:
+ FindStatus, DeleteTree = self.FindNode(deletekey)
+ if FindStatus:
+ parentTree = DeleteTree.Parent
+ lastTree = DeleteTree.LastRel
+ nextTree = DeleteTree.NextRel
+ if parentTree:
+ index = parentTree.Child.index(DeleteTree)
+ del parentTree.Child[index]
+ if lastTree and nextTree:
+ lastTree.NextRel = nextTree
+ nextTree.LastRel = lastTree
+ elif lastTree:
+ lastTree.NextRel = None
+ elif nextTree:
+ nextTree.LastRel = None
+ return DeleteTree
+ else:
+ print('Could not find the target tree')
+ return None
+
+ def FindNode(self, key: str, Findlist: list) -> None:
+ if self.key == key or (self.Data and self.Data.Name == key) or (self.type == FFS_TREE and self.Data.UiName == key):
+ Findlist.append(self)
+ else:
+ for item in self.Child:
+ item.FindNode(key, Findlist)
+
+ def GetTreePath(self):
+ BiosTreePath = [self]
+ while self.Parent:
+ BiosTreePath.insert(0, self.Parent)
+ self = self.Parent
+ return BiosTreePath
+
+ def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0, ParFvId="") -> None:
+ Key = list(TargetDict.keys())[0]
+ if TargetDict[Key]["Type"] in RootType:
+ Info.append("Image File: {}".format(Key))
+ Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum')))
+ Info.append("\n")
+ elif TargetDict[Key]["Type"] in FvType:
+ space += 2
+ if TargetDict[Key]["Type"] == SEC_FV_TREE:
+ Info.append("{}Child FV named {} of {}".format(space*" ", Key, ParFvId))
+ space += 2
+ else:
+ Info.append("FvId: {}".format(Key))
+ ParFvId = Key
+ Info.append("{}FvNameGuid: {}".format(space*" ", TargetDict.get(Key).get('FvNameGuid')))
+ Info.append("{}Attributes: {}".format(space*" ", TargetDict.get(Key).get('Attributes')))
+ Info.append("{}Total Volume Size: {}".format(space*" ", TargetDict.get(Key).get('Size')))
+ Info.append("{}Free Volume Size: {}".format(space*" ", TargetDict.get(Key).get('FreeSize')))
+ Info.append("{}Volume Offset: {}".format(space*" ", TargetDict.get(Key).get('Offset')))
+ Info.append("{}FilesNum: {}".format(space*" ", TargetDict.get(Key).get('FilesNum')))
+ elif TargetDict[Key]["Type"] in FfsType:
+ space += 2
+ if TargetDict.get(Key).get('UiName') != "b''":
+ Info.append("{}File: {} / {}".format(space*" ", Key, TargetDict.get(Key).get('UiName')))
+ else:
+ Info.append("{}File: {}".format(space*" ", Key))
+ if "Files" in list(TargetDict[Key].keys()):
+ for item in TargetDict[Key]["Files"]:
+ self.parserTree(item, Info, space, ParFvId)
+
+ def ExportTree(self,TreeInfo: dict=None) -> dict:
+ if TreeInfo is None:
+ TreeInfo =collections.OrderedDict()
+
+ if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
+ key = str(self.key)
+ TreeInfo[self.key] = collections.OrderedDict()
+ TreeInfo[self.key]["Name"] = key
+ TreeInfo[self.key]["Type"] = self.type
+ TreeInfo[self.key]["FilesNum"] = len(self.Child)
+ elif self.type == FV_TREE or self.type == SEC_FV_TREE:
+ key = str(self.Data.FvId)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ if self.Data.FvId != self.Data.Name:
+ TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes)
+ TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
+ TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self.type == FFS_TREE:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
+ TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self.type == SECTION_TREE and self.Data.Type == 0x02:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + self.Data.HeaderLength)
+ TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self is not None:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+
+ for item in self.Child:
+ TreeInfo[key].setdefault('Files',[]).append( item.ExportTree())
+
+ return TreeInfo
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
new file mode 100644
index 000000000000..cfb711eea5a2
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
@@ -0,0 +1,191 @@
+## @file
+# This file is used to define the BIOS Tree Node.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from PI.FvHeader import *
+from PI.FfsFileHeader import *
+from PI.SectionHeader import *
+from PI.Common import *
+import uuid
+
+SectionHeaderType = {
+ 0x01:'EFI_COMPRESSION_SECTION',
+ 0x02:'EFI_GUID_DEFINED_SECTION',
+ 0x03:'EFI_SECTION_DISPOSABLE',
+ 0x10:'EFI_SECTION_PE32',
+ 0x11:'EFI_SECTION_PIC',
+ 0x12:'EFI_SECTION_TE',
+ 0x13:'EFI_SECTION_DXE_DEPEX',
+ 0x14:'EFI_SECTION_VERSION',
+ 0x15:'EFI_SECTION_USER_INTERFACE',
+ 0x16:'EFI_SECTION_COMPATIBILITY16',
+ 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
+ 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
+ 0x19:'EFI_SECTION_RAW',
+ 0x1B:'EFI_SECTION_PEI_DEPEX',
+ 0x1C:'EFI_SECTION_MM_DEPEX'
+}
+HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
+
+class BinaryNode:
+ def __init__(self, name: str) -> None:
+ self.Size = 0
+ self.Name = "BINARY" + str(name)
+ self.HOffset = 0
+ self.Data = b''
+
+class FvNode:
+ def __init__(self, name, buffer: bytes) -> None:
+ self.Header = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
+ Map_num = (self.Header.HeaderLength - 56)//8
+ self.Header = Refine_FV_Header(Map_num).from_buffer_copy(buffer)
+ self.FvId = "FV" + str(name)
+ self.Name = "FV" + str(name)
+ if self.Header.ExtHeaderOffset:
+ self.ExtHeader = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header.ExtHeaderOffset:])
+ self.Name = uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
+ self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
+ if self.ExtHeader.ExtHeaderSize != 20:
+ self.ExtEntryExist = 1
+ self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntryOffset:])
+ self.ExtTypeExist = 1
+ if self.ExtEntry.ExtEntryType == 0x01:
+ nums = (self.ExtEntry.ExtEntrySize - 8) // 16
+ self.ExtEntry = Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
+ elif self.ExtEntry.ExtEntryType == 0x02:
+ nums = self.ExtEntry.ExtEntrySize - 20
+ self.ExtEntry = Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
+ elif self.ExtEntry.ExtEntryType == 0x03:
+ self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(buffer[self.ExtEntryOffset:])
+ else:
+ self.ExtTypeExist = 0
+ else:
+ self.ExtEntryExist = 0
+ self.Size = self.Header.FvLength
+ self.HeaderLength = self.Header.HeaderLength
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ if self.Header.Signature != 1213613663:
+ print('Invalid! Fv Header Signature {} is not "_FVH".'.format(self.Header.Signature))
+ with open(str(self.Name)+'.fd', "wb") as f:
+ f.write(struct2stream(self.Header))
+ assert False
+ self.PadData = b''
+ self.Free_Space = 0
+ self.ModCheckSum()
+
+ def ModCheckSum(self) -> None:
+ # Fv Header Sums to 0.
+ Header = struct2stream(self.Header)[::-1]
+ Size = self.HeaderLength // 2
+ Sum = 0
+ for i in range(Size):
+ Sum += int(Header[i*2: i*2 + 2].hex(), 16)
+ if Sum & 0xffff:
+ self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - self.Header.Checksum)[-4:], 16)), 16)
+
+ def ModFvExt(self) -> None:
+ # If used space changes and self.ExtEntry.UsedSize exists, self.ExtEntry.UsedSize need to be changed.
+ if self.Header.ExtHeaderOffset and self.ExtEntryExist and self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03:
+ self.ExtEntry.UsedSize = self.Header.FvLength - self.Free_Space
+
+ def ModFvSize(self) -> None:
+ # If Fv Size changed, self.Header.FvLength and self.Header.BlockMap[i].NumBlocks need to be changed.
+ BlockMapNum = len(self.Header.BlockMap)
+ for i in range(BlockMapNum):
+ if self.Header.BlockMap[i].Length:
+ self.Header.BlockMap[i].NumBlocks = self.Header.FvLength // self.Header.BlockMap[i].Length
+
+ def ModExtHeaderData(self) -> None:
+ if self.Header.ExtHeaderOffset:
+ ExtHeaderData = struct2stream(self.ExtHeader)
+ ExtHeaderDataOffset = self.Header.ExtHeaderOffset - self.HeaderLength
+ self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData + self.Data[ExtHeaderDataOffset+20:]
+ if self.Header.ExtHeaderOffset and self.ExtEntryExist:
+ ExtHeaderEntryData = struct2stream(self.ExtEntry)
+ ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + 20 - self.HeaderLength
+ self.Data = self.Data[:ExtHeaderEntryDataOffset] + ExtHeaderEntryData + self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
+
+class FfsNode:
+ def __init__(self, buffer: bytes) -> None:
+ self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
+ # self.Attributes = unpack("<B", buffer[21:22])[0]
+ if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes != 0xff and self.Header.Attributes & 0x01 == 1:
+ print('Error Ffs Header! Ffs Header Size and Attributes is not matched!')
+ if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes & 0x01 == 1:
+ self.Header = EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
+ self.Name = uuid.UUID(bytes_le=struct2stream(self.Header.Name))
+ self.UiName = b''
+ self.Version = b''
+ self.Size = self.Header.FFS_FILE_SIZE
+ self.HeaderLength = self.Header.HeaderLength
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ self.PadData = b''
+
+ def ModCheckSum(self) -> None:
+ HeaderData = struct2stream(self.Header)
+ HeaderSum = 0
+ for item in HeaderData:
+ HeaderSum += item
+ HeaderSum -= self.Header.State
+ HeaderSum -= self.Header.IntegrityCheck.Checksum.File
+ if HeaderSum & 0xff:
+ Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 - int(hex(HeaderSum)[-2:], 16)
+ self.Header.IntegrityCheck.Checksum.Header = int(hex(Header)[-2:], 16)
+
+class SectionNode:
+ def __init__(self, buffer: bytes) -> None:
+ if buffer[0:3] != b'\xff\xff\xff':
+ self.Header = EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
+ else:
+ self.Header = EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
+ if self.Header.Type in SectionHeaderType:
+ self.Name = SectionHeaderType[self.Header.Type]
+ elif self.Header.Type == 0:
+ self.Name = "EFI_SECTION_RAW"
+ else:
+ self.Name = "SECTION"
+ if self.Header.Type in HeaderType:
+ self.ExtHeader = self.GetExtHeader(self.Header.Type, buffer[self.Header.Common_Header_Size():], (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
+ self.HeaderLength = self.Header.Common_Header_Size() + self.ExtHeader.ExtHeaderSize()
+ else:
+ self.ExtHeader = None
+ self.HeaderLength = self.Header.Common_Header_Size()
+ self.Size = self.Header.SECTION_SIZE
+ self.Type = self.Header.Type
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ self.OriData = b''
+ self.OriHeader = b''
+ self.PadData = b''
+
+ def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None:
+ if Type == 0x01:
+ return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
+ elif Type == 0x02:
+ return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
+ elif Type == 0x14:
+ return Get_VERSION_Header((nums - 2)//2).from_buffer_copy(buffer)
+ elif Type == 0x15:
+ return Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
+ elif Type == 0x18:
+ return EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
+
+class FreeSpaceNode:
+ def __init__(self, buffer: bytes) -> None:
+ self.Name = 'Free_Space'
+ self.Data = buffer
+ self.Size = len(buffer)
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.PadData = b''
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
new file mode 100644
index 000000000000..a0432c4093cf
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
@@ -0,0 +1,140 @@
+## @file
+# This file is used to define the functions to operate bios binary file.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from core.FMMTParser import *
+from core.FvHandler import *
+from utils.FvLayoutPrint import *
+
+global Fv_count
+Fv_count = 0
+
+# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE'
+def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # 3. Log Output
+ InfoDict = FmmtParser.WholeFvTree.ExportTree()
+ FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
+ GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
+ if logfile:
+ GetFormatter(logfile.lower()).dump(InfoDict, FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile),".{}".format(logfile.lower())))
+ # 4. Data Encapsultion
+ if outputfile:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # 3. Data Modify
+ FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist)
+ # Choose the Specfic DeleteFfs with Fv info
+ if Fv_name:
+ for item in FmmtParser.WholeFvTree.Findlist:
+ if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
+ FmmtParser.WholeFvTree.Findlist.remove(item)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
+ FfsMod = FvHandler(None, Delete_Ffs)
+ Status = FfsMod.DeleteFfs()
+ else:
+ print('Target Ffs not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # Get Target Fv and Target Ffs_Pad
+ FmmtParser.WholeFvTree.FindNode(Fv_name, FmmtParser.WholeFvTree.Findlist)
+ # Create new ffs Tree
+ with open(newffsfile, "rb") as f:
+ new_ffs_data = f.read()
+ NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
+ Status = False
+ # 3. Data Modify
+ if FmmtParser.WholeFvTree.Findlist:
+ for TargetFv in FmmtParser.WholeFvTree.Findlist:
+ TargetFfsPad = TargetFv.Child[-1]
+ if TargetFfsPad.type == FFS_FREE_SPACE:
+ NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset)
+ else:
+ NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
+ FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], TargetFfsPad)
+ Status = FfsMod.AddFfs()
+ else:
+ print('Target Fv not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ with open(newffsfile, "rb") as f:
+ new_ffs_data = f.read()
+ newFmmtParser = FMMTParser(newffsfile, FV_TREE)
+ newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, new_ffs_data)
+ Status = False
+ # 3. Data Modify
+ new_ffs = newFmmtParser.WholeFvTree.Child[0]
+ new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
+ FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
+ if Fv_name:
+ for item in FmmtParser.WholeFvTree.Findlist:
+ if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
+ FmmtParser.WholeFvTree.Findlist.remove(item)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ for TargetFfs in FmmtParser.WholeFvTree.Findlist:
+ FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs)
+ Status = FfsMod.ReplaceFfs()
+ else:
+ print('Target Ffs not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ TargetNode = FmmtParser.WholeFvTree.Findlist[0]
+ TargetFv = TargetNode.Parent
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ TargetNode.Data.Header.State = c_uint8(
+ ~TargetNode.Data.Header.State)
+ FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data
+ with open(outputfile, "wb") as f:
+ f.write(FinalData)
+ else:
+ print('Target Ffs not found!!!')
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
new file mode 100644
index 000000000000..6e54b860a9c9
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
@@ -0,0 +1,86 @@
+## @file
+# This file is used to define the interface of Bios Parser.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from PI.Common import *
+from core.BinaryFactoryProduct import ParserEntry
+from core.BiosTreeNode import *
+from core.BiosTree import *
+from core.GuidTools import *
+
+class FMMTParser:
+ def __init__(self, name: str, TYPE: str) -> None:
+ self.WholeFvTree = BIOSTREE(name)
+ self.WholeFvTree.type = TYPE
+ self.FinalData = b''
+ self.BinaryInfo = []
+
+ ## Parser the nodes in WholeTree.
+ def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', Reloffset: int=0) -> None:
+ if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE:
+ ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset)
+ else:
+ ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset)
+ for Child in WholeFvTree.Child:
+ self.ParserFromRoot(Child, "")
+
+ ## Encapuslation all the data in tree into self.FinalData
+ def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
+ # If current node is Root node, skip it.
+ if rootTree.type == ROOT_TREE or rootTree.type == ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == ROOT_SECTION_TREE:
+ print('Start at Root !')
+ # If current node do not have Header, just add Data.
+ elif rootTree.type == BINARY_DATA or rootTree.type == FFS_FREE_SPACE:
+ self.FinalData += rootTree.Data.Data
+ rootTree.Child = []
+ # If current node do not have Child and ExtHeader, just add its Header and Data.
+ elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
+ self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ if ParTree.type != 'ROOT':
+ self.FinalData += ParTree.Data.PadData
+ rootTree.Child = []
+ # If current node is not Section node and may have Child and ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data.
+ elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or rootTree.type == SEC_FV_TREE:
+ if rootTree.HasChild():
+ self.FinalData += struct2stream(rootTree.Data.Header)
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ if ParTree.type != 'ROOT':
+ self.FinalData += ParTree.Data.PadData
+ # If current node is Section, need to consider its ExtHeader, Child and Compressed Status.
+ elif rootTree.type == SECTION_TREE:
+ # Not compressed section
+ if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != b'' and CompressStatus):
+ if rootTree.HasChild():
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader)
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header)
+ else:
+ Data = rootTree.Data.Data
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ self.FinalData += ParTree.Data.PadData
+ # If compressed section
+ else:
+ Data = rootTree.Data.OriData
+ rootTree.Child = []
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ self.FinalData += ParTree.Data.PadData
+ for Child in rootTree.Child:
+ self.Encapsulation(Child, CompressStatus)
diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py
new file mode 100644
index 000000000000..f73f1fd65c07
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
@@ -0,0 +1,521 @@
+## @file
+# This file is used to the implementation of Bios layout handler.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+from core.BiosTree import *
+from core.GuidTools import GUIDTools
+from core.BiosTreeNode import *
+from PI.Common import *
+
+EFI_FVB2_ERASE_POLARITY = 0x00000800
+
+def ChangeSize(TargetTree, size_delta: int=0) -> None:
+ if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or type(TargetTree.Data.Header) == type(EFI_COMMON_SECTION_HEADER2()):
+ TargetTree.Data.Size -= size_delta
+ TargetTree.Data.Header.ExtendedSize -= size_delta
+ elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
+ OriSize = TargetTree.Data.Header.SECTION_SIZE
+ OriSize -= size_delta
+ TargetTree.Data.Header.Size[0] = OriSize % (16**2)
+ TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
+ TargetTree.Data.Header.Size[2] = OriSize // (16**4)
+ else:
+ TargetTree.Data.Size -= size_delta
+ TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
+ TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) //(16**2)
+ TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
+
+def ModifyFfsType(TargetFfs) -> None:
+ if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and TargetFfs.Data.Size > 0xFFFFFF:
+ ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
+ New_Header = EFI_FFS_FILE_HEADER2()
+ New_Header.Name = TargetFfs.Data.Header.Name
+ New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
+ New_Header.Type = TargetFfs.Data.Header.Type
+ New_Header.Attributes = TargetFfs.Data.Header.Attributes
+ New_Header.Size = 0
+ New_Header.State = TargetFfs.Data.Header.State
+ New_Header.ExtendedSize = ExtendSize
+ TargetFfs.Data.Header = New_Header
+ TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
+ TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
+ TargetFfs.Data.ModCheckSum()
+ elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and TargetFfs.Data.Size <= 0xFFFFFF:
+ New_Header = EFI_FFS_FILE_HEADER()
+ New_Header.Name = TargetFfs.Data.Header.Name
+ New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
+ New_Header.Type = TargetFfs.Data.Header.Type
+ New_Header.Attributes = TargetFfs.Data.Header.Attributes
+ New_Header.Size = TargetFfs.Data.HeaderLength + TargetFfs.Data.Size
+ New_Header.State = TargetFfs.Data.Header.State
+ TargetFfs.Data.Header = New_Header
+ TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
+ TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
+ TargetFfs.Data.ModCheckSum()
+ if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
+ NeedChange = True
+ for item in TargetFfs.Parent.Child:
+ if type(item.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
+ NeedChange = False
+ if NeedChange:
+ TargetFfs.Parent.Data.Header.FileSystemGuid = ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
+
+ if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
+ TarParent = TargetFfs.Parent
+ while TarParent:
+ if TarParent.type == FV_TREE and struct2stream(TarParent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
+ TarParent.Data.Header.FileSystemGuid = ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
+ TarParent = TarParent.Parent
+
+class FvHandler:
+ def __init__(self, NewFfs, TargetFfs) -> None:
+ self.NewFfs = NewFfs
+ self.TargetFfs = TargetFfs
+ self.Status = False
+ self.Remain_New_Free_Space = 0
+
+ ## Use for Compress the Section Data
+ def CompressData(self, TargetTree) -> None:
+ TreePath = TargetTree.GetTreePath()
+ pos = len(TreePath)
+ self.Status = True
+ while pos:
+ if self.Status:
+ if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-1].Data.Type == 0x02:
+ self.CompressSectionData(TreePath[pos-1], None, TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
+ else:
+ if pos == len(TreePath):
+ self.CompressSectionData(TreePath[pos-1], pos)
+ else:
+ self.CompressSectionData(TreePath[pos-1], None)
+ pos -= 1
+
+ def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> None:
+ NewData = b''
+ temp_save_child = TargetTree.Child
+ if TargetTree.Data:
+ for item in temp_save_child:
+ if item.type == SECTION_TREE and not item.Data.OriData and item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.OriData and not item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + item.Data.OriData + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.OriData and item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ elif item.type == FFS_FREE_SPACE:
+ NewData += item.Data.Data + item.Data.PadData
+ else:
+ NewData += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
+ if TargetTree.type == FFS_TREE:
+ New_Pad_Size = GetPadSize(len(NewData), 8)
+ Size_delta = len(NewData) - len(TargetTree.Data.Data)
+ ChangeSize(TargetTree, -Size_delta)
+ Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
+ self.Remain_New_Free_Space += Delta_Pad_Size
+ TargetTree.Data.PadData = b'\xff' * New_Pad_Size
+ TargetTree.Data.ModCheckSum()
+ elif TargetTree.type == FV_TREE or TargetTree.type == SEC_FV_TREE and not pos:
+ if self.Remain_New_Free_Space:
+ if TargetTree.Data.Free_Space:
+ TargetTree.Data.Free_Space += self.Remain_New_Free_Space
+ NewData += self.Remain_New_Free_Space * b'\xff'
+ TargetTree.Child[-1].Data.Data += self.Remain_New_Free_Space * b'\xff'
+ else:
+ TargetTree.Data.Data += self.Remain_New_Free_Space * b'\xff'
+ New_Free_Space = BIOSTREE('FREE_SPACE')
+ New_Free_Space.type = FFS_FREE_SPACE
+ New_Free_Space.Data = FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
+ TargetTree.insertChild(New_Free_Space)
+ self.Remain_New_Free_Space = 0
+ if TargetTree.type == SEC_FV_TREE:
+ Size_delta = len(NewData) + self.Remain_New_Free_Space - len(TargetTree.Data.Data)
+ TargetTree.Data.Header.FvLength += Size_delta
+ TargetTree.Data.ModFvExt()
+ TargetTree.Data.ModFvSize()
+ TargetTree.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetTree)
+ TargetTree.Data.ModCheckSum()
+ elif TargetTree.type == SECTION_TREE and TargetTree.Data.Type != 0x02:
+ New_Pad_Size = GetPadSize(len(NewData), 4)
+ Size_delta = len(NewData) - len(TargetTree.Data.Data)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
+ self.Remain_New_Free_Space += Delta_Pad_Size
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ TargetTree.Data.Data = NewData
+ if GuidTool:
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
+ ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
+ CompressedData = guidtool.pack(TargetTree.Data.Data)
+ if len(CompressedData) < len(TargetTree.Data.OriData):
+ New_Pad_Size = GetPadSize(len(CompressedData), 4)
+ Size_delta = len(CompressedData) - len(TargetTree.Data.OriData)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ self.Remain_New_Free_Space = len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - len(CompressedData) - New_Pad_Size
+ else:
+ TargetTree.Data.PadData = b''
+ self.Remain_New_Free_Space = len(TargetTree.Data.OriData) - len(CompressedData)
+ TargetTree.Data.OriData = CompressedData
+ elif len(CompressedData) == len(TargetTree.Data.OriData):
+ TargetTree.Data.OriData = CompressedData
+ elif len(CompressedData) > len(TargetTree.Data.OriData):
+ New_Pad_Size = GetPadSize(CompressedData, 4)
+ self.Remain_New_Free_Space = len(CompressedData) + New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData)
+ Size_delta = len(TargetTree.Data.OriData) - len(CompressedData)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ TargetTree.Data.OriData = CompressedData
+ self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
+ self.Status = False
+
+ def ModifyFvExtData(self, TreeNode) -> None:
+ FvExtData = b''
+ if TreeNode.Data.Header.ExtHeaderOffset:
+ FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
+ FvExtData += FvExtHeader
+ if TreeNode.Data.Header.ExtHeaderOffset and TreeNode.Data.ExtEntryExist:
+ FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
+ FvExtData += FvExtEntry
+ if FvExtData:
+ InfoNode = TreeNode.Child[0]
+ InfoNode.Data.Data = FvExtData + InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
+ InfoNode.Data.ModCheckSum()
+
+ def ModifyTest(self, ParTree, Needed_Space: int) -> None:
+ if Needed_Space > 0:
+ if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
+ ParTree.Data.Data = b''
+ Needed_Space = Needed_Space - ParTree.Data.Free_Space
+ if Needed_Space < 0:
+ ParTree.Child[-1].Data.Data = b'\xff' * (-Needed_Space)
+ ParTree.Data.Free_Space = (-Needed_Space)
+ self.Status = True
+ else:
+ if ParTree.type == FV_TREE:
+ self.Status = False
+ else:
+ BlockSize = ParTree.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - Needed_Space%BlockSize
+ if New_Add_Len % BlockSize:
+ ParTree.Child[-1].Data.Data = b'\xff' * New_Add_Len
+ ParTree.Data.Free_Space = New_Add_Len
+ Needed_Space += New_Add_Len
+ else:
+ ParTree.Child.remove(ParTree.Child[-1])
+ ParTree.Data.Free_Space = 0
+ ParTree.Data.Size += Needed_Space
+ ParTree.Data.Header.Fvlength = ParTree.Data.Size
+ for item in ParTree.Child:
+ if item.type == FFS_FREE_SPACE:
+ ParTree.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ ParTree.Data.ModFvExt()
+ ParTree.Data.ModFvSize()
+ ParTree.Data.ModExtHeaderData()
+ self.ModifyFvExtData(ParTree)
+ ParTree.Data.ModCheckSum()
+ elif ParTree.type == FFS_TREE:
+ ParTree.Data.Data = b''
+ for item in ParTree.Child:
+ if item.Data.OriData:
+ if item.Data.ExtHeader:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData
+ else:
+ if item.Data.ExtHeader:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ ChangeSize(ParTree, -Needed_Space)
+ New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ Needed_Space += Delta_Pad_Size
+ ParTree.Data.PadData = b'\xff' * GetPadSize(ParTree.Data.Size, 8)
+ ParTree.Data.ModCheckSum()
+ elif ParTree.type == SECTION_TREE:
+ OriData = ParTree.Data.Data
+ ParTree.Data.Data = b''
+ for item in ParTree.Child:
+ if item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type != 0x02:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type == 0x02:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
+ if ParTree.Data.Type == 0x02:
+ ParTree.Data.Size += Needed_Space
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+ ToolPath = os.path.join(os.path.dirname(ParPath), r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.SectionDefinitionGuid))
+ CompressedData = guidtool.pack(ParTree.Data.Data)
+ Needed_Space = len(CompressedData) - len(ParTree.Data.OriData)
+ ParTree.Data.OriData = CompressedData
+ New_Size = ParTree.Data.HeaderLength + len(CompressedData)
+ ParTree.Data.Header.Size[0] = New_Size % (16**2)
+ ParTree.Data.Header.Size[1] = New_Size % (16**4) //(16**2)
+ ParTree.Data.Header.Size[2] = New_Size // (16**4)
+ if ParTree.NextRel:
+ New_Pad_Size = GetPadSize(New_Size, 4)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ ParTree.Data.PadData = b'\x00' * New_Pad_Size
+ Needed_Space += Delta_Pad_Size
+ else:
+ ParTree.Data.PadData = b''
+ elif Needed_Space:
+ ChangeSize(ParTree, -Needed_Space)
+ New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ Needed_Space += Delta_Pad_Size
+ ParTree.Data.PadData = b'\x00' * New_Pad_Size
+ NewParTree = ParTree.Parent
+ ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE, ROOT_TREE]
+ if NewParTree and NewParTree.type not in ROOT_TYPE:
+ self.ModifyTest(NewParTree, Needed_Space)
+ else:
+ self.Status = True
+
+ def ReplaceFfs(self) -> bool:
+ TargetFv = self.TargetFfs.Parent
+ # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ # NewFfs parsing will not calculate the PadSize, thus recalculate.
+ self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
+ if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size:
+ Needed_Space = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData)
+ # If TargetFv have enough free space, just move part of the free space to NewFfs.
+ if TargetFv.Data.Free_Space >= Needed_Space:
+ # Modify TargetFv Child info and BiosTree.
+ TargetFv.Child[-1].Data.Data = b'\xff' * (TargetFv.Data.Free_Space - Needed_Space)
+ TargetFv.Data.Free_Space -= Needed_Space
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ # Modify TargetFv Header and ExtHeader info.
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # return the Status
+ self.Status = True
+ # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ else:
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ else:
+ # Recalculate TargetFv needed space to keep it match the BlockSize setting.
+ Needed_Space -= TargetFv.Data.Free_Space
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - Needed_Space%BlockSize
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ if New_Add_Len % BlockSize:
+ TargetFv.Child[-1].Data.Data = b'\xff' * New_Add_Len
+ TargetFv.Data.Free_Space = New_Add_Len
+ Needed_Space += New_Add_Len
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ TargetFv.Child.remove(self.TargetFfs)
+ else:
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.Data.Free_Space = 0
+ TargetFv.insertChild(self.NewFfs)
+ # Encapsulate the Fv Data for update.
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ TargetFv.Data.Size += Needed_Space
+ # Modify TargetFv Data Header and ExtHeader info.
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # Start free space calculating and moving process.
+ self.ModifyTest(TargetFv.Parent, Needed_Space)
+ else:
+ New_Free_Space = self.TargetFfs.Data.Size - self.NewFfs.Data.Size
+ # If TargetFv already have free space, move the new free space into it.
+ if TargetFv.Data.Free_Space:
+ TargetFv.Child[-1].Data.Data += b'\xff' * New_Free_Space
+ TargetFv.Data.Free_Space += New_Free_Space
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ self.Status = True
+ # If TargetFv do not have free space, create free space for Fv.
+ else:
+ New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
+ New_Free_Space_Tree.type = FFS_FREE_SPACE
+ New_Free_Space_Tree.Data = FfsNode(b'\xff' * New_Free_Space)
+ TargetFv.Data.Free_Space = New_Free_Space
+ TargetFv.insertChild(New_Free_Space)
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ self.Status = True
+ # Modify TargetFv Header and ExtHeader info.
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ return self.Status
+
+ def AddFfs(self) -> bool:
+ # NewFfs parsing will not calculate the PadSize, thus recalculate.
+ self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
+ if self.TargetFfs.type == FFS_FREE_SPACE:
+ TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData)
+ TargetFv = self.TargetFfs.Parent
+ # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ # If TargetFv have enough free space, just move part of the free space to NewFfs, split free space to NewFfs and new free space.
+ if TargetLen < 0:
+ self.Status = True
+ self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
+ TargetFv.Data.Free_Space = (-TargetLen)
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ TargetFv.insertChild(self.NewFfs, -1)
+ ModifyFfsType(self.NewFfs)
+ elif TargetLen == 0:
+ self.Status = True
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs)
+ ModifyFfsType(self.NewFfs)
+ # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ else:
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ elif TargetFv.type == SEC_FV_TREE:
+ # Recalculate TargetFv needed space to keep it match the BlockSize setting.
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - TargetLen%BlockSize
+ if New_Add_Len % BlockSize:
+ self.TargetFfs.Data.Data = b'\xff' * New_Add_Len
+ self.TargetFfs.Data.Size = New_Add_Len
+ TargetLen += New_Add_Len
+ TargetFv.insertChild(self.NewFfs, -1)
+ TargetFv.Data.Free_Space = New_Add_Len
+ else:
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs)
+ TargetFv.Data.Free_Space = 0
+ ModifyFfsType(self.NewFfs)
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ # Encapsulate the Fv Data for update.
+ TargetFv.Data.Size += TargetLen
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # Start free space calculating and moving process.
+ self.ModifyTest(TargetFv.Parent, TargetLen)
+ else:
+ # If TargetFv do not have free space, need directly move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData)
+ TargetFv = self.TargetFfs.Parent
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ elif TargetFv.type == SEC_FV_TREE:
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - TargetLen%BlockSize
+ if New_Add_Len % BlockSize:
+ New_Free_Space = BIOSTREE('FREE_SPACE')
+ New_Free_Space.type = FFS_FREE_SPACE
+ New_Free_Space.Data = FreeSpaceNode(b'\xff' * New_Add_Len)
+ TargetLen += New_Add_Len
+ TargetFv.Data.Free_Space = New_Add_Len
+ TargetFv.insertChild(self.NewFfs)
+ TargetFv.insertChild(New_Free_Space)
+ else:
+ TargetFv.insertChild(self.NewFfs)
+ ModifyFfsType(self.NewFfs)
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ TargetFv.Data.Size += TargetLen
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ self.ModifyTest(TargetFv.Parent, TargetLen)
+ return self.Status
+
+ def DeleteFfs(self) -> bool:
+ Delete_Ffs = self.TargetFfs
+ Delete_Fv = Delete_Ffs.Parent
+ Add_Free_Space = Delete_Ffs.Data.Size + len(Delete_Ffs.Data.PadData)
+ if Delete_Fv.Data.Free_Space:
+ if Delete_Fv.type == SEC_FV_TREE:
+ Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
+ BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
+ New_Free_Space = BlockSize - Used_Size % BlockSize
+ self.Remain_New_Free_Space += Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
+ Delete_Fv.Child[-1].Data.Data = New_Free_Space * b'\xff'
+ Delete_Fv.Data.Free_Space = New_Free_Space
+ else:
+ Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
+ Delete_Fv.Child[-1].Data.Data += Add_Free_Space * b'\xff'
+ Delete_Fv.Data.Free_Space += Add_Free_Space
+ New_Free_Space = Delete_Fv.Data.Free_Space + Add_Free_Space
+ else:
+ if Delete_Fv.type == SEC_FV_TREE:
+ Used_Size = Delete_Fv.Data.Size - Add_Free_Space
+ BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
+ New_Free_Space = BlockSize - Used_Size % BlockSize
+ self.Remain_New_Free_Space += Add_Free_Space - New_Free_Space
+ Add_Free_Space = New_Free_Space
+ else:
+ Used_Size = Delete_Fv.Data.Size - Add_Free_Space
+ New_Free_Space = Add_Free_Space
+ New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
+ New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
+ New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
+ New_Ffs_Tree.type = FFS_FREE_SPACE
+ New_Ffs_Tree.Data = New_Free_Space_Info
+ Delete_Fv.insertChild(New_Ffs_Tree)
+ Delete_Fv.Data.Free_Space = Add_Free_Space
+ Delete_Fv.Child.remove(Delete_Ffs)
+ Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
+ Delete_Fv.Data.ModFvExt()
+ Delete_Fv.Data.ModFvSize()
+ Delete_Fv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(Delete_Fv)
+ Delete_Fv.Data.ModCheckSum()
+ self.CompressData(Delete_Fv)
+ self.Status = True
+ return self.Status
diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py b/BaseTools/Source/Python/FMMT/core/GuidTools.py
new file mode 100644
index 000000000000..e21d8e0406ae
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
@@ -0,0 +1,152 @@
+## @file
+# This file is used to define the FMMT dependent external tool management class.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import glob
+import logging
+import os
+import shutil
+import sys
+import tempfile
+import uuid
+from PI.Common import *
+from utils.FmmtLogger import FmmtLogger as logger
+import subprocess
+
+def ExecuteCommand(cmd: list) -> None:
+ subprocess.run(cmd,stdout=subprocess.DEVNULL)
+
+class GUIDTool:
+ def __init__(self, guid: str, short_name: str, command: str) -> None:
+ self.guid: str = guid
+ self.short_name: str = short_name
+ self.command: str = command
+
+ def pack(self, buffer: bytes) -> bytes:
+ """
+ compress file.
+ """
+ tool = self.command
+ if tool:
+ tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
+ ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")
+ ToolOuputFile = os.path.join(tmp, "pack_sec_file")
+ try:
+ file = open(ToolInputFile, "wb")
+ file.write(buffer)
+ file.close()
+ command = [tool, '-e', '-o', ToolOuputFile,
+ ToolInputFile]
+ ExecuteCommand(command)
+ buf = open(ToolOuputFile, "rb")
+ res_buffer = buf.read()
+ except Exception as msg:
+ logger.error(msg)
+ return ""
+ else:
+ buf.close()
+ if os.path.exists(tmp):
+ shutil.rmtree(tmp)
+ return res_buffer
+ else:
+ logger.error(
+ "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
+ logger.info("Its GUID is: %s" % self.guid)
+ return ""
+
+
+ def unpack(self, buffer: bytes) -> bytes:
+ """
+ buffer: remove common header
+ uncompress file
+ """
+ tool = self.command
+ if tool:
+ tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
+ ToolInputFile = os.path.join(tmp, "unpack_sec_file")
+ ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")
+ try:
+ file = open(ToolInputFile, "wb")
+ file.write(buffer)
+ file.close()
+ command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]
+ ExecuteCommand(command)
+ buf = open(ToolOuputFile, "rb")
+ res_buffer = buf.read()
+ except Exception as msg:
+ logger.error(msg)
+ return ""
+ else:
+ buf.close()
+ if os.path.exists(tmp):
+ shutil.rmtree(tmp)
+ return res_buffer
+ else:
+ logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
+ logger.info("Its GUID is: %s" % self.guid)
+ return ""
+
+class GUIDTools:
+ '''
+ GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools.
+ '''
+ default_tools = {
+ struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", "TianoCompress"),
+ struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", "LzmaCompress"),
+ struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", "GenCrc32"),
+ struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", "LzmaF86Compress"),
+ struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", "BrotliCompress"),
+ }
+
+ def __init__(self, tooldef_file: str=None) -> None:
+ self.dir = os.path.dirname(__file__)
+ self.tooldef_file = tooldef_file if tooldef_file else os.path.join(
+ self.dir, "FMMTConfig.ini")
+ self.tooldef = dict()
+ self.load()
+
+ def VerifyTools(self) -> None:
+ """
+ Verify Tools and Update Tools path.
+ """
+ path_env = os.environ.get("PATH")
+ path_env_list = path_env.split(os.pathsep)
+ path_env_list.append(os.path.dirname(__file__))
+ path_env_list = list(set(path_env_list))
+ for tool in self.tooldef.values():
+ cmd = tool.command
+ if os.path.isabs(cmd):
+ if not os.path.exists(cmd):
+ print("Tool Not found %s" % cmd)
+ else:
+ for syspath in path_env_list:
+ if glob.glob(os.path.join(syspath, cmd+"*")):
+ break
+ else:
+ print("Tool Not found %s" % cmd)
+
+ def load(self) -> None:
+ if os.path.exists(self.tooldef_file):
+ with open(self.tooldef_file, "r") as fd:
+ config_data = fd.readlines()
+ for line in config_data:
+ try:
+ guid, short_name, command = line.split()
+ new_format_guid = struct2stream(ModifyGuidFormat(guid.strip()))
+ self.tooldef[new_format_guid] = GUIDTool(
+ guid.strip(), short_name.strip(), command.strip())
+ except:
+ print("GuidTool load error!")
+ continue
+ else:
+ self.tooldef.update(self.default_tools)
+
+ self.VerifyTools()
+
+ def __getitem__(self, guid) -> None:
+ return self.tooldef.get(guid)
+
+
+guidtools = GUIDTools()
diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
new file mode 100644
index 000000000000..18f0cff96e4b
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
@@ -0,0 +1,18 @@
+## @file
+# This file is used to define the Fmmt Logger.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+##
+
+import logging
+import sys
+
+FmmtLogger = logging.getLogger('FMMT')
+FmmtLogger.setLevel(logging.INFO)
+
+lh=logging.StreamHandler(sys.stdout)
+lf=logging.Formatter("%(levelname)-8s: %(message)s")
+lh.setFormatter(lf)
+FmmtLogger.addHandler(lh)
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
new file mode 100644
index 000000000000..1a6c67056266
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
@@ -0,0 +1,54 @@
+## @file
+# This file is used to define the printer for Bios layout.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+def GetFormatter(layout_format: str):
+ if layout_format == 'json':
+ return JsonFormatter()
+ elif layout_format == 'yaml':
+ return YamlFormatter()
+ elif layout_format == 'html':
+ return HtmlFormatter()
+ else:
+ return TxtFormatter()
+
+class Formatter(object):
+ def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
+ raise NotImplemented
+
+class JsonFormatter(Formatter):
+ def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
+ try:
+ import json
+ except:
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
+ return
+ print(outputfile)
+ if outputfile:
+ with open(outputfile,"w") as fw:
+ json.dump(layoutdict, fw, indent=2)
+ else:
+ print(json.dumps(layoutdict,indent=2))
+
+class TxtFormatter(Formatter):
+ def LogPrint(self,layoutlist: list) -> None:
+ for item in layoutlist:
+ print(item)
+ print('\n')
+
+ def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
+ print(outputfile)
+ with open(outputfile, "w") as f:
+ for item in layoutlist:
+ f.writelines(item + '\n')
+
+class YamlFormatter(Formatter):
+ def dump(self,layoutdict, layoutlist, outputfile = None):
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
+
+class HtmlFormatter(Formatter):
+ def dump(self,layoutdict, layoutlist, outputfile = None):
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
\ No newline at end of file
--
2.27.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
2021-12-01 1:29 [PATCH 1/1] BaseTools: Add FMMT Tool Yuwei Chen
@ 2021-12-03 3:18 ` gaoliming
2021-12-06 8:34 ` Yuwei Chen
0 siblings, 1 reply; 6+ messages in thread
From: gaoliming @ 2021-12-03 3:18 UTC (permalink / raw)
To: devel, yuwei.chen; +Cc: 'Bob Feng'
Yuwei:
I did some test and meet three problems. I submit BZ
https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check.
Thanks
Liming
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen
> 发送时间: 2021年12月1日 9:29
> 收件人: devel@edk2.groups.io
> 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>
> 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
>
> The FMMT python tool is used for firmware files operation, which has
> the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function:
>
> 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files)
> 2.Add a new FFS into a FV file (both included in a FD file or not)
> 3.Replace an FFS in a FV file with a new FFS file
> 4.Delete an FFS in a FV file (both included in a FD file or not)
> 5.Extract the FFS from a FV file (both included in a FD file or not)
>
> Currently the FMMT C tool is saved in edk2-staging repo, but its
> quality and coding style can't meet the Edk2 quality, which is hard to
> maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
>
> The new Python version keeps same functions with origin C version. It
> has higher quality and better coding style, and it is much easier to
> extend new functions and to maintain.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847
> PR Link: https://github.com/tianocore/edk2-basetools/pull/12
> RFC Link: https://edk2.groups.io/g/devel/message/82877
> Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
>
> Cc: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
> ---
> V4 fixed the Linux file format issue and known bugs.
> BaseTools/BinWrappers/PosixLike/FMMT | 14 +
> BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
> BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
> BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 +
> .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
> .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes
> BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
> .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++
> BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++
> .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++
> BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
> BaseTools/Source/Python/FMMT/README.md | 180 ++++++
> BaseTools/Source/Python/FMMT/__init__.py | 0
> .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
> BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++
> .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
> .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
> .../Source/Python/FMMT/core/FMMTParser.py | 86 +++
> .../Source/Python/FMMT/core/FvHandler.py | 521
> ++++++++++++++++++
> .../Source/Python/FMMT/core/GuidTools.py | 152 +++++
> .../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
> .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
> 22 files changed, 2432 insertions(+)
> create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
> create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
> create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
> create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
> create mode 100644
> BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> create mode 100644
> BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
> create mode 100644 BaseTools/Source/Python/FMMT/README.md
> create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
> create mode 100644
> BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
> create mode 100644
> BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> create mode 100644
> BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
> create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> create mode 100644
> BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
>
> diff --git a/BaseTools/BinWrappers/PosixLike/FMMT
> b/BaseTools/BinWrappers/PosixLike/FMMT
> new file mode 100644
> index 000000000000..5f5519e1e1b6
> --- /dev/null
> +++ b/BaseTools/BinWrappers/PosixLike/FMMT
> @@ -0,0 +1,14 @@
> +#!/usr/bin/env bash
> +#python `dirname $0`/RunToolFromSource.py `basename $0` $*
> +
> +# If a ${PYTHON_COMMAND} command is available, use it in preference to
> python
> +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
> + python_exe=${PYTHON_COMMAND}
> +fi
> +
> +full_cmd=${BASH_SOURCE:-$0} # see
> http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a
> good choice here
> +dir=$(dirname "$full_cmd")
> +cmd=${full_cmd##*/}
> +
> +export
> PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY
> THONPATH:+:"$PYTHONPATH"}"
> +exec "${python_exe:-python}" -m $cmd.$cmd "$@"
> diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> new file mode 100644
> index 000000000000..f0551c4ac54a
> --- /dev/null
> +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> @@ -0,0 +1,4 @@
> +@setlocal
> +@set ToolName=%~n0%
> +@set
> PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA
> SE_TOOLS_PATH%\Source\Python\FMMT
> +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
> diff --git a/BaseTools/Source/Python/FMMT/FMMT.py
> b/BaseTools/Source/Python/FMMT/FMMT.py
> new file mode 100644
> index 000000000000..5028d8446ee0
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/FMMT.py
> @@ -0,0 +1,117 @@
> +# @file
> +# Firmware Module Management Tool.
> +#
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +# Import Modules
> +#
> +import argparse
> +import sys
> +from core.FMMTOperation import *
> +
> +parser = argparse.ArgumentParser(description='''
> +View the Binary Structure of FD/FV/Ffs/Section, and
> Delete/Extract/Add/Replace a Ffs from/into a FV.
> +''')
> +parser.add_argument("--version", action="version", version='%(prog)s
> Version 1.0',
> + help="Print debug information.")
> +parser.add_argument("-v", "--View", dest="View", nargs='+',
> + help="View each FV and the named files within
> each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
> +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
> + help="Delete a Ffs from FV: '-d inputfile
> TargetFfsName outputfile TargetFvName(Optional,\
> + If not given, wil delete all the existed target
Ffs)'")
> +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
> + help="Extract a Ffs Info: '-e inputfile TargetFfsName
> outputfile'")
> +parser.add_argument("-a", "--Add", dest="Add", nargs='+',
> + help="Add a Ffs into a FV:'-a inputfile
> TargetFvName newffsfile outputfile'")
> +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
> + help="Replace a Ffs in a FV: '-r inputfile
> TargetFfsName newffsfile outputfile TargetFvName(Optional,\
> + If not given, wil replace all the existed target
> Ffs with new Ffs file)'")
> +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
> + help="The format of log file which saves Binary
> layout. Currently supports: json, txt. More formats will be added in the
> future")
> +
> +def print_banner():
> + print("")
> +
> +class FMMT():
> + def __init__(self) -> None:
> + self.firmware_packet = {}
> +
> + def CheckFfsName(self, FfsName:str) -> str:
> + try:
> + return uuid.UUID(FfsName)
> + except:
> + return FfsName
> +
> + def View(self, inputfile: str, logfiletype: str=None, outputfile:
str=None) ->
> None:
> + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
> + filetype = os.path.splitext(inputfile)[1].lower()
> + if filetype == '.fd':
> + ROOT_TYPE = ROOT_TREE
> + elif filetype == '.fv':
> + ROOT_TYPE = ROOT_FV_TREE
> + elif filetype == '.ffs':
> + ROOT_TYPE = ROOT_FFS_TREE
> + elif filetype == '.sec':
> + ROOT_TYPE = ROOT_SECTION_TREE
> + else:
> + ROOT_TYPE = ROOT_TREE
> + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
> +
> + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile:
str,
> Fv_name: str=None) -> None:
> + if Fv_name:
> + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> outputfile, uuid.UUID(Fv_name))
> + else:
> + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> outputfile)
> +
> + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) ->
None:
> + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
> +
> + def Add(self, inputfile: str, Fv_name: str, newffsfile: str,
outputfile: str) ->
> None:
> + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile,
> outputfile)
> +
> + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str,
outputfile:
> str, Fv_name: str=None) -> None:
> + if Fv_name:
> + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
newffsfile,
> outputfile, uuid.UUID(Fv_name))
> + else:
> + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
newffsfile,
> outputfile)
> +
> +
> +def main():
> + args=parser.parse_args()
> + status=0
> +
> + try:
> + fmmt=FMMT()
> + if args.View:
> + if args.LogFileType:
> + fmmt.View(args.View[0], args.LogFileType[0])
> + else:
> + fmmt.View(args.View[0])
> + if args.Delete:
> + if len(args.Delete) == 4:
> +
> fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
> + else:
> +
> fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
> + if args.Extract:
> + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
> + if args.Add:
> + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
> + if args.Replace:
> + if len(args.Replace) == 5:
> +
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> 3],args.Replace[4])
> + else:
> +
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> 3])
> + # TODO:
> + '''Do the main work'''
> + except Exception as e:
> + print(e)
> +
> + return status
> +
> +
> +if __name__ == "__main__":
> + exit(main())
> diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> new file mode 100644
> index 000000000000..aa2444f11b38
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> @@ -0,0 +1,11 @@
> +## @file
> +# This file is used to define the FMMT dependent external tool guid.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
> +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
> +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
> +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
> +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
> diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..7cc806a0133413a4aa037
> f1d43d80000546a5246
> GIT binary patch
> literal 29515
> zcmcG$bySpZzxIs{h;*kQ-QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+
> z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@-mueX!oILX!ky#
> KL)-b
> z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx
> mKL
> z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K
> zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A-~0
> Os
> zomQa`7xm?Vn1W*P-%s-jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK
> u0
> zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{)
> abe
> z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He
> 5*9B
> z*-Jfk;((ApOh<DBpW00KVT-d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_
> e
> z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU-u*mWM
> w)
> zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK
> !@Kal=
> zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04
> 1
> z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^
> W
> zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy-4#Vx^C$n*R(S2#<fkNRn8K6C!26<
> O
> zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<-BdBP<AmFX)1
> _0^
> zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt-C5{L_
> zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@
> YoAv$
> zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o%
> z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT
> oZlL
> z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk`
> zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@-nrRU
> zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr
> k
> z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX-Sd(_WJqP_|B0b^CxF|AoL+M;CA
> Vm
> zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT+
> 5
> z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu
> D}JIY
> zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY
> y
> z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk
> znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h
> W653
> zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz
> z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8
> zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B-8MDTh)0*RC#EN#u!^
> nVH$m
> zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd
> m$
> zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^|
> 1l
> zs#*3J+AHPINX8;)QiLwy6-Z2S$&-jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep
> z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l
> As
> zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$-*{a=n
> ?K!V
> zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb}
> rWM
> zKu}~4YZm`$e$42-HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k
> sy
> z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU
> CN$
> z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG
> |Lx3X6
> zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt
> P
> z4}!3MY9t1~*EvD4lR~M)=-uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P!
> zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b
> 3+@WmhX
> z>ZGUkb+ts3Tk&n$W-n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C
> Qkvs@
> zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)-!o_k?1CJInjgyPOhp1A%MDgUMftCS$J~
> zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA-1pvp;SGObla#%wB7pN+^fnJc#a?jT)B
> 8
> zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&-l~CT@#e0@&
> vmX7
> zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*-7<1UbT|>O|@l;?iY=`N4
> z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*%
> zg_$H!-&YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW
> z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^(
> F<T-(}
> zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy`
> TJt!CY
> zZezN}4wz=94~>e){&{8Z-!pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c
> PC
> z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4|
> bv
> zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb
> HJ6Kn
> zcW5oArH&O&iy$dE`i=$R|12WEk|rl78-3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq
> ;E
> zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9
> uN5=1
> z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu
> S
> zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D
> p?;
> zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)%
> zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw
> Z%2
> z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl;
> utt
> z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5
> W0`!
> z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59
> {es93C0D
> zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@>
> 3g{x5
> z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^-1kaKB+d7T
> Drx2
> ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB
> (wX
> zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u?
> 3XkOqt
> zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX
> DU
> z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy
> z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y-oCVYo9xaw1S?6YWT`9V^=h<QFr
> Q}
> zHAIHMg-^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0
> NyW
> zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t-!imMfLU8CUGd)w
> ^
> zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ
> L
> zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j}
> *
> zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r-rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb
> z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ-?%k;$V^R5XclbB
> !ZjD
> zt=UY&?7-X9<AFk^dEO%~_#P&-r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(=
> tOwMb
> z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0
> lL_
> z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+
> YC
> zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc
> OCnX
> za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss
> @v
> zSgaMn{Kb=7It4nMlG8iA*-tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH
> Y<UT
> zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M
> y7^
> zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf
> z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS-w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR
> A2ii
> z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB
> z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V-{XCZzitML(}hGq&W
> zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q
> zeC@D`Bk`qD-*FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS
> bRs
> zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw
> z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0
> zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9<
> 3
> zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO
> 7{FtVq
> zO<`-jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT
> -Ie5
> z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg
> u
> zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV
> aGRj!
> z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D
> h
> z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o
> M(_fvkH
> zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY
> $
> z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H
> @@5TTQn
> z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|-*^dW
> 5
> zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG-=t3xx
> w9x1s>
> zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)-^X=?*fdvD
> OD
> z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ-h^Vc`*v)kGJbP?dUI5
> #x
> z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o
> S
> zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5
> sA
> zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A
> -H_
> zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq
> Cg}S
> zLrkk-#H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB
> $or-
> z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{
> }W
> zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo
> wW$
> znAFU~_wY4f2q?dP-TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D
> &U93
> zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>-&vpdCAooZEI#
> wk{a
> zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T)
> z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c#
> ~d
> zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt
> z0zq
> z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5-iu6O
> P@(+
> zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p-UTYHHHGHJ
> a^R
> z4e9LSAJ3h-L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR
> zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO<
> C
> zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B-aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad
> u
> z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<-CE_@x)deTU#?kEtpbb>pf
> JQ
> zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#-<B(*%Baj
> w8bG
> z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4
> pUp
> z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j
> kUEqfGQeE
> zsxs)ys+*k-a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j
> zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G*
> Aw_D
> z`pX6=`~Txca<xNgGlAlLtXNkpUFznb-9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1
> D
> z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7
> X^
> zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe
> pj>)
> z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID<
> <
> z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(`
> 3v
> zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@
> Y8EQ
> zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>-&_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar
> }<t
> zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+
> -Xd
> zF@iS2N;c?&GGNFv1f-nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF
> lqL!
> z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$
> zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M
> TTEJ1
> z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+-iRa;O_hx8v1
> pM
> zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ
> i-E
> z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{-<qQVg#k>78
> zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#-fvwHu8795}6
> W
> z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-`
> X2@$m4(
> zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r
> A*%
> zYs#3InBRHdV-hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L
> zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09
> 9|n
> zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@
> u
> zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6%
> Ib
> zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU
> *R)a;LqQ
> zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w
> vUtt
> zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c
> zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE-{)&!(C4TBm|f@H
> Qxf
> zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx
> &
> zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%=
> WmbM0
> z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl-q3
> 6
> zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6-LubB
> c
> z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha
> zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh
> g
> zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$
> z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB
> k2bs
> zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#(
> t_TQ<~
> zPpkWLsyFv=kpB8wMCMJ461d6-pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB
> WqSJV
> zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u
> w9Z
> zIQm^k)g4d<<I-`XDjPImuOoV3k-fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@
> z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ-q&>D;Lu4Y*65q
> 0=*^{N
> zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT
> bF
> ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv<
> z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv
> L
> zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5
> g^7sU
> zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*>
> 4
> zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t`
> !
> zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$-5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In
> Z;K
> z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u=
> z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H-JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V
> J)p
> zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3#
> MZ@o
> z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G-;I<V5t?h0H4ZJmY{X!kNZmp3
> lj
> zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo#
> 0G7mqVU
> zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx|
> C^
> zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os-Y*<Arj
> @T
> zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U
> zv&u^91`JfQ*$6*pQVC-u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z
> T
> zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB-Dh>thr$2oA7josXpNOr1+
> 57
> z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~
> zUK--r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd
> V-z
> zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY
> VB&
> zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w*
> oz
> z@o`0!-;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe`
> m
> zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B-{
> Y
> z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T
> nb329
> zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY-w@fzc7$VQ4tNhm5V8N(S
> dPS
> zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8-C&&+<Zy65#V5
> z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw
> hf!j
> zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j-W2=miHT
> no
> zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1-qeL<q;^=2F}
> T|
> zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC
> pwM(WO
> z`0>B1JR`+)ZDiuFC!F7Fv-o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF
> =-
> zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP
> (nm$
> zgn7NXKD%P4(&M*qR-(Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c
> <p
> zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av-4<bCdT@wTC>GBy~|DLthW;7TX
> boX
> z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C-ixZ#a}(P
> %71
> zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg-Xm`x2Xg
> z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA
> qe
> z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4
> z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8
> z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH
> T-
> zH|7YArh@+FLkg-WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3
> UO`cs
> zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB)
> 0
> zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25
> zwYj@;E^4?Qbs%M^x|g>zUX-moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A!
> IRJo
> zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL
> wpm5C
> zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd-6Ob;XHAbX$!ujWY~NcR
> 9fz?
> zA{m&^E5y==&`JNCtrsVh*i&iF-?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj
> mI
> zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r
> z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi-6N<6qBRAbW>R|5Yvc<6M7$K
> w`6V
> zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2
> q4`
> z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^
> |E7=&
> zinFr&rqO5i{Cmn-mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U
> ab
> zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO
> zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw
> n>R7
> zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc#
> zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)-%FkT
> XOBB
> zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`&
> uLj
> zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({|
> *p
> zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X-Z#BGRQr2o
> aKQ
> zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt(
> zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q-=mGP;tP2mL@wi(xnoq6<%Cb76W9}f
> Ny@K
> zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O
> pL)Fq>4
> zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf
> Mt
> z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@
> @Yi
> zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v
> E`
> zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u
> Q@)u
> zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4
> PQQA
> z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4
> ~<o<8e
> zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D
> <J
> z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F`
> F4&
> zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb
> E5
> z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z
> #~g=O
> zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k
> e1
> z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi-O@I~^x{;?=(JqlKKAP)z9
> zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF%
> *F9!4P^
> zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N)
> x`
> zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82#
> hx6wR
> z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp%
> FUzQ
> zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb
> 4G2Su$
> zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&-TpdZ4Sm%Z^!(mu%Q
> -d6
> z8CSq{iA^TAM+Sba`K-HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd
> qw
> z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci
> zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;>
> m
> zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW
> DlU4VKO$Q7#
> zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF
> m!6A
> z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s
> 2
> zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq
> uX
> zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b
> URoM
> z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T;
> dh
> z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b-+I~rxJ^NTX^hUZQ_xQHPN@RYRbv=
> OAaP0<
> z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv
> Yry
> zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls>
> &a*
> z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8-K
> z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m
> zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j
> >
> zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW
> d@XHe
> zvn*f~#Zp|_nC%d-|J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`<
> x-t
> zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc
> ny<
> z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d-chHgloB
> Wr|bA
> zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v
> z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH
> y
> z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ
> u7Dn
> z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_-YI>c&n(Yp>Lyir
> ~@
> zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-<
> h!%=
> z*&>EVOnq&ad$05T2-6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7
> Tcf_kK
> zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve
> HMi
> zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?-}0}e(EkUQx{gt5Qv2GI}9K
> s
> z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~
> |
> zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y
> *YvY
> z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW-`VxgtihK5w!+4bR%e5W4fcRUBu
> t}=3
> z-)H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*&
> MCZ
> zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&-
> zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}#
> (sm;
> zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzcE
> -_;{w
> zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0
> R!C
> z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h
> o5lF
> z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+
> &#`
> zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD-
> m$*V
> zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt
> a
> zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+&
> `~cD
> zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@>
> U5(
> zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#>
> i8(
> zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV
> zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ
> zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw
> JY7J-w
> zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^
> NQcQ
> zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~
> z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o
> m
> zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y
> C
> z<!BcWm*#gI)Q;$>P(-^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$
> VQ0FW
> zGH;^fyr(a?>xrm&;uh2hKqp>D-AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7
> aZ
> ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z?
> !Ajpt
> z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha
> 7z
> z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ
> @Ox
> zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0
> l
> zVjM=Qw37|BK0|)-NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj
> z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II
> Uz
> zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt}
> MtL
> zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr-NH4*=bhL7Tc<AKzmQSP`%KB$^O6d
> paf~!
> zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE-1A
> zv1;CZ!z3UqKTUkaP--mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw*
> zJq48N!P2zA_Le>{HRZryvx7sxFBEjO-t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs
> Eg
> z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$
> ^*M}
> zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v
> z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr
> Z?;v@B
> zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_
> zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb)
> OG
> z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK
> n{X
> z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1
> pZ%wkIe6
> zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY-
> pR
> zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75!
> sSCv
> zOI0V)+9b%8^ak8NWz6d-k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW&
> !*&3(
> zh6=X0QmwWX9XHj5l1@tYGXVhG)-Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+
> HQzlwT
> z8x|ZZV|V(-wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH
> Psf
> z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs
> s8V7
> z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj
> z5_5g=+O$i$k;%-1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO
> 5%a
> z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z-
> qZ)Dr
> z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E
> NpfA
> zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0
> zd*)2v-xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k
> XtIl50
> zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F
> Um
> zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}-_g|Ab91$j2ad2jnt
> +=M
> znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg
> zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY
> QmA
> zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf
> HM#
> zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5
> VI=
> z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL-`KrNzBi@nX
> eF
> z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r
> ;!F
> z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t
> xQ
> z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y|
> p
> zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e
> zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp-=DEZ9aDLwe&emQpH(ng8O8f|
> N|b
> zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO
> -%SX
> zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm-Et@op
> ^sZ
> z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW
> 5K
> zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes
> )B
> zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o-9JRkFbj^Cvi9
> l63
> z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v
> +d4T
> z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^
> `QF}Y
> zTI!eAjaQV1M2^`)i<P>gsTGz-UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew<
> 3
> z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V
> mt<0
> zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^
> +
> zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=-Jy}m
> Zu
> zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^-&~y
> sjCF
> zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC-gE$~l!e
> zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^-Xvwp0G$Ypd!Rc|ZQdfy
> )>q
> z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d-LF2U(
> N;ve
> z`|0v08lJhE-43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK|
> T
> z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`(
> m
> zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<-L*AxFh1pz<SsamItVw$U*
> KSpI
> z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ
> G;
> zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G
> iy|~
> z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw>
> 1jO
> zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR
> ~#6
> z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W
> ;)#
> zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb
> z$n8i2c(^-EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN
> 9%7z
> zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J-iap7Ma
> 7+~R
> zr)wN#;gC`Q+R-b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7
> sn
> zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw
> HK
> zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz
> zM
> zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c*
> wq)=
> z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF
> S*
> z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk-
> _@X*
> za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~
> I4
> zMe~hi*!yt-e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW
> B@
> ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z
> aMs11
> zN|%vFr}N@XKRz-JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW&
> XA7Ak
> z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY
> M
> z{((;&-ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB
> z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S
> KDX
> zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`-jSejso!@e^uJ
> <
> zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG
> HTu
> znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH
> d+
> zMY-=jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+
> k&+m
> z%ZWm1z4nMfO?(4A8G8!-oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+-
> ^I
> z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4
> e|4?
> ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj#
> ^0e
> zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E;
> aO
> zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI)
> d
> z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B
> zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA-+T`x7hrGd7
> zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G-tP(~dNEPPRy<$X2&|cAe5A
> }bI
> z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C
> zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM#
> g8_@a_!
> z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0
> 06
> zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q#
> N
> zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@
> M4b@Z
> zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A
> W
> zDssgPVVyB-*vr3ad5~B-)<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f
> wo)
> zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H-BNMSM32B_HnUIx=z%Fof0ntPF#j9W
> WX+
> zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u
> ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L
> D0
> z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$
> T2!
> zdK(Bjx%p|zQnoY<UWi-I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb
> Nki
> zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP>
> u{Cu
> z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA
> z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a
> @W=
> zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p
> zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b
> aP~U
> z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS?
> dZ
> z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T-wQgkxi3VLQjxyVy
> zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod
> Up5h
> zqp!T4LK?<KJ()xH%)kcP!N1qc-swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n
> rr|
> z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g
> $M
> zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG
> nyO9
> z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<=
> QC
> z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO
> 2Oi
> z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl
> zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI
> +uw!;
> zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL
> z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2
> )p
> zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B
> c;i!
> zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV-Hkg6e~c%ayO
> }6e
> z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf
> zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx
> yhi
> zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE
> FSC
> zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz-*>o*46xhGpS8Y;XQ
> *+
> z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_;
> $3Q
> zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9
> d
> zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq
> b-|
> zOx|zYa;20oYTSb^$f*puP6`{=@+R-cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs
> C^
> zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv
> $0gQ
> z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#-a+SMQ@Tv59b7zfSbF`J@FL3|c(?~
> Mw6
> zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva
> Y
> z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK
> J}o!
> zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y
> GYg
> zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE
> z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ
> QYoK
> zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ-~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M
> zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{-p3I!HZ(Q(cX|
> H6u
> zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@
> wl
> z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_-`ds;ZHWg<At
> o
> z_!d&4;KL)krKVbM_-%V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3
> zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW?
> s&KLw+
> zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB(
> ~6l
> z==pSlrsfT~2W{Zj-#*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU
> Xk
> zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1(
> zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$-Ow%eFF$z!@
> J+-
> zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R
> zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR
> +Kh}Lr
> zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2
> zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{aQ
> z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n
> C)ZrQ
> zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7
> 6h
> zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW
> z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C
> Wu8yz
> zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{)
> zw7h-b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{
> $z*$
> z=zlg}>gO`p-0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i
> B
> z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul
> @}
> z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6
> nc`
> z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU
> z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7
> 2C@
> zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM
> e
> zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2
> z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg
> 7
> z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP
> Su5
> z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{
> 2
> z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^
> h{bn+
> zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4
> uNZt+
> z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH
> @17p
> z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@-1E
> 7@!
> z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv
> UZA3
> ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13
> z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq
> z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2
> zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH
> zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY
> Ep}s
> z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox
> zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n
> z{aj
> zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT
> zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC&
> Q*
> z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@
> 1dFnWtdD
> zNVk1t_y;mT-k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr
> q=F
> zDjf9;-DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu
> WqN
> zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM
> o0
> zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p
> h-@
> z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK
> HW
> z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y
> nKla
> zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D!
> B
> z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp
> Zw$e
> zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c;
> za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g%
> mO
> zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_-Hx
> _2|
> zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6
> R4Rr
> zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N
> zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd
> zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6&
> u@Wv
> z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6
> 9Jd_v
> zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a
> z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56-8|HN!VHDt?X!7%VRV8^)x
> U0D
> z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e-h|F2yMD^>eWe)o2zdCq!a(n?9
> >#f
> z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO}
> F
> z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ#
> qTm(t
> zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;-}$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG(
> 6c
> zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr
> a
> zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU
> zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h
> <pq
> zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC
> Mb
> zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn?
> G
> z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm!
> &o
> zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem
> zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e-RM%C;1ods}_Dy6=&aE!DH&yZe}Po
> l_s&^
> ztt&=Z6-Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D}
> 1
> zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6
> Vm*0jD
> zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS
> z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|>
> `XAJs
> z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL&
> z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A-
> Mf
> z<-7K<$G6OrXCLF&g-X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN
> z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il
> {Aw9
> zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87
> CC@??
> zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo-^_Ot?JdLg|1aj$ifpl{V^
> zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C-R#Vcu^1XBSkb
> =
> zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o--&31)1TQ|Q%EAhuIXZd?<`#d
> Hj
> zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1-k2y^JQ>&e<>!r+45@!bqRS
> D
> zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#=
> z8@e(3tmNqVWq`wXV!qG<JTY-Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3
> e-e`uBA
> zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq-a`x7HIXwJ=fQf_ro@BbDbjW+5A=13
> ?M
> zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A
> z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71-xIa;QyQ+A+=ch*hu
> DSEC
> cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0&
>
> literal 0
> HcmV?d00001
>
> diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..6335653ece1605cd0c53b
> d2cc2bc21d57d213dae
> GIT binary patch
> literal 79906
> zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$
> C9i
> zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c
> }
> zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I
> {
> z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7
> MH&Y
> zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM|
> NThc
> zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M-DQkUsiWm_>>F`39z{F@w
> QiMSjA
> zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^
> -oj
> zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB-Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY
> zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1>
> z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o
> OF-(
> ze(GY+PNz-|cTO$duNND)-{Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR&
> %J
> zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{
> z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb-jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD
> z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW
> %3^
> zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k
> vG
> zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3d
> R&s7P
> z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq-u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt
> z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm-&}GK
> x(<
> zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n
> -t?
> z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9
> *
> z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V
> 4Ni
> zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu
> ^%
> z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4
> C=
> zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+-DI^9d~!WoYX0A1$
> X%
> z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=-;cGp&
> 30
> z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X-)f2nzV!Q^qU_$m?x3Qsm
> ex3w
> zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j-#eg0l|9C)@T=sxzA
> k
> zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E
> NK9U!c
> z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4-eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb
> nmP
> zDdg?>-mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a
> R`2d(
> zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|<
> D<#}
> zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o
> 8
> zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e-W7
> zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_
> P
> zLL$x|O2|$4_>pUK%4O!a-6#4-alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT
> z`*O5L^inXLpWTzaUm%TSE<U`-Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs
> p!
> z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{
> z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR-#Ov6((s
> C#V
> zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T
> @9C
> zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&-x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4
> n=
> z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ
> e
> zuk|Q9*5!@y$-x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF
> 8^
> z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G-<BptWKsIz=W_P31e
> zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2
> &++Q{
> zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv
> Y!Bo}
> z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8
> P<
> zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z
> RAE+
> z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K
> z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e
> g
> zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA-UumgF$+yN
> ^{w
> zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR
> {j
> z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0-9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N
> XFE
> zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj
> zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z
> v^+
> zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)#
> Yhjbc;
> z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_
> Rx-k$
> zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r
> !n
> z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#};
> @Voub
> ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX
> #p{~VSr
> zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2
> 6z*3T
> znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^-D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d
> NUT
> zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s
> zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ
> znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp
> utI
> ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg-y}h%yHH_0H
> a8<A
> zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps
> >6Mc?h
> z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e
> TQ%X
> zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M-G
> 2{M
> znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u&
> Jp
> zum8=!r+B_~0&G%_%VRj-TC~2mL-ot07njmvdGDQXScyh?WMt%s_phdFXEx;v
> A6W{j
> z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam
> `+(0
> z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29
> @
> z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On
> @-tU=bw%s
> zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{
> YugQ}
> zM8N()%W_L~2Da%^cIAH-<-an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v*
> wES
> z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H-AhOC|1BQKucrND=U^;)jo
> OarT+
> zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s-8ymFk^)c%duzJ;nL)3Nu
> }
> z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx-&f`Khm=*XOz
> ?S<B}
> z%8w-r#pfF@&BNC-fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2
> 2QC!aZ
> ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP
> W
> z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!%
> U)1gME
> zXaJ!`N#R-_I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk
> z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@
> ZQJwxv
> zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM
> |FT
> z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M
> Re<Cff;
> z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{
> P5
> zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L
> zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg
> uoJJp
> zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^
> AC
> z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f
> z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7-rV
> rF
> zg3F-R(c*YRq-@%swU!k`8-wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R(
> 9R2;h
> z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs
> 08Z
> zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r
> wY
> zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a
> %KM75
> zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2
> z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW
> G
> zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K
> 9+X
> zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S
> z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ
> pa
> zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds
> zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^
> rj9
> z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI
> 7hE2
> z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U
> Qp
> zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P
> u^kAGC
> zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p
> &qx
> zu6PAe_-|zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce
> Wy}o-
> zDVg;W`B&bT@-K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~
> zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV
> >9
> zsE<cJl8QUANXMMXD!_@-n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P
> q
> z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC-=%ubEfAZ
> @
> zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^
> zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA
> R5My
> zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v
> adA
> z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L
> ~M
> z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW-e{py@
> Z9m
> zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d
> zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G
> %
> zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y
> 1
> zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI>
> pGi
> z+_V-c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+
> X
> zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj
> !|*
> z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU
> M9o^q
> zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k
> z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y
> zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G
> tq
> z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp%
> wS#
> zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2
> iu$
> zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^
> Q
> zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{
> znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x
> z-axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b
> zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d
> zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi
> GxV
> zW+Xgk^iMPoaLhyqRlH?kt-@DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~
> z
> z?VV;!_jL_mlUw;2nHl-WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4-
> %
> zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+
> UJ
> z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2
> >D
> z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{(
> <dC
> zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i-6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2
> %
> z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7
> D~m%
> zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU
> wS<o
> z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT
> h8Q
> zoJ6nV;1DH2O4gK#e-q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO
> zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y-?g
> mho5+
> zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane-R8v5Z3OKYwF7I{995>T{A1a4Im!
> )_
> zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q
> wBco
> zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8=
> %Fv%A
> zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl
> ZU<
> zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0-}=OWCI_3x@
> 9
> zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz
> hw
> z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*)
> z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_
> z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC
> DNWo
> zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T
> !
> z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T
> z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s
> B
> zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7
> zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ>
> TQCm
> znzg-`v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a
> 0J
> zIkAk(wATQFU}lxojL8BaMgpS*sZF-`Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y
> z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e
> zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n
> >SOcM
> zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ
> %4x)R
> z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}-7DJqPTCn{7Nz>p0rZlI4~7mz
> zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|!
> g`?g
> zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO
> cr
> zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb
> Z!t
> zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3
> l8e%
> z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O
> (n
> zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O
> pc>
> zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>|
> 3uW
> zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{
> UyAaR~g
> zku^pl=~dP2`Zfc98X!v015wP-Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd
> r
> zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j
> 9
> zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so
> Gf%c@
> zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62
> 5bew
> z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG
> zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN
> ^
> zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=-Y=I$JBF{x__)9E*zZEmcCFhV9%@A
> |;C;
> z0dw89i-PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%-
> &
> z>Q=`%q>K==&;cust-ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV
> z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9
> XLis
> zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P
> 1}jc
> z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k-w~FY#E${v
> @rK
> zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp
> -fr0oM
> zeqF9y$w4I3?w-jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU
> Fr1!2
> z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~;
> mLh?
> z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj
> zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1-(p9OWCabzpEq45mFF
> oK|H
> z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+-O
> Y}tK
> zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a
> zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa
> +|BJf
> zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo-{zTWc%6}gM|{b`5lyb8()nn?Zf
> zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9
> +T
> z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u
> z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%-(}mcvBi24si~mkArbb_~r3o|KZf^n7Uy
> E
> z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{
> $e
> z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H-8)+593lMa!6m;Ey~fbc
> ;@zbu
> z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g-`zSeHh*X@cob
> g_J
> zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H-$azMlS<h3_eAd0+EVB
> ViPF*q=w
> zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS
> Tw
> zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K`
> zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;-q=U!pbpr~8VdgFOFb
> 5t^9
> zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9-6O1aqUt
> zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9
> QDz?mSX5
> z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l
> QHSl
> z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F
> C#
> znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1
> zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~
> H
> zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_
> oz
> z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K
> DGp
> zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o
> zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C#
> v9
> zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s`
> S
> zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E-y8jBnk?{Kg<Q(rP
> ?aP
> zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M
> #<y@7X
> zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P
> e
> z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf}
> Dot
> zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)-tXUE^B;?g$~2}e
> zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr-h5P};PfpB7o>k|p
> #
> zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5
> tV
> zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz-o1WNRw7&EKpp!}70%&c^b
> 4h<X*
> z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ<
> GAqMM
> zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q-5QmskD?C29B1Pr&(c@s&e+uwi>ijiC
> zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz
> 6I
> zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2
> p^z
> z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3
> z<50dfE9+W7#lo(K-r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+
> CCm
> zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7
> 2*<<s
> zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}-rVwE?y%~_n0~M
> }
> zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m
> &MC4
> zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw-XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL
> -MC
> zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY
> h39ZZ}0
> zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb!
> L
> zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v-s0rJQC*k<wIAScDz1q_$t
> 67V9
> z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M
> @O5t
> zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X
> NW
> z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3-Je!ymF9!@&)jg5>?2{8NsyKmZu
> 0v4vt
> z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6
> m~9%
> zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$
> 4
> zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls-oKS&kVw270i?>6=6@nEFRC5Es`
> ~
> zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*-LqT
> F>U
> z^KiUZAYXWSxqM(C(C=Zy<<Qa-QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r
> G
> zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=-4|~9MCtID_85v
> Yp
> zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W}
> hq
> znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<-JnxxY)Hg
> z?YX0XeW;3-48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n
> >i
> z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU<
> pvY2
> zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb%
> W=j
> zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re
> %CCQ<r
> z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1#
> &l`5
> z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2?
> |b4
> zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx
> E)m#
> zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV
> >xj
> zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o
> b|>
> zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB
> wX}s$
> z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw
> m=%XJu
> zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf
> XFK
> z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87
> omSx
> z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v
> zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#-8~w<KRe>5t8O19tX
> VdlKcX
> zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X|
> zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s
> zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza-27uAu?{)Oh
> zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1
> u
> zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll
> Tnbb(?(
> z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L
> W5JPe
> zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT
> G
> zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x||
> &@
> z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B-qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y
> Sa
> zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw
> (
> zY^$M(f1CD!4Fn3S@`Lx%c?j-wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac
> z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7-Yq$
> gRd
> z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA
> z8K_Ar&HHJwu<-S7^&Tz-z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D
> Q{Qdr
> z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz
> zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l
> h|`
> zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H
> d>
> zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+
> p8T
> zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi
> Z`#p
> z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK
> G
> zO!{{Gr-ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N
> z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E
> QFcnaYc^
> zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe-{}E&CO6a@=<Y;tXT*n
> V6
> zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC#
> 52^
> zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j(
> V7D7
> z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u-U{
> b
> z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t
> ^wM9?
> zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs
> K25^
> z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff-KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt
> zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|-EFP&Y*s>3Yf2)ZCTs)~
> gJ+
> zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{
> z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G-PPJ0
> ?Kf3
> z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o
> Qo<
> zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o
> UA=
> zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD-X_KaBxie|nwb|o$l{eH#^hvv27<
> Qn
> zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn
> D@
> zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb-jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U(
> z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ
> zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$
> %Qo3*6
> zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m
> 9{p
> z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ
> +Y
> zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl
> z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE
> 9&
> z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$
> &>8io
> zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb-OZgaoXUvS83(PBK8FLxH<rd+PcVL
> z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr
> @>iU79
> zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl<
> @
> zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth*
> NP
> z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_
> <h1r2
> z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U
> U^
> zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S
> a#=2pN
> z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T
> KI
> za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp
> z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh-`^5g98TqP_j#KdfRYD|0YNGFhOt4
> #(
> z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy%
> MXI4g
> zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc
> v
> zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA6
> 3
> z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L
> P`
> zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&-acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z
> G
> zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF
> Xihx
> zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg
> ~d{ri!Y
> zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{
> z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_
> z)
> ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi
> x|!
> z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G;
> *KA
> z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a-2i*w9Y1kWggcE
> Az
> z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz-Yc~Qsu2kWQ?O0sIz*2Ug$6lF
> 7j$V
> zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN
> bAk
> ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc
> @
> zi|8mSqO-MoaYaqA_#}w?c->nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G
> 65>`
> zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog-(Rz@ruT7zBf!)UI
> W~
> z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T
> `E
> zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^-^WD
> %
> zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf
> zTyu*%V(L_|%5}>KD68-34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy
> 2
> zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr
> ^+)zfc4
> z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#-Uk>=DjJl057_mpgxax|_Z7^eE
> *fBXa
> z5_DRyRueL^-#{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;(
> z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg
> &
> zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB
> z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&}
> h
> z32!E$+=MZ91HfdyI-J-l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$
> zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m
> @
> z7tPMl@iqfxzh@Lj$xc-Z{m@G-GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P
> nn4<
> zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX)
> q(
> zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb-qV@_uT2r9>Pn}r5o@L|E
> Y*YV
> z0`B%7x?w2<&7x>az-wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1
> m0yoPLQ
> zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y
> z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W
> mG
> zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j
> sD@ZJ
> z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28
> 9!|
> zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR*
> r7a77
> zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG-
> z-09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e
> WrXO
> zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC
> TI
> zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk-v)o<J5KbA=o=@`(r5hoYx
> Mi^
> z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6
> 6N
> z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO
> zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#-IZ<w4%qoDyYF%VJC8
> ue
> z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n-wj*c)&TK
> 0t?
> zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm-qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~
> z!
> z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56
> MWm-
> z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92
> W=k
> zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?-nog7X%sk_s<Y+v
> *t
> z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo-`!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F
> zbCM2u?}yBTP-|YUP+qtE+N-$^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8
> 3OR
> zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc|
> ej
> z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{-f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~
> Y
> z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5
> mBp
> z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K-6r
> 9Of1
> z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB
> H*
> zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX-uT&S
> z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B
> Z5=er
> zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c
> sNof`
> z=Hs3R{$%c!jWY-L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP
> `
> z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0
> bt
> zlnR+ZB=thb?WfT~!j<x<0-aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u|
> vh
> zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7;
> J|z
> z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0&
> z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N
> YbY!ry
> zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX
> zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2-<QnUzm@<!39peL;+M
> Bzl|M
> z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_
> EO7gN
> zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6
> $i
> zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX
> n{Of
> z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R
> @dv8E
> zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@
> YK
> zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We-#w4(vmfn?Vr
> u
> z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6-4f(+RJub`mui!
> Dw
> zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl-}yeK=rbpE2k2X
> KXQx
> zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&!
> 6
> zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj
> N
> z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf-y^iZn3c@baZ{@GX$an^4lQ&IToF+y
> zyt
> z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd
> z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a?
> S
> zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di-#FqXjnSNMO_Y*e|TkzT6w
> L
> z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N
> L
> zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!-s9+9*KOCp;tUhBW(x32
> DqHX
> z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+
> (
> zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y-Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w
> X
> z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq%
> K
> zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel
> z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j#
> +q&
> zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t)
> MFP
> z2e~I-K~cSXx8EG)lzE+7@73IePhx-;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL
> #F
> zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5
> ~|o
> z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f
> zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf
> zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af
> A<3
> zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw
> FM4a
> zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD
> >YZ7`
> zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd
> W<i*
> z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q-dnOip*0`sN2T
> a~yG
> zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk-(q@M
> TF-Nx
> zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{
> `
> zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra
> OZX
> zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW-kGO+`xCf>(h{Mcc
> %|2
> zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE
> zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV
> -5^$B
> zPbdR=b%2-pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L
> ?
> z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2-pNELfG(uNbq{doFM5MP7xlb)Rgq
> <
> zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N
> DpUF
> zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q
> %wi~ga
> z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW-3aN5iiL|
> `
> zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$
> z
> zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+-lbp!I4w9ZnT_6aMT~=LLkg!$R
> l#
> zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c-lmKVwD
> 3GSE9z(
> z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE
> zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw
> bk
> z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo
> a9>Y
> zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(#
> R
> z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@
> K
> zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9
> N?
> z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw
> K
> zdildOB}k13;#BI@N5b9u5s-{=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp
> z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w
> 64j
> znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>|
> sB
> zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r
> zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL-$T
> m>
> zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1
> 3i$
> z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k
> G5`&V
> zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng--HdhvEg
> EU
> z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4
> zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$-Q%t!bC
> $cv!
> z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO)
> Br-
> z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C-8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ
> 9x`@
> z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB
> Hp}
> zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r-2YOPxyr*
> b}>
> z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A
> DU;X
> zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@
> bS
> zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|-W+1H2CZtdm
> OT(s
> zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J
> zwr
> ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$?
> Zisq
> z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo
> zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp
> <
> z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~
> zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x-|BgIJfi=ju7@WZg-
> yi
> z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW
> N<+%Xc6
> z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v
> Gh
> zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep-0s*6L=4RuZ>k3UeD`pkpd=
> K6
> zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8
> a1HxFs
> zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY
> yJ6
> z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR*
> &
> z-=>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk
> f
> z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJG
> f
> z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C-m=TI!deWV<@u@B+g9zOd!H<h7
> 6
> zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H-!7w?@Nm!4fF|H&)>RG9@xH#
> VA%Kj
> zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M
> 3@
> zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x
> zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL
> m2
> z`KG6~&Y4#$->{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO
> KIXO
> z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L
> NUGvT
> z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr|
> %C
> z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S
> $~q
> zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o-IzYg)#61qGsUJ
> @X>V
> z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY-L2ha3l(|O
> P
> zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=-neefemATL|%SeTj
> 7KM
> zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc
> e
> zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u
> L7
> z!mV(@!YY)C1EI1tx4-6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x
> $AP
> zwpSBL-W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu
> yMC6_
> zOF$m<BQ-2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI<
> T&4!
> z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~-^iTXueIx8byvHT>hu$|i_OeooSft
> n
> z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV?
> zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1
> zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%-W88*^zKTEx>j2)~V
> 9UTQ`*
> zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V--kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL
> 57
> ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V
> z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL)
> $Zo2
> za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I
> e~kMH
> zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?!
> %!FY6
> zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K-s2WN^ui3C{($wPhZa^$pzWR^Hl
> 3F
> zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw
> 4<G
> ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt-M7|}+UXRU7h?~TB=)5(t0^!(
> %P
> z-F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc
> )h3ea
> z6-G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W
> Nvtc
> z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O
> B-A
> zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV
> vU`(H
> zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW
> E37a#
> zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o-gou2?WYbb69sCMC}^w$$jzUo!Y&
> !
> zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm
> z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z
> #
> zq-Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV
> L
> zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;|
> z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO(
> 9zDJE
> z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p
> zKS?@9gC>?~`QG~vYx33_7id<K`zM2p-ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I
> z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6-fqr2rZ=VYP@rHCOq9pf8B0xw@Y0
> Q|UG
> zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY
> zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#-
> G
> zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X!
> we
> zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)-H!*m0eZZ!QVFvyXV^=j}!Z?!plq
> zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h
> 3
> zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43
> 0oJ
> zI(_U{Z0qELvqlo1zMy(-joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq
> I+
> z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+
> VXJD)
> z-q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV
> YY0B
> zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC!
> P|
> z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r-*H*VR4`LaS<<C1W7hg&
> ~pO+K-
> zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM*
> ANN
> zUz%6;oPCB&&k^}WT*2fbT-rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)(
> t{
> zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z
> 4P
> z{MfuNHeOI7d~NQbki>Wa*r?}Ta-}c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw
> nR7
> zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&-v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0`
> %z
> zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y
> O|w1&
> zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih-2{<n)!I+;AHbRo*RPPJ<gUm%2
> u
> za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP
> d~+Gh
> z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj-
> z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?-BXUNalABrN}l?3DDjuoNkTNq%YT7
> 3F~h
> zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV-S%|a7B=tS!rdlDQnw_~vR
> NG+
> z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI
> TI9~
> z80}SbU~>FO|9I4K$=-QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@
> JW;6
> zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=-TSOTON|2ebg0xls`JM}%@O`g
> K
> zmH+=v*cCg)>)6&*G74T9ntba~IB-18Gfz;WMB^neWL%=F6kixs3>vAmMHr<#
> a{F%5
> zSV4%6rVjJ{9oXWh7>e;x_5=7-ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@
> Cxn#6
> zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4
> z!jPQ@A+Wb%GhI-D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av
> QoVl
> zpg?U5sxJ^-s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU
> u2u
> zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH
> Y16t
> zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l-Fr_U^mpQywF
> 7_%T
> z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a
> mi%
> z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j#
> @z5(
> ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi-XyKLb
> hKa
> zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p
> zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt
> i-
> zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K
> 9fOo`p
> zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs-ui){uM_Y;pwOERO_
> ?nhh
> zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp
> !5R#S
> z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q-UO22MYfNY
> *&sB
> zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1
> zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN
> 1K
> zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt
> zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr
> |TU+
> zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@}
> qgr0T7w
> z<XUd9YdH`MV%gjTsUwYem-CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2#
> 7kIj!)
> zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D
> z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx<
> D`^2
> z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0
> O
> zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w
> )9*
> z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz-xEr*zAK9
> <N?Y
> z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F
> &Xs
> z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx
> qkyHve
> z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp
> E(bW+
> zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II
> z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a
> z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K
> 127i
> zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe
> WR1yd=
> zOy+GS3N+k-;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X
> 8KHw
> zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM
> wuHG
> z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T
> NTye@
> zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+-8Mp5YQRWhyS@`gIr&htF@U
> =BD#r6X7
> zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp
> i=M9v
> zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9
> f4
> zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f-C*U
> }T
> z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2
> T=@i
> zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_
> &ip
> z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED
> M
> zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F
> Ya5e
> zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A?
> N>
> zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n-
> -MxQ
> zG1h%OC9O9yC%If5t*4BIdz)$gh>-Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q
> MQ
> zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV
> SbVYbX
> zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`%
> WvX
> zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS
> zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d-XA~5}VSN6cplAA%P=_p4Y
> qn~a
> zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q%
> 9};T
> zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w#
> X`^h
> zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_}
> Ln=
> zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw-J{yCA}t$O?2Gbro_S0%@6bE|NUO7
> 3JAX4o
> zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM-0
> <2
> zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT
> D9y$
> zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4-pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ
> zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW-8FRu~9(wk+ock12GT_
> Ja
> zM^?ezBrqptKLHwLt1X-1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0
> #5
> zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82
> +`
> zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF-GVJ3Or!j$S_H;Jw
> z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!-_c(_oR
> c|
> zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu
> ma=
> zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW
> Kn#~-
> zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO
> XKo0`
> zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f&
> zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v-Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3;
> (
> zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y-BrsYiU;W<x<Ea;>dpU
> @
> zmR>$-PfosIWz(r5(5<wxPbjmo;#-XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE
> zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N-z3e*X4)s#1kO^g=a
> {~c
> zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl
> z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84}
> qZ
> zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1
> vI2
> zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP
> |K
> zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@
> +3pvf
> zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc
> 7
> zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l
> WtAe
> z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$
> w2^;3
> z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7(
> zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844
> z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP
> oM
> zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+
> zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j>
> aq
> zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`;
> L2G
> zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu-hUH$wa
> RbE
> z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6
> mTGS
> z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz
> w=
> z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID;
> @
> zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb-Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix
> z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F-?Au{0G5tdd)TPX1hakJ3TvR90rM<^
> Y
> z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa
> @~k)f
> zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m
> L4-Kc
> zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!-_hOdW0;F-
> OTOp
> zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!=
> X+}$
> zFuvZ~++1ipISzO)2)RT}D;-aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7
> =
> z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7
> GW
> zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU
> ePA~
> z_hxdvS8-a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E
> z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e
> zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(-
> C#Ha|I
> z=C2Ea@CE*LYY3?FwL2-o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn
> be
> z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A
> W=XSe-
> zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns
> zM-{9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs
> 456yTg
> z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U
> XC
> z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_-=gt@_z#8g{&FBl60M
> 8q
> z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl
> <
> z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+
> <`F
> zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v|
> da*
> zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv?
> e
> zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM
> P?$BB
> zOd-J<xYW8H1RRa|E>kVw-`TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da
> kHuGSr
> zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z)
> P
> z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r#
> z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl
> bN}<
> zqLB8`-^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX
> u{1
> zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ
> zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq
> zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX
> )z(Tp
> z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD-jHBwcr%2
> 0bUM~
> zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm
> n
> z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f-bCjEDTbbkioa3
> AvU
> zTgs{woXY3O-Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw
> FPeX
> zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh;
> z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G
> 86v
> zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu
> JvQk4
> zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An
> t>wSc
> zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af-Xuf0lKfuTpKFA04
> 1
> zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I;
> hr
> z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+
> wHXl
> zz&1Drp|7~EN?!zH5pKw!JvbXK-ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B
> C!KO
> z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug
> B$R
> zx6k>}-^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg
> zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD
> ;>-$c
> zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM}
> zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO
> P{<K
> zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB
> G7
> zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln
> z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7-kO_`Up!D&o+Zeo37N~wiT
> 81j
> zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e-+C(B!Y<Aj46`65i%71cYGD{
> znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;-TI~;
> EW
> zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n}
> xK
> z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I
> z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd
> nlbj
> zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05
> z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j-
> Y
> zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^
> 7
> zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0-O=A5+6B7bE
> #7
> zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ
> !$pK^xF
> z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn>
> z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf
> ma;W
> zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i
> xTr
> zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X}
> ms
> z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D-^e94<`cGBaYaA!4zd=KEsJn
> eJ
> zd%}Zl026m#*+6#l9yFz!8d8<-XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i
> }
> zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+
> zD#6R=4Z52d(S5iva$jQAz=xFyN-q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~
> (
> zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe
> z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG-UmfNcjAaL
> Epl$S
> z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7
> m#Z
> z1f>)aDLDPf#(_xvLI-F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g
> XhRr
> zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f
> zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_
> <Ne~e
> zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S
> znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p
> 2%fV|*A
> zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F
> +?=
> zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D
> 0
> zIugZZoN&hDJvgzTn^^1-d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X
> uR
> zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y
> wh4&L
> zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9
> v
> z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y?
> @d>R
> z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO-x&lC0KfJO|C8kgnlMCC`W~^izTp?
> z
> zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$
> )4
> z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj
> NU_
> zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L
> wJy
> z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o-D+M
> C?
> zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R
> @B3p
> zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p;
> pe#
> z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg
> Gu
> z<x;1&YdE7!dLGg3LR#-vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H
> xN>
> z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45%
> zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh}
> R
> zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!;
> z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`-<Skpc
> zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI(
> zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck>
> zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1=
> O7
> zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ
> Q
> z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$
> &S(O@
> za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{-gM3Y^a
> D&p
> zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C
> 9
> zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw
> R
> z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA
> Ms?
> zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l;
> EF=S
> zx7~>-e--gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi
> fo
> zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d
> P
> z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx
> RVQs
> z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e-eJ
> (bu7W
> z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY
> jt9
> zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW
> zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M
> M>h@k1
> zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^
> zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7
> z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2-Z~r3V
> 4w4#M}^k
> z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7-#MPr;?r3h8
> kN
> zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF
> ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p
> 4&oPZ
> zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V
> W1
> zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?*
> 5gM
> z-dO<=pUw9Hu!6VH-$5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^
> P$
> zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D?
> W@}5
> zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8
> _Vr
> zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G
> Uu
> zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M%
> 7_V&j
> zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ`
> z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG
> z--mu$ZE#I*Q8<#GJ~-LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts
> 5J#$S
> zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`-h@bk9
> O3s
> zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S-y+h<
> ?#Y
> zk-Qk=flDo-RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu
> z+C9W1IPvuo^Z|-GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw
> VT0
> zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy-t?t~fVXzqFG>P(y1EoKn
> x2hb
> z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b|
> +mG
> zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D
> !#34
> z-*FDsO~mox-k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93-
> 5v$t
> zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO
> CE
> zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z(Y
> z)aDR~xD1dzXmhus5Q??fihY8I-?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1
> QMq
> zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@
> H~~
> zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT-h%26Z
> X#
> z7~{-@v;G{8Lxo0@cHdz4T{-P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur
> +Z
> zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6-Xr9n
> R6
> zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf
> w^
> zZ3$IK{RGVZe9g9-KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul
> qu_{W
> zTj#6IYv<7-Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7
> AD
> z{ZzN7#^JAPYu-X7Y-03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{
> uPf9
> zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f
> 4A>iW
> zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d
> &(
> zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l
> #
> zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_
> _~%;
> zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki
> M#a
> zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D
> vAn@
> zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0
> zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l
> zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~
> zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_-EP9=wZkWSqwPf`a`R&_k
> |@1@
> zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj((
> |{)
> z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$-(zx$a
> ^1S
> zX!<JR+joeIbZEYtIBvgBnl#LV4-NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g
> |
> z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp
> zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b
> z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg%
> z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz-khs!4b#@5QjP>U9%zLiUFG
> ~av?
> zeUJ9-Dv~3N$B!appHtL@3-IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q
> 46kGa
> zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y
> E
> zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm
> ppAB<
> zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+)
> 7
> z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v
> bV
> zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT-57V;K;+syy?R+C30w{q70#TZ1
> (Ev
> zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V
> @y@+N~R
> zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I
> zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k<
> >s
> z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ
> G+U
> zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U
> S
> zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q
> HH0-&U
> zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn
> znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt
> zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9
> _?krc
> zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF%
> zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(|
> z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW
> p_`g?
> zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^
> zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof}
> z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^--
> zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x
> `m
> z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA-cq+Wq%`jv
> zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i-+%|*Ny&
> A
> z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA
> &6k{Fd
> zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5-JAQI7W$
> CZ<;`
> zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S
> OsN
> zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj
> mz-w
> z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR
> 7~
> z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3
> D{
> zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S
> UN
> zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs
> mu
> zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m;
> Nu2W
> z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk
> V!}}
> zz+g-u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y
> z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC-xL=Y(
> GRx
> zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q
> zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii
> zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM
> XGy
> zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc
> zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q
> VM
> z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU
> zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E;
> iUxRR
> zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v
> zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s
> zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<-rUD)H9&S
> f@E
> zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn
> >#iM
> zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5
> wX%
> zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@
> zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP
> z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298}
> 0gs
> zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM-
> rJhB%
> z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k
> zPBTLqcmk>G0PwmJ^W#xC-O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6
> 7AvC
> zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=;
> ?!
> zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*%
> J?t7L
> zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D
> K(~
> zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL
> zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD
> z*w1fD++$^@e$D7^UGJgf-rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3
> <D
> z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p-@)*^
> N(5Ei!
> z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$-P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu
> ~
> z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP-wj@j!4#6iMbDW)MruAkHCb1Nqxw
> NM{
> z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb;
> P_l#tb4g
> z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P
> zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57-^*tCzH+>d*z@3AV|%h%!1NOg+zH
> >^N55
> zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h
> E5}(1<
> zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t
> @BwZ
> zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t
> ag
> z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ
> zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA-S)#DE
> zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe-+OTZJW>x%V
> y
> z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz!
> Q?
> zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW
> VJ
> zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT
> @L_3c
> zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq
> w?L
> zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw-G<
> ~n&
> zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC
> {22
> zX-I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4
> dD%
> z<YEj;4*V+0;|M-rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes
> #~
> zqZrF<mFWvzkmFGC{3-LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d
> G1&
> z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v;
> ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA
> z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+
> z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd
> ppY;|*f
> zdVc@~A9~wr5$E1you*)8n4i?F--}{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l&
> wBh
> zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o
> wnE
> zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54
> +~m
> ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R
> Z>
> z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z-WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B&
> MMf
> z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)|2
> aiA
> zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8
> ~=75zos
> z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g-QOrn
> %{
> zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$
> Wvx
> zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P
> Q5^
> zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q
> AJ(0a~#
> zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D
> O*
> z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN
> #0-*
> z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD
> NuPv
> z8A&gM+yWoI3+p-Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm
> Rd
> z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki
> No!Ys
> zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S(
> B7X}h
> zVR;Et%eD@V5-g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3
> #N
> zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx
> z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}-8k0{FELICbyZM7w
> lN
> zHgWxV%B~vg3Kg%{-@*F@zI^eKA{-JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb
> iKo8
> z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV
> hw$
> z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz
> =
> zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe
> Mux8;
> z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*;
> =YK
> zjl$=}dcQ-TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr
> zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj
> c
> z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY
> 3VqP
> ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^
> b4_
> zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k
> ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC
> 6Q_?
> zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{
> zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;-zV}=Ffb;y0
> z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV
> 9?w%
> zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$
> `2Z9
> z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK
> MQo
> zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$
> #|)V;RX
> zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@
> Ox5H
> z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD-VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{
> #
> ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv
> <E={9
> zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua
> {h
> z1c&pk*C&s-u!f*^mD<d?d91-{0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{
> 71|@f
> zqyCdPYA>=Yf_ZfXdKIQ7K-BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS=
> *8
> zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz--=+yEpn0V;dyO#f3
> quY*
> z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN
> n#x
> zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7)
> z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp->DBbJFmh
> ~
> zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc
> 359
> z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP
> z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42
> R
> z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR-
> }t
> zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc
> zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E-c!f2kMR<>)RwV=hmWjbJxmB
> OGSp>
> z=zoS%q90`C_3r-1I|(vxy$L|<-~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53#
> E3
> zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o
> z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm-eR5re6n!d6@_6hyx(
> I78k
> zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY
> Wssf9!
> zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ
> zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P-
> %+f<
> zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G`
> zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd
> j+el
> zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G%
> >t
> zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@%
> Il^r=
> zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg
> 6d?0S
> zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c>
> }u
> zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh
> +5
> ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V
> bfpO
> zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W-!~C&zci
> |?
> z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT
> h?j
> zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4
> 8K^U
> z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+
> 9a
> zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM-
> Wn
> z9YL6MHz1*R`Ebg>i(85{!WP-zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M
> $<
> z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<?
> zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk
> zjcnO0FC<-zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP
> c8Q1
> z>8<aHYtJ``M!kq=@76^J=2^>e*+-?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS
> z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb-
> KY
> zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@)
> {}ye
> zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H
> X$b5|#j
> zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee-d!ko~1?$I;0XQ0Lcy}V_T
> M9HH
> zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M-xe{E>sl9(>CA<_JNmMi
> xd
> zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP-t~(*7E<kqy26Hww<ma171sv
> !t#Q
> z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X-XGl*%Q0ElH2aXP)|ASi9~aI8
> )Vn
> zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s
> zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;-*c4|rL<x*=v#r8
> zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$
> AaI
> zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M
> -hX
> z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x
> B
> zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x
> kdv8
> zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH
> Z
> zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm
> z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv
> znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g-dTo#iWkSVwCW1XNNk>DTg
> aD;g
> zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF
> WS_L$5
> zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk-&zLAxDgQMl#h~
> l)AM;
> z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK
> zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm-$hEIpj?<LiYD}ov|o=<+m77@%`dhAH~
> ua
> zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5
> zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf
> }$y^xf
> z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y
> z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk-N;TT
> N~tt
> zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o
> zQ-15yS^!}n-@U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M
> Y69Y
> ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A-Rih9xWf6KdR0%$1u!qOps1C2Q#
> ANP
> z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u!
> Dqgb3Ca
> zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86-gbBvpzX
> R
> z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5
> T
> z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj-hIrr3a)n*V>r6m=eJo=M3#L3_
> &Y
> zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7
> z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^
> =n
> zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ
> IJm
> z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9
> z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz
> g5f7(M
> zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG-kU
> G*
> zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no
> Oj
> zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)-2TC_XY^XyU+7`Q)it$=yI_HeO$|
> zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}-n<&rw6V{rKB|$Og
> GoBpL
> zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf-;e_A#;c07yl@emICdlfx6?S
> zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9-W
> Pr4Do
> zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x-OHJh=>^
> %$z
> zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf
> R=j_i)
> zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb->
> N#*
> zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_
> zLs>gSMg&%IxgXVsk+G<1aLQyI;+-(x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p
> 4d
> z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a
> O?%3UXP
> zmxkemLOe-bD%O81OOdPv56yFNIJswr)-r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR
> n
> zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W
> 5H`Q
> zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=)
> @EPJJ
> z!!F00iIqj9<FImx<-TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu
> Z
> zA@6GBn_*`<fZu;fKyYcdsVz-LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb
> JP
> zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD
> z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o
> &q
> zxj*LqEY-ZnACrceN-~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573
> zN&n5k9DfdGDn-n*utQW4V{X-IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP
> Mq2Z
> zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4-Y(zEt0m3<zZQzZOBUz
> lhe
> z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i
> !
> zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v=
> 5E
> zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2
> U3cy
> zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL%
> @Pb
> zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W
> T~0Y
> zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f
> 3EE
> z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt<
> {8Z-8
> zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE
> m16
> z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4
> LVb1o
> z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@
> x0z
> z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn
> ~4&d
> zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu
> G$}Tz
> z#IEmCFn7df^>D7-H--ADnz)!4ImOJ-Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@
> =?WW
> zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I-)fwRt3qD8qt(
> {
> z<P<KF=}PJ1#r#`jS-C-BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a
> (X
> zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB-$@AJqDd(YoB@ZYfK6vP54O
> =^o2
> z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN
> g
> zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(;
> P
> zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD
> mu
> z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF
> {3
> zwPHdUsL_Emi-|sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx
> tn
> zbrc)1<0dX~X#twYtTp`&I-K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ
> n
> zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5
> +#Xc
> zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%-xVei
> qO1Hf
> z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU
> <cW
> zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c-
> zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?-up`F97
> _
> zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e
> PVQj
> z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT
> z4)s@IGNTe?4-@J{iz-J0sXQl-t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P
> U}
> zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}&
> jB
> zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9
> XPvK
> z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck
> N
> zH}9#C6|qJ(-~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb
> 5c
> zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx
> C
> z(-KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr
> |
> zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS
> n)edp
> zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh
> 94r
> z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk
> Q;
> zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS
> z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B!
> zLKgK@^uHSZLNEF1>n3-)R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP
> T*O
> z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL?
> zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB>
> 4f|!
> zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF-f1_RXCi@Ib*0
> z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4
> 8XtM
> z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi
> Vn
> zP5ZAFYbCS1g7-`&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G
> uEt
> zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N
> Vpdll
> z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a-3`@t)z}?8R=?u@$Rw&yc>*^x
> zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{
> %xn
> z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0
> zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5
> B
> zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm
> 5jhv7qJ6
> zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs
> G&n
> zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc
> X7Yw
> zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*-s7
> b^
> zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm
> zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR-qjhh
> O
> zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)|
> CS
> z^GD&-H%jsm7i~c(IDGo_-?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y
> w
> zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h-%XTOuIK%jeRlC4YOaKdYsipAm+
> WrxJ
> z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_
> emtz|
> zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alVq
> N6
> zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ
> 9VH
> zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td
> R
> zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm-z5jm=aFjj$na3>$mvN|33HD3iFuOn0
> va3
> z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k
> zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic
> ;
> zO)ScHYd^W4>p1IZF-rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I
> nuw
> zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq
> ~p!H
> zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR
> z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH
> @xAy1o
> ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;-FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq
> z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb-d5Kj>373=4;|gla3^9<xGWqY!YN
> zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF
> ^
> z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe
> z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)%
> 6TeU
> zDai3Q)sDP}fd8!F4@GgYGt3O#w-T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=&
> !#
> zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ
> zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A>
> JLS
> zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B
> ^2@xF
> zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo-1(
> TU>k
> zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q-I>Wsn^_=%oN0?9m<2++S;$}<NQ
> !2w
> z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y
> @4wr+
> z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW
> igCND
> zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G
> f
> zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM
> +HRe
> zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7>
> za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!-N|
> -
> z;QcJ-_4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2
> Vq6r2
> zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y(
> z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X
> ^
> zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL
> z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o
> @ew
> zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij%
> 2fn_q4
> zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`>
> =!
> z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw%
> <b
> zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d
> {;+cG)
> zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z-9KqzX4ywpKgSlL&Lplu
> #f5K
> zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN
> Be
> zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb
> `1J
> zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6
> h9#
> z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW
> Ts
> z@juu7-1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS
> pa}
> z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;-DANP
> e-
> zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O-5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5
> 6
> z4%Obc4bQ}m#H`ZWui1dCf-8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q
> a
> zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K>
> Mz
> z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4-gIH0R$|yhL0%iyEWP)
> -dMFq
> zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4;
> zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(-#
> w5
> zSQe21-iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH
> zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=-
> h3
> z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#-u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6
> zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V
> B
> z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii
> zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C-NcZPpT3FT+YGkGFM
> 6L6
> zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3>
> 49;t
> z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@
> ZoU
> z1o^bK^-i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e
> <06
> zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23
> |;
> zI-8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0
> p%hX
> z-z&;-5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{
> O2
> zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(*
> znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf
> zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL
> mu
> zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt-)j9cW`J=^32#Q
> _0v=
> zYuS>-!$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4
> T3
> z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d-y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%(
> U
> z6;SpLK}$lNH+Qlh-cKR-YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>&
> oV-UQQh
> zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U(
> c{
> zfIZlR!@-s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld*
> zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e<
> WpJJ
> z-`$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ
> N;@<uUxT
> z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@-auQ<`tj
> RFOs
> z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A
> m
> zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A
> G
> zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB
> e+D$Sx
> zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-|
> z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7<
> K
> zTOHkDcgdOyfsEiOu%WtEi(>#Z-~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY
> u|
> z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG-KacrZ
> _
> zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG>
> N9F
> zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U-w88FH|Vp0NA28vf|sjS
> i!
> zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt-fK$0VNHs&Mk>^C1D
> zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce
> z$GM4
> zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV?
> ?+@e
> zg`wK!-l8aDa_m35OpOA{bq~|+%F-ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ
> {
> zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY
> zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE
> f!T<
> z2ci!iV-wM?Bu7s^Huqb-4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C
> Ct6d4
> z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p;
> %j)
> z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu
> zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%-(2Z`Wl
> @e
> zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1
> Smv
> z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE
> TIA
> zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH-#T
> #5p
> z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV
> z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS-W4+WUsh43&>4RG*{QQ#GI!w
> phN<ut
> z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O!
> 8
> z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC
> li
> zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF
> no2|(R
> zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS
> 4D;
> zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R-Jpx~r9!pm?4kz;k|ao%zB@5Hbe
> <
> z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV
> $~Mw0
> zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM-j_UaA
> x<g;
> zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu-o$d)MnXpluW?a_({zl
> g
> zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^
> Nsh
> zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^
> H>
> z@#^-Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5#
> zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd-Ge_d>@
> =&
> zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK<
> zN_8RoATaW}d{5!m3i1gyT+$O()xZN-q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n
> z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8`
> AC$53
> zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d
> 7^x3lQL
> zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t
> ^
> zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n-;m<n!p%lxe5r|
> zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD)
> S*
> zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8-9ip&dZ
> 5@B
> z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja
> zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D
> @Lj
> zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_`
> ?(Q=eq
> zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su
> !
> zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n`
> lly-i
> z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77-?_
> D
> zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=-#ZF|U1if%4r0!Fqa4AKSYGr=Bp4
> wS;j
> zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f
> B
> zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w
> SvXa
> zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg
> @KJ
> zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL`
> =`
> z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q-|Gt8<U$^Rmw`&o%H;FN+S+(N
> H@-}E
> z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx
> qT
> z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ&
> z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7
> v#qf
> z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp*
> M&
> z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf
> zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!%
> R0i
> z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C
> m*DkC
> zHs9kcukmSQnY-`;FsIMBQNgVP-Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd
> 6
> zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU
> 7F@}
> zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI-W354EXdcSk^K;5aK
> zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)-a48PghrZ+3AO}YN
> &bdTo
> ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk
> ce
> zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c;
> zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO-KB7MVoi
> X`~8>
> z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E
> h
> z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe-jybQSioRnO
> 6
> zpm;JeMEQciVCPbow+)K59-z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs
> X$9
> zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps
> 19
> z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM-V3W7dJ0WrB4
> !!+0k
> z;zYZk1x)Y5=+Q4I`1dZe_-J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~
> h
> zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY
> ^|^o
> zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY
> w
> z8&-yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_
> Pl}l
> zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn-cjsU7u?E8Rr%=Go&yh&47sj4
> @fk~gw
> zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz;
> Vn
> z-7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH-
> #bB
> zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W-7Me#XrQ^Tzt>kfFu8R(s
> Yw
> zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi
> G
> z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=|
> B
> zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU-`l%kXo|H)KHVD6KW
> h*Rz
> zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx=
> &<
> zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT
> zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr
> 1>
> ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx-gL}d<c_Mn^@%_FE+g
> ?M
> zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB
> m<8{
> zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB
> rHu
> zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB-gw(`|azE*a<_S1weMZAOo%w(L
> )Kl
> z-dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_
> 3&$$E$
> z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3-B{
> GV
> zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s
> z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d
> N
> zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f
> E#
> ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l
> 27AMD
> z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql
> amYM
> zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE?
> zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7
> W<MJ
> z%-SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH
> R8=T
> z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo-@a)b+Ml`1F<g{$T*e1di)$*fQ5m
> |)PQDO
> ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8>
> ;g4
> zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF
> zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA-k%PLdC*dz
> w1?
> z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c<
> zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G-H!u*oMbA8
> 4$
> zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q|
> z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd
> WSp
> z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK
> !+9
> zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq%
> zw_MRqd{G)1`B`l*-mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg
> z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~
> zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA
> z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6-9?bOShFo2W$of{J{
> gHl
> zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y
> $TzS4WWp
> z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_}
> zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7#
> T9bz
> zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r;
> 7VlOw;
> z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g;
> zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@
> ~Q`G
> zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s-2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v
> z8QwfoitD*@-5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j
> ~x
> zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o
> }${B{GLO@
> z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO
> >
> zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@(
> W
> z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r#
> JmFX
> zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0
> TYK
> z-`2+H1Yr#7j9>-Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M
> $i
> zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@}
> 8Q-
> zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB
> {d;Z$
> z>%q~GMLth%$)7kc<>-;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX
> =3xm
> zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2
> eba=c
> zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn
> vLvp4*
> zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mMJ
> XCoBHnW
> zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1
> zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f
> zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO-2
> |a}K?r
> zFo(mo@$6w!RCO;!k{m2{z-_`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C
> _9
> ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u
> G8
> z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o|
> p
> z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK
> pU
> zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G
> z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`-GBdrly&WQ1*?kDL@
> pG<V!
> zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3-JyC<keh(WCoDi(@n0xqm`@&*0R>;
> SVa
> zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?-i$S
> )
> z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj
> z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#-5>lJ2jXZ|?d~C=
> n*V
> zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR
> 6na4
> zw-T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L
> i
> zajQH#9E-re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L
> 675^
> zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T-5)vkqIFntDZMA1VMOHjx#|#
> gp
> z<=jzFhYH`U9&O8-fDan`-Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ
> s9
> z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+
> B<
> zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(-AS
> z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W-JCA@y|<k2?s=otq
> kXs
> zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf%
> 6
> ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg
> V>
> z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}-
> zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP
> e+{
> zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b-LbUdRv*H4Cj>iO=b6AU_W
> kt_g
> zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><}
> &(L
> ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~
> zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCAI
> uWDE
> z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy
> WSRlcK
> zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL
> =h8r
> z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L
> M^W
> z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7?
> _YY
> zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf(
> zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W
> u$Jn
> zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j
> Uyi#
> z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1-7wk8y&7D+XUbG
> qc
> zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{
> B?
> z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR-`ynB}GDY7)z8WdiaOz1?
> $
> z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2
> w_fKH^bO
> zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C>
> r
> z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Yb
> }g
> zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi
> zXl`9?-$MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29
> @(BH
> zQPs%IT;9S({?mP*=Qnc|D5J-|w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf=
> c
> zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4-F^%90(P&<beWqvDXsg0?i
> WV^Yr
> zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz
> m*iO
> z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv-0T#hDV!d
> ^^pp
> zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{
> zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I;
> zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu
> G
> zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da-R)wUYvP#%R8D{%W4M3=p@E&YpC5Y
> <^3Ym
> ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%-wXl_NyC`0qB
> zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr-wIc*7P
> U)!KE
> z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek-a?2dg6PVM6GVX~3`oj
> %%M;
> z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je
> zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i
> z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`>
> g
> zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T-2DeQ#fI
> 0ra
> zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90%
> U2ISK
> z7k~rD4m&7xFAX&{$U-)37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA
> m&$g3
> z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n
> z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;-d#*zW#Tye9hV)P&G*REZ2he+xK461i
> S
> zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+-@izT8*fdO5W<a
> <>h=
> zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O-U`a;Yy~M(7
> z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0-*)&Q!XszxM?Zk
> c
> zJxsx>FboFMSO_UsBIRuzb;YY9gvg>-Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s
> z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB
> ^
> z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y
> mQ9
> z7-54~(UFH?f-J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V
> zmVbN(^|1#(h+-lD+oK-PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W
> b
> zObewKL-P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E
> ~AL
> zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ
> mE}
> zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS
> Ar
> zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{
> eM#TotF
> zf2^1WUw|=jGZ{M_KC6YOEM6I@-R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ>
> -!8~
> zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G
> w
> z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ
> vh0
> z2yd+qIez;p={X=o?0-^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F
> 9F
> zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi-7AsygbO%g|<oo|
> F
> zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7
> mcGpsI
> zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z
> eLf}n
> z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_
> V58p
> z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE;
> _G
> zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?-MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC
> uL|
> zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y
> 7
> z*L9AUT{ijtMS0dcKOCKHpr-+xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR
> p+
> zM}!>G-HW_0p+C0|#wR#aRBk!spJCi-eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS
> Q!<O&
> zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r-sKrwU
> sCLRyE
> z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1
> shL
> zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U
> e@
> zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r
> za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp`
> zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4
> +q
> zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D-B$kndG=Y6ir}mBr@$2Y+D1hg2`
> HSFo?UV4
> zWpi&inW)}pTDjzcWI2#9hs__rze4CYs-U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73
> t+H6
> z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W
> 0@Pm_Y
> zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j)
> zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK
> zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3
> z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P
> z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH
> z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t
> $g7Mc
> z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw
> g4XT
> zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2-&x>7Mi3KPo##3Vi5A!D
> ~zVd
> zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ
> )g}U
> zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo
> aKg
> zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y-AD^;!g
> x|
> z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3
> R
> zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V-O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v
> OZ
> z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz-
> DH
> z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52
> m?
> zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET-fIoOZ<f~u
> zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol-KEmeMx`wo+msu_i=!gCUc5
> aAFo
> zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o-UlMiBIpwFoxSL(w@3J7A9556*;P>na
> q(Up`
> z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7
> zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr
> zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5
> k7
> zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i
> ?0^U
> zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C
> zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq
> $
> zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm`
> `jz`
> zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr
> T%2I
> zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69-HYb
> z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9
> zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh*
> !tsx
> zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C
> z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD
> &
> zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X
> @*1fT
> zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr-G6WS1r9|13yh@
> Y{v
> zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6-{$zk^x|sZJl
> O+j
> zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x
> LE}S
> zE-yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9`
> UBK8
> zQ#_-WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s
> HLzP7
> zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om*
> TH
> zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&=
> w*FLg
> zsI<EKP=R6SqF-IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D
> k*l
> z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt
> gvZ`h
> zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW?
> MMr
> zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j%
> zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u-_fVYHP%QJS6G+)Vr9%12
> >J
> z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw
> Mk8(V
> zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)-?sMK$L?>Ng)`3v
> `R
> z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl
> NJlM
> zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi-f1#Bw(VP<qeg{%cT1IJ97@nLSx
> z_X-ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4
> 5
> zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4-kyiVyjuy47$
> @|
> z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk
> q6<X@
> znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu-b=1;<A1a(HF7
> `i
> z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y-<
> @
> zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb-%NnQFS!>!e+)H<J7
> %
> z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq
> )L
> zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh-@%MC4@d
> 0h&s<FN
> zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V-_M01I|
> m8wTMI
> zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld
> (#T`
> zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK-OFjWJG?jVvSoZ_a6
> jbw
> zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa
> qQ
> z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX-B8hJF!+PDU)2Ng~^@q8b
> e+U
> zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk
> zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo
> zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L
> cp
> zKSVWp#RY$Lhkns{H6-Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x
> d}
> zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f
> zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*-i8
> r$$4
> zZOqr7#;sW-rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_;
> 4Fzt
> zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob-K5PWDTzJUeq*If}X<4`_2c(`X*0
> z6;L!+h$=hX6x?t-Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY
> <t#vw;
> z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG
> zsy
> z&r3>eq@*BKMfN&W*>mt#-zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d
> 4t+{
> zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf
> is
> ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U;
> ?2
> zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv
> *TAdi
> zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS
> zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I
> zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l
> hv
> z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK
> z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K
> B(|Tz
> z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+
> XbfG
> zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^-;pwarlq8+@E8O5*D1MF
> F1&w
> zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud
> zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA
> ^H
> z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv
> jX2
> RBat2OV|2<CTVmi8`9DHIo&o>>
>
> literal 0
> HcmV?d00001
>
> diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py
> b/BaseTools/Source/Python/FMMT/PI/Common.py
> new file mode 100644
> index 000000000000..efab874ee08b
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/Common.py
> @@ -0,0 +1,81 @@
> +## @file
> +# This file is used to define the common C struct and functions.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from ctypes import *
> +import uuid
> +
> +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
> +# EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
> +# EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
> +# EFI_FFS_VOLUME_TOP_FILE_GUID =
> uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
> +
> +EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
> +EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
> +EFI_SYSTEM_NVDATA_FV_GUID =
> uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
> +EFI_SYSTEM_NVDATA_FV_GUID_BYTE =
> b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
> +EFI_FFS_VOLUME_TOP_FILE_GUID =
> uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
> +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE =
> b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
> +ZEROVECTOR_BYTE =
> b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
> +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
> +FVH_SIGNATURE = b'_FVH'
> +
> +class GUID(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Guid1', c_uint32),
> + ('Guid2', c_uint16),
> + ('Guid3', c_uint16),
> + ('Guid4', ARRAY(c_uint8, 8)),
> + ]
> +
> + def from_list(self, listformat: list) -> None:
> + self.Guid1 = listformat[0]
> + self.Guid2 = listformat[1]
> + self.Guid3 = listformat[2]
> + for i in range(8):
> + self.Guid4[i] = listformat[i+3]
> +
> + def __cmp__(self, otherguid) -> bool:
> + if not isinstance(otherguid, GUID):
> + return 'Input is not the GUID instance!'
> + rt = False
> + if self.Guid1 == otherguid.Guid1 and self.Guid2 ==
otherguid.Guid2
> and self.Guid3 == otherguid.Guid3:
> + rt = True
> + for i in range(8):
> + rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
> + return rt
> +
> +def ModifyGuidFormat(target_guid: str) -> GUID:
> + target_guid = target_guid.replace('-', '')
> + target_list = []
> + start = [0,8,12,16,18,20,22,24,26,28,30]
> + end = [8,12,16,18,20,22,24,26,28,30,32]
> + num = len(start)
> + for pos in range(num):
> + new_value = int(target_guid[start[pos]:end[pos]], 16)
> + target_list.append(new_value)
> + new_format = GUID()
> + new_format.from_list(target_list)
> + return new_format
> +
> +
> +# Get data from ctypes to bytes.
> +def struct2stream(s) -> bytes:
> + length = sizeof(s)
> + p = cast(pointer(s), POINTER(c_char * length))
> + return p.contents.raw
> +
> +
> +
> +def GetPadSize(Size: int, alignment: int) -> int:
> + if Size % alignment == 0:
> + return 0
> + Pad_Size = alignment - Size % alignment
> + return Pad_Size
> diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> new file mode 100644
> index 000000000000..33c49ffb50bc
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> @@ -0,0 +1,66 @@
> +## @file
> +# This file is used to define the Ffs Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +EFI_FFS_FILE_HEADER_LEN = 24
> +EFI_FFS_FILE_HEADER2_LEN = 32
> +
> +class CHECK_SUM(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Header', c_uint8),
> + ('File', c_uint8),
> + ]
> +
> +class EFI_FFS_INTEGRITY_CHECK(Union):
> + _pack_ = 1
> + _fields_ = [
> + ('Checksum', CHECK_SUM),
> + ('Checksum16', c_uint16),
> + ]
> +
> +
> +class EFI_FFS_FILE_HEADER(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Name', GUID),
> + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> + ('Type', c_uint8),
> + ('Attributes', c_uint8),
> + ('Size', ARRAY(c_uint8, 3)),
> + ('State', c_uint8),
> + ]
> +
> + @property
> + def FFS_FILE_SIZE(self) -> int:
> + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> +
> + @property
> + def HeaderLength(self) -> int:
> + return 24
> +
> +class EFI_FFS_FILE_HEADER2(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Name', GUID),
> + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> + ('Type', c_uint8),
> + ('Attributes', c_uint8),
> + ('Size', ARRAY(c_uint8, 3)),
> + ('State', c_uint8),
> + ('ExtendedSize', c_uint64),
> + ]
> +
> + @property
> + def FFS_FILE_SIZE(self) -> int:
> + return self.ExtendedSize
> +
> + @property
> + def HeaderLength(self) -> int:
> + return 32
> diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> new file mode 100644
> index 000000000000..aae2feae844a
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> @@ -0,0 +1,112 @@
> +## @file
> +# This file is used to define the FV Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from ast import Str
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +class EFI_FV_BLOCK_MAP_ENTRY(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('NumBlocks', c_uint32),
> + ('Length', c_uint32),
> + ]
> +
> +
> +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> + _fields_ = [
> + ('ZeroVector', ARRAY(c_uint8, 16)),
> + ('FileSystemGuid', GUID),
> + ('FvLength', c_uint64),
> + ('Signature', c_uint32),
> + ('Attributes', c_uint32),
> + ('HeaderLength', c_uint16),
> + ('Checksum', c_uint16),
> + ('ExtHeaderOffset', c_uint16),
> + ('Reserved', c_uint8),
> + ('Revision', c_uint8),
> + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY,
> 1)),
> + ]
> +
> +def Refine_FV_Header(nums):
> + class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> + _fields_ = [
> + ('ZeroVector', ARRAY(c_uint8, 16)),
> + ('FileSystemGuid', GUID),
> + ('FvLength', c_uint64),
> + ('Signature', c_uint32),
> + ('Attributes', c_uint32),
> + ('HeaderLength', c_uint16),
> + ('Checksum', c_uint16),
> + ('ExtHeaderOffset', c_uint16),
> + ('Reserved', c_uint8),
> + ('Revision', c_uint8),
> + ('BlockMap',
> ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
> + ]
> + return EFI_FIRMWARE_VOLUME_HEADER
> +
> +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
> + _fields_ = [
> + ('FvName', GUID),
> + ('ExtHeaderSize', c_uint32)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
> + _fields_ = [
> + ('ExtEntrySize', c_uint16),
> + ('ExtEntryType', c_uint16)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32),
> + ('Types', ARRAY(GUID, 1))
> + ]
> +
> +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) ->
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
> + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32),
> + ('Types', ARRAY(GUID, nums))
> + ]
> + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID),
> + ('Data', ARRAY(c_uint8, 1))
> + ]
> +
> +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) ->
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
> + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID),
> + ('Data', ARRAY(c_uint8, nums))
> + ]
> + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
> + _fields_ = [
> + ('Hdr',
> EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('UsedSize', c_uint32)
> + ]
> diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> new file mode 100644
> index 000000000000..c2cc8e0172fb
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> @@ -0,0 +1,110 @@
> +## @file
> +# This file is used to define the Section Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +EFI_COMMON_SECTION_HEADER_LEN = 4
> +EFI_COMMON_SECTION_HEADER2_LEN = 8
> +
> +class EFI_COMMON_SECTION_HEADER(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Size', ARRAY(c_uint8, 3)),
> + ('Type', c_uint8),
> + ]
> +
> + @property
> + def SECTION_SIZE(self) -> int:
> + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> +
> + def Common_Header_Size(self) -> int:
> + return 4
> +
> +class EFI_COMMON_SECTION_HEADER2(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Size', ARRAY(c_uint8, 3)),
> + ('Type', c_uint8),
> + ('ExtendedSize', c_uint32),
> + ]
> +
> + @property
> + def SECTION_SIZE(self) -> int:
> + return self.ExtendedSize
> +
> + def Common_Header_Size(self) -> int:
> + return 8
> +
> +class EFI_COMPRESSION_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('UncompressedLength', c_uint32),
> + ('CompressionType', c_uint8),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 5
> +
> +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('SubTypeGuid', GUID),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 16
> +
> +class EFI_GUID_DEFINED_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('SectionDefinitionGuid', GUID),
> + ('DataOffset', c_uint16),
> + ('Attributes', c_uint16),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 20
> +
> +def Get_USER_INTERFACE_Header(nums: int):
> + class EFI_SECTION_USER_INTERFACE(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('FileNameString', ARRAY(c_uint16, nums)),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 2 * nums
> +
> + def GetUiString(self) -> str:
> + UiString = ''
> + for i in range(nums):
> + if self.FileNameString[i]:
> + UiString += chr(self.FileNameString[i])
> + return UiString
> +
> + return EFI_SECTION_USER_INTERFACE
> +
> +def Get_VERSION_Header(nums: int):
> + class EFI_SECTION_VERSION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('BuildNumber', c_uint16),
> + ('VersionString', ARRAY(c_uint16, nums)),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 2 * (nums+1)
> +
> + def GetVersionString(self) -> str:
> + VersionString = ''
> + for i in range(nums):
> + if self.VersionString[i]:
> + VersionString += chr(self.VersionString[i])
> + return VersionString
> +
> + return EFI_SECTION_VERSION
> diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py
> b/BaseTools/Source/Python/FMMT/PI/__init__.py
> new file mode 100644
> index 000000000000..4e8296fad1ba
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
> @@ -0,0 +1,6 @@
> +## @file
> +# This file is used to define the FMMT dependent external tool management
> class.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/README.md
> b/BaseTools/Source/Python/FMMT/README.md
> new file mode 100644
> index 000000000000..e14dfa34ea66
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/README.md
> @@ -0,0 +1,180 @@
> +# FMMT
> +## Overview
> +This FMMT tool is the python implementation of the edk2 FMMT tool which
> locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
> +This implementation has the same usage as the edk2 FMMT, but it's more
> readable and relaiable.
> +
> +# FMMT User Guide
> +
> +#### Last updated October 13, 2021
> +
> +Important Changes and Updates:
> +
> +- Oct 13, 2021 Initial Draft of FMMT Python Tool
> +
> +#### Note:
> +
> +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is
> much easier to maintain and extend other functions.
> +
> +
> +
> +# 1. Introduction
> +
> +## 1.1 Overview
> +
> +The Firmware Device is a persistent physical repository that contains
> firmware code and/or data. The firmware code and/or data stored in
> Firmware Volumes. Detail layout of Firmware Volumes is described in
?Figure
> 1. The Firmware Volume Format?.
> +
> +![](Img/FirmwareVolumeFormat.png)
> +
> +<center>Figure 1. The Firmware Volume Format</center>
> +
> +In firmware development, binary file has its firmware layout following
the
> Platform-Initialization Specification. Thus, operation on FV file / FFS
file
> (Firmware File) is an efficient and convenient way for firmware function
> testing and developing. FMMT Python tool is used for firmware files
> operation.
> +
> +## 1.2 Tool Capabilities
> +
> +The FMMT tool is capable of:
> +
> +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware
> Files)
> +
> +- Add a new FFS into a FV file (both included in a FD file or not)
> +
> +- Replace an FFS in a FV file with a new FFS file
> +
> +- Delete an FFS in a FV file (both included in a FD file or not)
> +
> +- Extract the FFS from a FV file (both includ-v < Inputfile > <
Outputfile >ed
> in a FD file or not)
> +
> +## 1.3 References
> +
> +| Document |
> +| ------------------------------------------------ |
> +| UEFI Platform Initialization (PI) Specification |
> +
> +
> +
> +# 2. FMMT Python Tool Usage
> +
> +## 2.1 Required Files
> +
> +### 2.1.1 Independent use
> +
> +When independent use the FMMT Python Tool, the following files and
> settings are required:
> +
> +- GuidTool executable files used for Decompress/Compress Firmware data.
> +
> +- Environment variables path with GuidTool path setting.
> +
> +### 2.1.2 Use with Build System
> +
> +When use the FMMT Python Tool with Build System:
> +
> +- If only use Edk2 based GuidTool, do not need other preparation.
> +
> +- If use other customized GuidTool, need prepare the config file with
GuidTool
> info. The syntax for GuidTool definition shown as follow:
> +
> + ***ToolsGuid ShortName Command***
> +
> + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI
> BrotliCompress***
> +
> +## 2.2 Syntax
> +
> +### 2.2.1 Syntax for Parse file
> +
> +***-v < Inputfile > < Outputfile > -l < LogFileType >***
> +
> +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile*
is
> optional, if inputs, the *Inputfile* will be encapsulated into
*Outputfile*
> following the parsed firmware layout. *"-l LogFileType"* is optional, it
decides
> the format of log file which saves Binary layout. Currently supports:
json, txt.
> More formats will be added in the future.
> +
> +### 2.2.2 Syntax for Add a new FFS
> +
> +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > <
> Outputfile >***
> +
> +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid*
> (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
> +
> +### 2.2.3 Syntax for Delete an FFS
> +
> +***-d < Inputfile > < TargetFfsName > < Outputfile > <
> TargetFvName/TargetFvGuid >***
> +
> +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs
> which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is
the
> parent of TargetFfs*.*
> +
> +### 2.2.4 Syntax for Replace an FFS
> +
> +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > <
> TargetFvName/TargetFvGuid >***
> +
> +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the
TargetFfs
> which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is
> the parent of TargetFfs*.*
> +
> +### 2.2.5 Syntax for Extract an FFS
> +
> +***-e < Inputfile > < TargetFfsName > < Outputfile >***
> +
> +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the
TargetFfs
> which will be extracted.
> +
> +
> +
> +# 3. FMMT Python Tool Design
> +
> +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each
> Node have its Data field, which saves the
> FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the
> parse/add/delete/replace/extract operations are based on the NodeTree
> (adjusting the layout and data).
> +
> +## 3.1 NodeTree
> +
> +A whole NodeTree saves all the Firmware info.
> +
> +- Parent & Child relationship figured out the Firmware layout.
> +
> +- Each Node have several fields. ?Data? field saves an FirmwareClass
> instance which contains all the data info of the info.
> +
> +### 3.1.1 NodeTree Format
> +
> +The NodeTree will be created with parse function. When parse a file, a
Root
> Node will be initialized firstly. The Data split and Tree construction
process is
> described with an FD file shown as ?Figure 2. The NodeTree format?:
> +
> +- A Root Node is initialized.
> +
> +- Use the ?FV Signature? as FV key to split Whole FD
> Data. ?FV0?, ?FV1?, ?FV2?? Node created.
> +
> +- After FV level Node created, use the ?Ffs Data Size? as FFS key to
split each
> FV Data. ?Ffs0?...Node created.
> +
> +- After FFS level Node created, use the ?Section Data Size? as Section
key to
> split each Ffs Data. ?Section0?...Node created.
> +
> +- If some of Section includes other Sections, continue use the ?Section
Data
> Size? as Section key to split each Section Data.
> +
> +- After all Node created, the whole NodeTree saves all the info. (Can be
used
> in other functions or print the whole firmware layout into log file)
> +
> +![](Img/NodeTreeFormat.png)
> +
> +<center>Figure 2. The NodeTree format</center>
> +
> +### 3.1.2 Node Factory and Product
> +
> +As 3.1.1, Each Node is created by data split and recognition. To extend
the
> NodeTree usage, Factory pattern is used in Node created process.
> +
> +Each Node have its Factory to create Product and use Product ParserData
> function to deal with the data.
> +
> +## 3.2 GuidTool
> +
> +There are two ways to set the GuidTool. One from Config file, another
from
> environment variables.
> +
> +Current GuidTool first check if has Config file.
> +
> +- If have, load the config GuidTool Information.
> +
> +- Else get from environment variables.
> +
> +### 3.2.1 Get from Config file
> +
> +- Config file should in same folder with FMMT.py or the path in
environment
> variables.
> +
> +- Content should follow the format:
> +
> + ***ToolsGuid ShortName Command***
> +
> +### 3.2.2 Get from Environment Variables
> +
> +- The GuidTool Command used must be set in environment variables.
> +
> +### 3.2.3 Edk2 Based GuidTool
> +
> +| ***Guid*** | ***ShortName***
> | ***Command*** |
> +| ------------------------------------------ | --------------- |
--------------------- |
> +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** |
> ***TianoCompress*** |
> +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** |
> ***LzmaCompress*** |
> +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** |
> ***GenCrc32*** |
> +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** |
> ***LzmaF86Compress*** |
> +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** |
> ***BrotliCompress*** |
> diff --git a/BaseTools/Source/Python/FMMT/__init__.py
> b/BaseTools/Source/Python/FMMT/__init__.py
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> new file mode 100644
> index 000000000000..33ffe73cab27
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> @@ -0,0 +1,371 @@
> +## @file
> +# This file is used to implement of the various bianry parser.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from re import T
> +import copy
> +import os
> +from PI.Common import *
> +from core.BiosTreeNode import *
> +from core.BiosTree import *
> +from core.GuidTools import *
> +
> +ROOT_TREE = 'ROOT'
> +ROOT_FV_TREE = 'ROOT_FV_TREE'
> +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> +
> +FV_TREE = 'FV'
> +DATA_FV_TREE = 'DATA_FV'
> +FFS_TREE = 'FFS'
> +FFS_PAD = 'FFS_PAD'
> +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> +SECTION_TREE = 'SECTION'
> +SEC_FV_TREE = 'SEC_FV_IMAGE'
> +BINARY_DATA = 'BINARY'
> +Fv_count = 0
> +
> +## Abstract factory
> +class BinaryFactory():
> + type:list = []
> +
> + def Create_Product():
> + pass
> +
> +class BinaryProduct():
> + ## Use GuidTool to decompress data.
> + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
> + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
")
> + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> + DecompressedData = guidtool.unpack(Section_Data)
> + return DecompressedData
> +
> + def ParserData():
> + pass
> +
> +class SectionFactory(BinaryFactory):
> + type = [SECTION_TREE]
> +
> + def Create_Product():
> + return SectionProduct()
> +
> +class FfsFactory(BinaryFactory):
> + type = [ROOT_SECTION_TREE, FFS_TREE]
> +
> + def Create_Product():
> + return FfsProduct()
> +
> +class FvFactory(BinaryFactory):
> + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
> +
> + def Create_Product():
> + return FvProduct()
> +
> +class FdFactory(BinaryFactory):
> + type = [ROOT_FV_TREE, ROOT_TREE]
> +
> + def Create_Product():
> + return FdProduct()
> +
> +class SectionProduct(BinaryProduct):
> + ## Decompress the compressed section.
> + def ParserData(self, Section_Tree, whole_Data: bytes,
> Rel_Whole_Offset: int=0) -> None:
> + if Section_Tree.Data.Type == 0x01:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + self.ParserFfs(Section_Tree, b'')
> + # Guided Define Section
> + elif Section_Tree.Data.Type == 0x02:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + DeCompressGuidTool =
> Section_Tree.Data.ExtHeader.SectionDefinitionGuid
> + Section_Tree.Data.Data =
> self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
> + Section_Tree.Data.Size = len(Section_Tree.Data.Data) +
> Section_Tree.Data.HeaderLength
> + self.ParserFfs(Section_Tree, b'')
> + elif Section_Tree.Data.Type == 0x03:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + self.ParserFfs(Section_Tree, b'')
> + # SEC_FV Section
> + elif Section_Tree.Data.Type == 0x17:
> + global Fv_count
> + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
> + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
> + Sec_Fv_Tree.type = SEC_FV_TREE
> + Sec_Fv_Tree.Data = Sec_Fv_Info
> + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
> + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset +
> Sec_Fv_Tree.Data.Header.HeaderLength
> + Sec_Fv_Tree.Data.Data =
> Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
> + Section_Tree.insertChild(Sec_Fv_Tree)
> + Fv_count += 1
> +
> + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> + Rel_Offset = 0
> + Section_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get
it
> from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Section_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Section recorded in its
Parent
> Section.
> + while Rel_Offset < Data_Size:
> + # Create a SectionNode and set it as the SectionTree's Data
> + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> + Section_Tree = BIOSTREE(Section_Info.Name)
> + Section_Tree.type = SECTION_TREE
> + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> Rel_Offset+Section_Info.Size]
> + Section_Info.DOffset = Section_Offset +
> Section_Info.HeaderLength + Rel_Whole_Offset
> + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> + Section_Info.ROffset = Rel_Offset
> + if Section_Info.Header.Type == 0:
> + break
> + # The final Section in parent Section does not need to add
> padding, else must be 4-bytes align with parent Section start offset
> + Pad_Size = 0
> + if
> (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
Data_Size):
> + Pad_Size = GetPadSize(Section_Info.Size, 4)
> + Section_Info.PadData = Pad_Size * b'\x00'
> + if Section_Info.Header.Type == 0x02:
> + Section_Info.DOffset = Section_Offset +
> Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> Rel_Offset+Section_Info.Size]
> + if Section_Info.Header.Type == 0x14:
> + ParTree.Data.Version =
> Section_Info.ExtHeader.GetVersionString()
> + if Section_Info.Header.Type == 0x15:
> + ParTree.Data.UiName =
> Section_Info.ExtHeader.GetUiString()
> + Section_Offset += Section_Info.Size + Pad_Size
> + Rel_Offset += Section_Info.Size + Pad_Size
> + Section_Tree.Data = Section_Info
> + ParTree.insertChild(Section_Tree)
> +
> +class FfsProduct(BinaryProduct):
> + # ParserFFs / GetSection
> + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> + Rel_Offset = 0
> + Section_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get
it
> from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Section_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Section recorded in Ffs.
> + while Rel_Offset < Data_Size:
> + # Create a SectionNode and set it as the SectionTree's Data
> + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> + Section_Tree = BIOSTREE(Section_Info.Name)
> + Section_Tree.type = SECTION_TREE
> + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> Rel_Offset+Section_Info.Size]
> + Section_Info.DOffset = Section_Offset +
> Section_Info.HeaderLength + Rel_Whole_Offset
> + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> + Section_Info.ROffset = Rel_Offset
> + if Section_Info.Header.Type == 0:
> + break
> + # The final Section in Ffs does not need to add padding, else
> must be 4-bytes align with Ffs start offset
> + Pad_Size = 0
> + if
> (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
Data_Size):
> + Pad_Size = GetPadSize(Section_Info.Size, 4)
> + Section_Info.PadData = Pad_Size * b'\x00'
> + if Section_Info.Header.Type == 0x02:
> + Section_Info.DOffset = Section_Offset +
> Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> Rel_Offset+Section_Info.Size]
> + # If Section is Version or UI type, it saves the version and
UI
> info of its parent Ffs.
> + if Section_Info.Header.Type == 0x14:
> + ParTree.Data.Version =
> Section_Info.ExtHeader.GetVersionString()
> + if Section_Info.Header.Type == 0x15:
> + ParTree.Data.UiName =
> Section_Info.ExtHeader.GetUiString()
> + Section_Offset += Section_Info.Size + Pad_Size
> + Rel_Offset += Section_Info.Size + Pad_Size
> + Section_Tree.Data = Section_Info
> + ParTree.insertChild(Section_Tree)
> +
> +class FvProduct(BinaryProduct):
> + ## ParserFv / GetFfs
> + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> + Ffs_Offset = 0
> + Rel_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get
it
> from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Ffs_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Ffs recorded in Fv.
> + while Rel_Offset < Data_Size:
> + # Create a FfsNode and set it as the FFsTree's Data
> + if Data_Size - Rel_Offset < 24:
> + Ffs_Tree = BIOSTREE('Free_Space')
> + Ffs_Tree.type = FFS_FREE_SPACE
> + Ffs_Tree.Data =
> FreeSpaceNode(Whole_Data[Rel_Offset:])
> + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
> + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
> + ParTree.Data.Free_Space = Data_Size - Rel_Offset
> + ParTree.insertChild(Ffs_Tree)
> + Rel_Offset = Data_Size
> + else:
> + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
> + Ffs_Tree = BIOSTREE(Ffs_Info.Name)
> + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
> + Ffs_Info.DOffset = Ffs_Offset +
> Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
> + Ffs_Info.ROffset = Rel_Offset
> + if Ffs_Info.Name == PADVECTOR:
> + Ffs_Tree.type = FFS_PAD
> + Ffs_Info.Data =
> Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> Rel_Offset+Ffs_Info.Size]
> + Ffs_Info.Size = len(Ffs_Info.Data) +
> Ffs_Info.Header.HeaderLength
> + # if current Ffs is the final ffs of Fv and full of
b'\xff',
> define it with Free_Space
> + if struct2stream(Ffs_Info.Header).replace(b'\xff',
b'')
> == b'':
> + Ffs_Tree.type = FFS_FREE_SPACE
> + Ffs_Info.Data = Whole_Data[Rel_Offset:]
> + Ffs_Info.Size = len(Ffs_Info.Data)
> + ParTree.Data.Free_Space = Ffs_Info.Size
> + else:
> + Ffs_Tree.type = FFS_TREE
> + Ffs_Info.Data =
> Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> Rel_Offset+Ffs_Info.Size]
> + # The final Ffs in Fv does not need to add padding, else
> must be 8-bytes align with Fv start offset
> + Pad_Size = 0
> + if Ffs_Tree.type != FFS_FREE_SPACE and
> (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != Data_Size):
> + Pad_Size = GetPadSize(Ffs_Info.Size, 8)
> + Ffs_Info.PadData = Pad_Size * b'\xff'
> + Ffs_Offset += Ffs_Info.Size + Pad_Size
> + Rel_Offset += Ffs_Info.Size + Pad_Size
> + Ffs_Tree.Data = Ffs_Info
> + ParTree.insertChild(Ffs_Tree)
> +
> +class FdProduct(BinaryProduct):
> + type = [ROOT_FV_TREE, ROOT_TREE]
> +
> + ## Create DataTree with first level /fv Info, then parser each Fv.
> + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset:
int=0) ->
> None:
> + # Get all Fv image in Fd with offset and length
> + Fd_Struct = self.GetFvFromFd(whole_data)
> + data_size = len(whole_data)
> + Binary_count = 0
> + global Fv_count
> + # If the first Fv image is the Binary Fv, add it into the tree.
> + if Fd_Struct[0][1] != 0:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset = 0 + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> + # Add the first collected Fv image into the tree.
> + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
> + Cur_node.type = Fd_Struct[0][0]
> + Cur_node.Data = FvNode(Fv_count,
> whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
> + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
> + Cur_node.Data.DOffset =
> Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> + Cur_node.Data.Data =
> whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct
> [0][1]+Cur_node.Data.Size]
> + WholeFvTree.insertChild(Cur_node)
> + Fv_count += 1
> + Fv_num = len(Fd_Struct)
> + # Add all the collected Fv image and the Binary Fv image between
> them into the tree.
> + for i in range(Fv_num-1):
> + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data =
> whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset =
> Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
> + Cur_node.type = Fd_Struct[i+1][0]
> + Cur_node.Data = FvNode(Fv_count,
> whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
> + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
> + Cur_node.Data.DOffset =
> Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> + Cur_node.Data.Data =
> whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru
> ct[i+1][1]+Cur_node.Data.Size]
> + WholeFvTree.insertChild(Cur_node)
> + Fv_count += 1
> + # If the final Fv image is the Binary Fv, add it into the tree
> + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data =
> whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset =
> Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> +
> + ## Get the first level Fv from Fd file.
> + def GetFvFromFd(self, whole_data: bytes=b'') -> list:
> + Fd_Struct = []
> + data_size = len(whole_data)
> + cur_index = 0
> + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV
> image offset and length.
> + while cur_index < data_size:
> + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in
> whole_data[cur_index:]:
> + target_index =
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) +
> cur_index
> + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> ZEROVECTOR_BYTE:
> + Fd_Struct.append([FV_TREE, target_index - 16,
> unpack("Q", whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + cur_index = 0
> + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV
> image offset and length.
> + while cur_index < data_size:
> + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in
> whole_data[cur_index:]:
> + target_index =
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) +
> cur_index
> + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> ZEROVECTOR_BYTE:
> + Fd_Struct.append([FV_TREE, target_index - 16,
> unpack("Q", whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + cur_index = 0
> + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image
> offset and length.
> + while cur_index < data_size:
> + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in
> whole_data[cur_index:]:
> + target_index =
> whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) +
> cur_index
> + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> ZEROVECTOR_BYTE:
> + Fd_Struct.append([DATA_FV_TREE, target_index -
> 16, unpack("Q", whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + # Sort all the collect Fv image with offset.
> + Fd_Struct.sort(key=lambda x:x[1])
> + tmp_struct = copy.deepcopy(Fd_Struct)
> + tmp_index = 0
> + Fv_num = len(Fd_Struct)
> + # Remove the Fv image included in another Fv image.
> + for i in range(1,Fv_num):
> + if tmp_struct[i][1]+tmp_struct[i][2][0] <
> tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
> + Fd_Struct.remove(Fd_Struct[i-tmp_index])
> + tmp_index += 1
> + return Fd_Struct
> +
> +class ParserEntry():
> + FactoryTable:dict = {
> + SECTION_TREE: SectionFactory,
> + ROOT_SECTION_TREE: FfsFactory,
> + FFS_TREE: FfsFactory,
> + ROOT_FFS_TREE: FvFactory,
> + FV_TREE: FvFactory,
> + SEC_FV_TREE: FvFactory,
> + ROOT_FV_TREE: FdFactory,
> + ROOT_TREE: FdFactory,
> + }
> +
> + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
> + if Tree_type in self.FactoryTable:
> + return self.FactoryTable[Tree_type]
> +
> + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data:
> bytes, Offset: int) -> None:
> + New_Product = TargetFactory.Create_Product()
> + New_Product.ParserData(Tree, Data, Offset)
> +
> + def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
> + TargetFactory = self.GetTargetFactory(Tree.type)
> + if TargetFactory:
> + self.Generate_Product(TargetFactory, Tree, Data, Offset)
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py
> b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> new file mode 100644
> index 000000000000..0b6252ecc1bb
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> @@ -0,0 +1,198 @@
> +## @file
> +# This file is used to define the Bios layout tree structure and related
> operations.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import collections
> +from PI.Common import *
> +
> +ROOT_TREE = 'ROOT'
> +ROOT_FV_TREE = 'ROOT_FV_TREE'
> +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> +
> +FV_TREE = 'FV'
> +DATA_FV_TREE = 'DATA_FV'
> +FFS_TREE = 'FFS'
> +FFS_PAD = 'FFS_PAD'
> +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> +SECTION_TREE = 'SECTION'
> +SEC_FV_TREE = 'SEC_FV_IMAGE'
> +BINARY_DATA = 'BINARY'
> +
> +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE,
> ROOT_SECTION_TREE]
> +FvType = [FV_TREE, SEC_FV_TREE]
> +FfsType = FFS_TREE
> +SecType = SECTION_TREE
> +
> +class BIOSTREE:
> + def __init__(self, NodeName: str) -> None:
> + self.key = NodeName
> + self.type = None
> + self.Data = None
> + self.Child = []
> + self.Findlist = []
> + self.Parent = None
> + self.NextRel = None
> + self.LastRel = None
> +
> + def HasChild(self) -> bool:
> + if self.Child == []:
> + return False
> + else:
> + return True
> +
> + def isFinalChild(self) -> bool:
> + ParTree = self.Parent
> + if ParTree:
> + if ParTree.Child[-1] == self:
> + return True
> + return False
> +
> + # FvTree.insertChild()
> + def insertChild(self, newNode, pos: int=None) -> None:
> + if len(self.Child) == 0:
> + self.Child.append(newNode)
> + else:
> + if not pos:
> + LastTree = self.Child[-1]
> + self.Child.append(newNode)
> + LastTree.NextRel = newNode
> + newNode.LastRel = LastTree
> + else:
> + newNode.NextRel = self.Child[pos-1].NextRel
> + newNode.LastRel = self.Child[pos].LastRel
> + self.Child[pos-1].NextRel = newNode
> + self.Child[pos].LastRel = newNode
> + self.Child.insert(pos, newNode)
> + newNode.Parent = self
> +
> + # lastNode.insertRel(newNode)
> + def insertRel(self, newNode) -> None:
> + if self.Parent:
> + parentTree = self.Parent
> + new_index = parentTree.Child.index(self) + 1
> + parentTree.Child.insert(new_index, newNode)
> + self.NextRel = newNode
> + newNode.LastRel = self
> +
> + def deleteNode(self, deletekey: str) -> None:
> + FindStatus, DeleteTree = self.FindNode(deletekey)
> + if FindStatus:
> + parentTree = DeleteTree.Parent
> + lastTree = DeleteTree.LastRel
> + nextTree = DeleteTree.NextRel
> + if parentTree:
> + index = parentTree.Child.index(DeleteTree)
> + del parentTree.Child[index]
> + if lastTree and nextTree:
> + lastTree.NextRel = nextTree
> + nextTree.LastRel = lastTree
> + elif lastTree:
> + lastTree.NextRel = None
> + elif nextTree:
> + nextTree.LastRel = None
> + return DeleteTree
> + else:
> + print('Could not find the target tree')
> + return None
> +
> + def FindNode(self, key: str, Findlist: list) -> None:
> + if self.key == key or (self.Data and self.Data.Name == key) or
> (self.type == FFS_TREE and self.Data.UiName == key):
> + Findlist.append(self)
> + else:
> + for item in self.Child:
> + item.FindNode(key, Findlist)
> +
> + def GetTreePath(self):
> + BiosTreePath = [self]
> + while self.Parent:
> + BiosTreePath.insert(0, self.Parent)
> + self = self.Parent
> + return BiosTreePath
> +
> + def parserTree(self, TargetDict: dict=None, Info: list=None, space:
int=0,
> ParFvId="") -> None:
> + Key = list(TargetDict.keys())[0]
> + if TargetDict[Key]["Type"] in RootType:
> + Info.append("Image File: {}".format(Key))
> + Info.append("FilesNum:
> {}".format(TargetDict.get(Key).get('FilesNum')))
> + Info.append("\n")
> + elif TargetDict[Key]["Type"] in FvType:
> + space += 2
> + if TargetDict[Key]["Type"] == SEC_FV_TREE:
> + Info.append("{}Child FV named {} of {}".format(space*" ",
> Key, ParFvId))
> + space += 2
> + else:
> + Info.append("FvId: {}".format(Key))
> + ParFvId = Key
> + Info.append("{}FvNameGuid: {}".format(space*" ",
> TargetDict.get(Key).get('FvNameGuid')))
> + Info.append("{}Attributes: {}".format(space*" ",
> TargetDict.get(Key).get('Attributes')))
> + Info.append("{}Total Volume Size: {}".format(space*" ",
> TargetDict.get(Key).get('Size')))
> + Info.append("{}Free Volume Size: {}".format(space*" ",
> TargetDict.get(Key).get('FreeSize')))
> + Info.append("{}Volume Offset: {}".format(space*" ",
> TargetDict.get(Key).get('Offset')))
> + Info.append("{}FilesNum: {}".format(space*" ",
> TargetDict.get(Key).get('FilesNum')))
> + elif TargetDict[Key]["Type"] in FfsType:
> + space += 2
> + if TargetDict.get(Key).get('UiName') != "b''":
> + Info.append("{}File: {} / {}".format(space*" ", Key,
> TargetDict.get(Key).get('UiName')))
> + else:
> + Info.append("{}File: {}".format(space*" ", Key))
> + if "Files" in list(TargetDict[Key].keys()):
> + for item in TargetDict[Key]["Files"]:
> + self.parserTree(item, Info, space, ParFvId)
> +
> + def ExportTree(self,TreeInfo: dict=None) -> dict:
> + if TreeInfo is None:
> + TreeInfo =collections.OrderedDict()
> +
> + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or
> self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
> + key = str(self.key)
> + TreeInfo[self.key] = collections.OrderedDict()
> + TreeInfo[self.key]["Name"] = key
> + TreeInfo[self.key]["Type"] = self.type
> + TreeInfo[self.key]["FilesNum"] = len(self.Child)
> + elif self.type == FV_TREE or self.type == SEC_FV_TREE:
> + key = str(self.Data.FvId)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + if self.Data.FvId != self.Data.Name:
> + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Attributes"] =
hex(self.Data.Header.Attributes)
> + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
> + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self.type == FFS_TREE:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
> + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self.type == SECTION_TREE and self.Data.Type == 0x02:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) +
> self.Data.HeaderLength)
> + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self is not None:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> +
> + for item in self.Child:
> + TreeInfo[key].setdefault('Files',[]).append(
item.ExportTree())
> +
> + return TreeInfo
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> new file mode 100644
> index 000000000000..cfb711eea5a2
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> @@ -0,0 +1,191 @@
> +## @file
> +# This file is used to define the BIOS Tree Node.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from PI.FvHeader import *
> +from PI.FfsFileHeader import *
> +from PI.SectionHeader import *
> +from PI.Common import *
> +import uuid
> +
> +SectionHeaderType = {
> + 0x01:'EFI_COMPRESSION_SECTION',
> + 0x02:'EFI_GUID_DEFINED_SECTION',
> + 0x03:'EFI_SECTION_DISPOSABLE',
> + 0x10:'EFI_SECTION_PE32',
> + 0x11:'EFI_SECTION_PIC',
> + 0x12:'EFI_SECTION_TE',
> + 0x13:'EFI_SECTION_DXE_DEPEX',
> + 0x14:'EFI_SECTION_VERSION',
> + 0x15:'EFI_SECTION_USER_INTERFACE',
> + 0x16:'EFI_SECTION_COMPATIBILITY16',
> + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
> + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
> + 0x19:'EFI_SECTION_RAW',
> + 0x1B:'EFI_SECTION_PEI_DEPEX',
> + 0x1C:'EFI_SECTION_MM_DEPEX'
> +}
> +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
> +
> +class BinaryNode:
> + def __init__(self, name: str) -> None:
> + self.Size = 0
> + self.Name = "BINARY" + str(name)
> + self.HOffset = 0
> + self.Data = b''
> +
> +class FvNode:
> + def __init__(self, name, buffer: bytes) -> None:
> + self.Header =
> EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
> + Map_num = (self.Header.HeaderLength - 56)//8
> + self.Header =
> Refine_FV_Header(Map_num).from_buffer_copy(buffer)
> + self.FvId = "FV" + str(name)
> + self.Name = "FV" + str(name)
> + if self.Header.ExtHeaderOffset:
> + self.ExtHeader =
> EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header
> .ExtHeaderOffset:])
> + self.Name =
> uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
> + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
> + if self.ExtHeader.ExtHeaderSize != 20:
> + self.ExtEntryExist = 1
> + self.ExtEntry =
> EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry
> Offset:])
> + self.ExtTypeExist = 1
> + if self.ExtEntry.ExtEntryType == 0x01:
> + nums = (self.ExtEntry.ExtEntrySize - 8) // 16
> + self.ExtEntry =
> Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[s
> elf.ExtEntryOffset:])
> + elif self.ExtEntry.ExtEntryType == 0x02:
> + nums = self.ExtEntry.ExtEntrySize - 20
> + self.ExtEntry =
> Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[
> self.ExtEntryOffset:])
> + elif self.ExtEntry.ExtEntryType == 0x03:
> + self.ExtEntry =
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b
> uffer[self.ExtEntryOffset:])
> + else:
> + self.ExtTypeExist = 0
> + else:
> + self.ExtEntryExist = 0
> + self.Size = self.Header.FvLength
> + self.HeaderLength = self.Header.HeaderLength
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + if self.Header.Signature != 1213613663:
> + print('Invalid! Fv Header Signature {} is not
> "_FVH".'.format(self.Header.Signature))
> + with open(str(self.Name)+'.fd', "wb") as f:
> + f.write(struct2stream(self.Header))
> + assert False
> + self.PadData = b''
> + self.Free_Space = 0
> + self.ModCheckSum()
> +
> + def ModCheckSum(self) -> None:
> + # Fv Header Sums to 0.
> + Header = struct2stream(self.Header)[::-1]
> + Size = self.HeaderLength // 2
> + Sum = 0
> + for i in range(Size):
> + Sum += int(Header[i*2: i*2 + 2].hex(), 16)
> + if Sum & 0xffff:
> + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum -
> self.Header.Checksum)[-4:], 16)), 16)
> +
> + def ModFvExt(self) -> None:
> + # If used space changes and self.ExtEntry.UsedSize exists,
> self.ExtEntry.UsedSize need to be changed.
> + if self.Header.ExtHeaderOffset and self.ExtEntryExist and
> self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03:
> + self.ExtEntry.UsedSize = self.Header.FvLength -
> self.Free_Space
> +
> + def ModFvSize(self) -> None:
> + # If Fv Size changed, self.Header.FvLength and
> self.Header.BlockMap[i].NumBlocks need to be changed.
> + BlockMapNum = len(self.Header.BlockMap)
> + for i in range(BlockMapNum):
> + if self.Header.BlockMap[i].Length:
> + self.Header.BlockMap[i].NumBlocks =
> self.Header.FvLength // self.Header.BlockMap[i].Length
> +
> + def ModExtHeaderData(self) -> None:
> + if self.Header.ExtHeaderOffset:
> + ExtHeaderData = struct2stream(self.ExtHeader)
> + ExtHeaderDataOffset = self.Header.ExtHeaderOffset -
> self.HeaderLength
> + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData
> + self.Data[ExtHeaderDataOffset+20:]
> + if self.Header.ExtHeaderOffset and self.ExtEntryExist:
> + ExtHeaderEntryData = struct2stream(self.ExtEntry)
> + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset +
> 20 - self.HeaderLength
> + self.Data = self.Data[:ExtHeaderEntryDataOffset] +
> ExtHeaderEntryData +
> self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
> +
> +class FfsNode:
> + def __init__(self, buffer: bytes) -> None:
> + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
> + # self.Attributes = unpack("<B", buffer[21:22])[0]
> + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes !=
0xff
> and self.Header.Attributes & 0x01 == 1:
> + print('Error Ffs Header! Ffs Header Size and Attributes is
not
> matched!')
> + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes &
> 0x01 == 1:
> + self.Header =
> EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
> + self.Name =
> uuid.UUID(bytes_le=struct2stream(self.Header.Name))
> + self.UiName = b''
> + self.Version = b''
> + self.Size = self.Header.FFS_FILE_SIZE
> + self.HeaderLength = self.Header.HeaderLength
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + self.PadData = b''
> +
> + def ModCheckSum(self) -> None:
> + HeaderData = struct2stream(self.Header)
> + HeaderSum = 0
> + for item in HeaderData:
> + HeaderSum += item
> + HeaderSum -= self.Header.State
> + HeaderSum -= self.Header.IntegrityCheck.Checksum.File
> + if HeaderSum & 0xff:
> + Header = self.Header.IntegrityCheck.Checksum.Header +
> 0x100 - int(hex(HeaderSum)[-2:], 16)
> + self.Header.IntegrityCheck.Checksum.Header =
> int(hex(Header)[-2:], 16)
> +
> +class SectionNode:
> + def __init__(self, buffer: bytes) -> None:
> + if buffer[0:3] != b'\xff\xff\xff':
> + self.Header =
> EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
> + else:
> + self.Header =
> EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
> + if self.Header.Type in SectionHeaderType:
> + self.Name = SectionHeaderType[self.Header.Type]
> + elif self.Header.Type == 0:
> + self.Name = "EFI_SECTION_RAW"
> + else:
> + self.Name = "SECTION"
> + if self.Header.Type in HeaderType:
> + self.ExtHeader = self.GetExtHeader(self.Header.Type,
> buffer[self.Header.Common_Header_Size():],
> (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
> + self.HeaderLength = self.Header.Common_Header_Size() +
> self.ExtHeader.ExtHeaderSize()
> + else:
> + self.ExtHeader = None
> + self.HeaderLength = self.Header.Common_Header_Size()
> + self.Size = self.Header.SECTION_SIZE
> + self.Type = self.Header.Type
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + self.OriData = b''
> + self.OriHeader = b''
> + self.PadData = b''
> +
> + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) ->
None:
> + if Type == 0x01:
> + return
> EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
> + elif Type == 0x02:
> + return
> EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
> + elif Type == 0x14:
> + return Get_VERSION_Header((nums -
> 2)//2).from_buffer_copy(buffer)
> + elif Type == 0x15:
> + return
> Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
> + elif Type == 0x18:
> + return
> EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
> +
> +class FreeSpaceNode:
> + def __init__(self, buffer: bytes) -> None:
> + self.Name = 'Free_Space'
> + self.Data = buffer
> + self.Size = len(buffer)
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.PadData = b''
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> new file mode 100644
> index 000000000000..a0432c4093cf
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> @@ -0,0 +1,140 @@
> +## @file
> +# This file is used to define the functions to operate bios binary file.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from core.FMMTParser import *
> +from core.FvHandler import *
> +from utils.FvLayoutPrint import *
> +
> +global Fv_count
> +Fv_count = 0
> +
> +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE',
> 'ROOT_SECTION_TREE'
> +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None,
outputfile:
> str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # 3. Log Output
> + InfoDict = FmmtParser.WholeFvTree.ExportTree()
> + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
> + GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
> + if logfile:
> + GetFormatter(logfile.lower()).dump(InfoDict,
>
FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile),
> ".{}".format(logfile.lower())))
> + # 4. Data Encapsultion
> + if outputfile:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str,
Fv_name:
> str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # 3. Data Modify
> + FmmtParser.WholeFvTree.FindNode(TargetFfs_name,
> FmmtParser.WholeFvTree.Findlist)
> + # Choose the Specfic DeleteFfs with Fv info
> + if Fv_name:
> + for item in FmmtParser.WholeFvTree.Findlist:
> + if item.Parent.key != Fv_name and
> item.Parent.Data.Name != Fv_name:
> + FmmtParser.WholeFvTree.Findlist.remove(item)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
> + FfsMod = FvHandler(None, Delete_Ffs)
> + Status = FfsMod.DeleteFfs()
> + else:
> + print('Target Ffs not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile:
str) ->
> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # Get Target Fv and Target Ffs_Pad
> + FmmtParser.WholeFvTree.FindNode(Fv_name,
> FmmtParser.WholeFvTree.Findlist)
> + # Create new ffs Tree
> + with open(newffsfile, "rb") as f:
> + new_ffs_data = f.read()
> + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
> + Status = False
> + # 3. Data Modify
> + if FmmtParser.WholeFvTree.Findlist:
> + for TargetFv in FmmtParser.WholeFvTree.Findlist:
> + TargetFfsPad = TargetFv.Child[-1]
> + if TargetFfsPad.type == FFS_FREE_SPACE:
> +
> NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> new_ffs_data, TargetFfsPad.Data.HOffset)
> + else:
> +
> NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
> + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0],
> TargetFfsPad)
> + Status = FfsMod.AddFfs()
> + else:
> + print('Target Fv not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str,
outputfile: str,
> Fv_name: str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + with open(newffsfile, "rb") as f:
> + new_ffs_data = f.read()
> + newFmmtParser = FMMTParser(newffsfile, FV_TREE)
> + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree,
> new_ffs_data)
> + Status = False
> + # 3. Data Modify
> + new_ffs = newFmmtParser.WholeFvTree.Child[0]
> + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
> + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> FmmtParser.WholeFvTree.Findlist)
> + if Fv_name:
> + for item in FmmtParser.WholeFvTree.Findlist:
> + if item.Parent.key != Fv_name and
> item.Parent.Data.Name != Fv_name:
> + FmmtParser.WholeFvTree.Findlist.remove(item)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + for TargetFfs in FmmtParser.WholeFvTree.Findlist:
> + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0],
> TargetFfs)
> + Status = FfsMod.ReplaceFfs()
> + else:
> + print('Target Ffs not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> FmmtParser.WholeFvTree.Findlist)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + TargetNode = FmmtParser.WholeFvTree.Findlist[0]
> + TargetFv = TargetNode.Parent
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + TargetNode.Data.Header.State = c_uint8(
> + ~TargetNode.Data.Header.State)
> + FinalData = struct2stream(TargetNode.Data.Header) +
> TargetNode.Data.Data
> + with open(outputfile, "wb") as f:
> + f.write(FinalData)
> + else:
> + print('Target Ffs not found!!!')
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> new file mode 100644
> index 000000000000..6e54b860a9c9
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> @@ -0,0 +1,86 @@
> +## @file
> +# This file is used to define the interface of Bios Parser.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from PI.Common import *
> +from core.BinaryFactoryProduct import ParserEntry
> +from core.BiosTreeNode import *
> +from core.BiosTree import *
> +from core.GuidTools import *
> +
> +class FMMTParser:
> + def __init__(self, name: str, TYPE: str) -> None:
> + self.WholeFvTree = BIOSTREE(name)
> + self.WholeFvTree.type = TYPE
> + self.FinalData = b''
> + self.BinaryInfo = []
> +
> + ## Parser the nodes in WholeTree.
> + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'',
> Reloffset: int=0) -> None:
> + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type ==
> ROOT_FV_TREE:
> + ParserEntry().DataParser(self.WholeFvTree, whole_data,
> Reloffset)
> + else:
> + ParserEntry().DataParser(WholeFvTree, whole_data,
> Reloffset)
> + for Child in WholeFvTree.Child:
> + self.ParserFromRoot(Child, "")
> +
> + ## Encapuslation all the data in tree into self.FinalData
> + def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
> + # If current node is Root node, skip it.
> + if rootTree.type == ROOT_TREE or rootTree.type ==
> ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type ==
> ROOT_SECTION_TREE:
> + print('Start at Root !')
> + # If current node do not have Header, just add Data.
> + elif rootTree.type == BINARY_DATA or rootTree.type ==
> FFS_FREE_SPACE:
> + self.FinalData += rootTree.Data.Data
> + rootTree.Child = []
> + # If current node do not have Child and ExtHeader, just add its
> Header and Data.
> + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
> + self.FinalData += struct2stream(rootTree.Data.Header) +
> rootTree.Data.Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + if ParTree.type != 'ROOT':
> + self.FinalData += ParTree.Data.PadData
> + rootTree.Child = []
> + # If current node is not Section node and may have Child and
> ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data.
> + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or
> rootTree.type == SEC_FV_TREE:
> + if rootTree.HasChild():
> + self.FinalData += struct2stream(rootTree.Data.Header)
> + else:
> + self.FinalData += struct2stream(rootTree.Data.Header) +
> rootTree.Data.Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + if ParTree.type != 'ROOT':
> + self.FinalData += ParTree.Data.PadData
> + # If current node is Section, need to consider its ExtHeader,
Child
> and Compressed Status.
> + elif rootTree.type == SECTION_TREE:
> + # Not compressed section
> + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData !=
> b'' and CompressStatus):
> + if rootTree.HasChild():
> + if rootTree.Data.ExtHeader:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader)
> + else:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header)
> + else:
> + Data = rootTree.Data.Data
> + if rootTree.Data.ExtHeader:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> + else:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + self.FinalData += ParTree.Data.PadData
> + # If compressed section
> + else:
> + Data = rootTree.Data.OriData
> + rootTree.Child = []
> + if rootTree.Data.ExtHeader:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> + else:
> + self.FinalData +=
> struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + self.FinalData += ParTree.Data.PadData
> + for Child in rootTree.Child:
> + self.Encapsulation(Child, CompressStatus)
> diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py
> b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> new file mode 100644
> index 000000000000..f73f1fd65c07
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> @@ -0,0 +1,521 @@
> +## @file
> +# This file is used to the implementation of Bios layout handler.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +from core.BiosTree import *
> +from core.GuidTools import GUIDTools
> +from core.BiosTreeNode import *
> +from PI.Common import *
> +
> +EFI_FVB2_ERASE_POLARITY = 0x00000800
> +
> +def ChangeSize(TargetTree, size_delta: int=0) -> None:
> + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or
> type(TargetTree.Data.Header) == type(EFI_COMMON_SECTION_HEADER2()):
> + TargetTree.Data.Size -= size_delta
> + TargetTree.Data.Header.ExtendedSize -= size_delta
> + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
> + OriSize = TargetTree.Data.Header.SECTION_SIZE
> + OriSize -= size_delta
> + TargetTree.Data.Header.Size[0] = OriSize % (16**2)
> + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
> + TargetTree.Data.Header.Size[2] = OriSize // (16**4)
> + else:
> + TargetTree.Data.Size -= size_delta
> + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
> + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4)
> //(16**2)
> + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
> +
> +def ModifyFfsType(TargetFfs) -> None:
> + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and
> TargetFfs.Data.Size > 0xFFFFFF:
> + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
> + New_Header = EFI_FFS_FILE_HEADER2()
> + New_Header.Name = TargetFfs.Data.Header.Name
> + New_Header.IntegrityCheck =
> TargetFfs.Data.Header.IntegrityCheck
> + New_Header.Type = TargetFfs.Data.Header.Type
> + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> + New_Header.Size = 0
> + New_Header.State = TargetFfs.Data.Header.State
> + New_Header.ExtendedSize = ExtendSize
> + TargetFfs.Data.Header = New_Header
> + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> + TargetFfs.Data.HeaderLength =
> TargetFfs.Data.Header.HeaderLength
> + TargetFfs.Data.ModCheckSum()
> + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and
> TargetFfs.Data.Size <= 0xFFFFFF:
> + New_Header = EFI_FFS_FILE_HEADER()
> + New_Header.Name = TargetFfs.Data.Header.Name
> + New_Header.IntegrityCheck =
> TargetFfs.Data.Header.IntegrityCheck
> + New_Header.Type = TargetFfs.Data.Header.Type
> + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> + New_Header.Size = TargetFfs.Data.HeaderLength +
> TargetFfs.Data.Size
> + New_Header.State = TargetFfs.Data.Header.State
> + TargetFfs.Data.Header = New_Header
> + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> + TargetFfs.Data.HeaderLength =
> TargetFfs.Data.Header.HeaderLength
> + TargetFfs.Data.ModCheckSum()
> + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) ==
> EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
> + NeedChange = True
> + for item in TargetFfs.Parent.Child:
> + if type(item.Data.Header) ==
> type(EFI_FFS_FILE_HEADER2()):
> + NeedChange = False
> + if NeedChange:
> + TargetFfs.Parent.Data.Header.FileSystemGuid =
> ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> +
> + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> + TarParent = TargetFfs.Parent
> + while TarParent:
> + if TarParent.type == FV_TREE and
> struct2stream(TarParent.Data.Header.FileSystemGuid) ==
> EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
> + TarParent.Data.Header.FileSystemGuid =
> ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> + TarParent = TarParent.Parent
> +
> +class FvHandler:
> + def __init__(self, NewFfs, TargetFfs) -> None:
> + self.NewFfs = NewFfs
> + self.TargetFfs = TargetFfs
> + self.Status = False
> + self.Remain_New_Free_Space = 0
> +
> + ## Use for Compress the Section Data
> + def CompressData(self, TargetTree) -> None:
> + TreePath = TargetTree.GetTreePath()
> + pos = len(TreePath)
> + self.Status = True
> + while pos:
> + if self.Status:
> + if TreePath[pos-1].type == SECTION_TREE and
> TreePath[pos-1].Data.Type == 0x02:
> + self.CompressSectionData(TreePath[pos-1], None,
> TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
> + else:
> + if pos == len(TreePath):
> + self.CompressSectionData(TreePath[pos-1],
> pos)
> + else:
> + self.CompressSectionData(TreePath[pos-1],
> None)
> + pos -= 1
> +
> + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) ->
> None:
> + NewData = b''
> + temp_save_child = TargetTree.Child
> + if TargetTree.Data:
> + for item in temp_save_child:
> + if item.type == SECTION_TREE and not
> item.Data.OriData and item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
> + elif item.type == SECTION_TREE and item.Data.OriData
> and not item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) +
> item.Data.OriData + item.Data.PadData
> + elif item.type == SECTION_TREE and item.Data.OriData
> and item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) + item.Data.OriData +
> item.Data.PadData
> + elif item.type == FFS_FREE_SPACE:
> + NewData += item.Data.Data + item.Data.PadData
> + else:
> + NewData += struct2stream(item.Data.Header) +
> item.Data.Data + item.Data.PadData
> + if TargetTree.type == FFS_TREE:
> + New_Pad_Size = GetPadSize(len(NewData), 8)
> + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> + ChangeSize(TargetTree, -Size_delta)
> + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> New_Pad_Size
> + self.Remain_New_Free_Space += Delta_Pad_Size
> + TargetTree.Data.PadData = b'\xff' * New_Pad_Size
> + TargetTree.Data.ModCheckSum()
> + elif TargetTree.type == FV_TREE or TargetTree.type ==
> SEC_FV_TREE and not pos:
> + if self.Remain_New_Free_Space:
> + if TargetTree.Data.Free_Space:
> + TargetTree.Data.Free_Space +=
> self.Remain_New_Free_Space
> + NewData += self.Remain_New_Free_Space *
> b'\xff'
> + TargetTree.Child[-1].Data.Data +=
> self.Remain_New_Free_Space * b'\xff'
> + else:
> + TargetTree.Data.Data +=
> self.Remain_New_Free_Space * b'\xff'
> + New_Free_Space = BIOSTREE('FREE_SPACE')
> + New_Free_Space.type = FFS_FREE_SPACE
> + New_Free_Space.Data =
> FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
> + TargetTree.insertChild(New_Free_Space)
> + self.Remain_New_Free_Space = 0
> + if TargetTree.type == SEC_FV_TREE:
> + Size_delta = len(NewData) +
> self.Remain_New_Free_Space - len(TargetTree.Data.Data)
> + TargetTree.Data.Header.FvLength += Size_delta
> + TargetTree.Data.ModFvExt()
> + TargetTree.Data.ModFvSize()
> + TargetTree.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetTree)
> + TargetTree.Data.ModCheckSum()
> + elif TargetTree.type == SECTION_TREE and
> TargetTree.Data.Type != 0x02:
> + New_Pad_Size = GetPadSize(len(NewData), 4)
> + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> New_Pad_Size
> + self.Remain_New_Free_Space += Delta_Pad_Size
> + TargetTree.Data.PadData = b'\x00' *
> New_Pad_Size
> + TargetTree.Data.Data = NewData
> + if GuidTool:
> + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
")
> + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> + CompressedData = guidtool.pack(TargetTree.Data.Data)
> + if len(CompressedData) < len(TargetTree.Data.OriData):
> + New_Pad_Size = GetPadSize(len(CompressedData), 4)
> + Size_delta = len(CompressedData) -
> len(TargetTree.Data.OriData)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + TargetTree.Data.PadData = b'\x00' *
> New_Pad_Size
> + self.Remain_New_Free_Space =
> len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) -
> len(CompressedData) - New_Pad_Size
> + else:
> + TargetTree.Data.PadData = b''
> + self.Remain_New_Free_Space =
> len(TargetTree.Data.OriData) - len(CompressedData)
> + TargetTree.Data.OriData = CompressedData
> + elif len(CompressedData) == len(TargetTree.Data.OriData):
> + TargetTree.Data.OriData = CompressedData
> + elif len(CompressedData) > len(TargetTree.Data.OriData):
> + New_Pad_Size = GetPadSize(CompressedData, 4)
> + self.Remain_New_Free_Space = len(CompressedData) +
> New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData)
> + Size_delta = len(TargetTree.Data.OriData) -
> len(CompressedData)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + TargetTree.Data.PadData = b'\x00' *
> New_Pad_Size
> + TargetTree.Data.OriData = CompressedData
> + self.ModifyTest(TargetTree,
> self.Remain_New_Free_Space)
> + self.Status = False
> +
> + def ModifyFvExtData(self, TreeNode) -> None:
> + FvExtData = b''
> + if TreeNode.Data.Header.ExtHeaderOffset:
> + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
> + FvExtData += FvExtHeader
> + if TreeNode.Data.Header.ExtHeaderOffset and
> TreeNode.Data.ExtEntryExist:
> + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
> + FvExtData += FvExtEntry
> + if FvExtData:
> + InfoNode = TreeNode.Child[0]
> + InfoNode.Data.Data = FvExtData +
> InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
> + InfoNode.Data.ModCheckSum()
> +
> + def ModifyTest(self, ParTree, Needed_Space: int) -> None:
> + if Needed_Space > 0:
> + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
> + ParTree.Data.Data = b''
> + Needed_Space = Needed_Space -
> ParTree.Data.Free_Space
> + if Needed_Space < 0:
> + ParTree.Child[-1].Data.Data = b'\xff' *
> (-Needed_Space)
> + ParTree.Data.Free_Space = (-Needed_Space)
> + self.Status = True
> + else:
> + if ParTree.type == FV_TREE:
> + self.Status = False
> + else:
> + BlockSize =
> ParTree.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize -
> Needed_Space%BlockSize
> + if New_Add_Len % BlockSize:
> + ParTree.Child[-1].Data.Data = b'\xff' *
> New_Add_Len
> + ParTree.Data.Free_Space =
> New_Add_Len
> + Needed_Space += New_Add_Len
> + else:
> + ParTree.Child.remove(ParTree.Child[-1])
> + ParTree.Data.Free_Space = 0
> + ParTree.Data.Size += Needed_Space
> + ParTree.Data.Header.Fvlength =
> ParTree.Data.Size
> + for item in ParTree.Child:
> + if item.type == FFS_FREE_SPACE:
> + ParTree.Data.Data += item.Data.Data +
> item.Data.PadData
> + else:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + ParTree.Data.ModFvExt()
> + ParTree.Data.ModFvSize()
> + ParTree.Data.ModExtHeaderData()
> + self.ModifyFvExtData(ParTree)
> + ParTree.Data.ModCheckSum()
> + elif ParTree.type == FFS_TREE:
> + ParTree.Data.Data = b''
> + for item in ParTree.Child:
> + if item.Data.OriData:
> + if item.Data.ExtHeader:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.OriData + item.Data.PadData
> + else:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData
> + else:
> + if item.Data.ExtHeader:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.Data + item.Data.PadData
> + else:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + ChangeSize(ParTree, -Needed_Space)
> + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
> + Delta_Pad_Size = New_Pad_Size -
> len(ParTree.Data.PadData)
> + Needed_Space += Delta_Pad_Size
> + ParTree.Data.PadData = b'\xff' *
> GetPadSize(ParTree.Data.Size, 8)
> + ParTree.Data.ModCheckSum()
> + elif ParTree.type == SECTION_TREE:
> + OriData = ParTree.Data.Data
> + ParTree.Data.Data = b''
> + for item in ParTree.Child:
> + if item.type == SECTION_TREE and
> item.Data.ExtHeader and item.Data.Type != 0x02:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.Data + item.Data.PadData
> + elif item.type == SECTION_TREE and
> item.Data.ExtHeader and item.Data.Type == 0x02:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.OriData + item.Data.PadData
> + else:
> + ParTree.Data.Data +=
> struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
> + if ParTree.Data.Type == 0x02:
> + ParTree.Data.Size += Needed_Space
> + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
> + ToolPath = os.path.join(os.path.dirname(ParPath),
> r'FMMTConfig.ini')
> + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Sec
> tionDefinitionGuid))
> + CompressedData =
> guidtool.pack(ParTree.Data.Data)
> + Needed_Space = len(CompressedData) -
> len(ParTree.Data.OriData)
> + ParTree.Data.OriData = CompressedData
> + New_Size = ParTree.Data.HeaderLength +
> len(CompressedData)
> + ParTree.Data.Header.Size[0] = New_Size % (16**2)
> + ParTree.Data.Header.Size[1] = New_Size % (16**4)
> //(16**2)
> + ParTree.Data.Header.Size[2] = New_Size // (16**4)
> + if ParTree.NextRel:
> + New_Pad_Size = GetPadSize(New_Size, 4)
> + Delta_Pad_Size = New_Pad_Size -
> len(ParTree.Data.PadData)
> + ParTree.Data.PadData = b'\x00' *
> New_Pad_Size
> + Needed_Space += Delta_Pad_Size
> + else:
> + ParTree.Data.PadData = b''
> + elif Needed_Space:
> + ChangeSize(ParTree, -Needed_Space)
> + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
> + Delta_Pad_Size = New_Pad_Size -
> len(ParTree.Data.PadData)
> + Needed_Space += Delta_Pad_Size
> + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> + NewParTree = ParTree.Parent
> + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE,
> ROOT_SECTION_TREE, ROOT_TREE]
> + if NewParTree and NewParTree.type not in ROOT_TYPE:
> + self.ModifyTest(NewParTree, Needed_Space)
> + else:
> + self.Status = True
> +
> + def ReplaceFfs(self) -> bool:
> + TargetFv = self.TargetFfs.Parent
> + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child
> Ffs Header State need be reversed.
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + # NewFfs parsing will not calculate the PadSize, thus
recalculate.
> + self.NewFfs.Data.PadData = b'\xff' *
> GetPadSize(self.NewFfs.Data.Size, 8)
> + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size:
> + Needed_Space = self.NewFfs.Data.Size +
> len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> len(self.TargetFfs.Data.PadData)
> + # If TargetFv have enough free space, just move part of the
> free space to NewFfs.
> + if TargetFv.Data.Free_Space >= Needed_Space:
> + # Modify TargetFv Child info and BiosTree.
> + TargetFv.Child[-1].Data.Data = b'\xff' *
> (TargetFv.Data.Free_Space - Needed_Space)
> + TargetFv.Data.Free_Space -= Needed_Space
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + # Modify TargetFv Header and ExtHeader info.
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # return the Status
> + self.Status = True
> + # If TargetFv do not have enough free space, need move part
> of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> + else:
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + else:
> + # Recalculate TargetFv needed space to keep it
> match the BlockSize setting.
> + Needed_Space -= TargetFv.Data.Free_Space
> + BlockSize =
> TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize -
> Needed_Space%BlockSize
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + if New_Add_Len % BlockSize:
> + TargetFv.Child[-1].Data.Data = b'\xff' *
> New_Add_Len
> + TargetFv.Data.Free_Space = New_Add_Len
> + Needed_Space += New_Add_Len
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + TargetFv.Child.remove(self.TargetFfs)
> + else:
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.Data.Free_Space = 0
> + TargetFv.insertChild(self.NewFfs)
> + # Encapsulate the Fv Data for update.
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data +
> item.Data.PadData
> + else:
> + TargetFv.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + TargetFv.Data.Size += Needed_Space
> + # Modify TargetFv Data Header and ExtHeader info.
> + TargetFv.Data.Header.FvLength =
> TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # Start free space calculating and moving process.
> + self.ModifyTest(TargetFv.Parent, Needed_Space)
> + else:
> + New_Free_Space = self.TargetFfs.Data.Size -
> self.NewFfs.Data.Size
> + # If TargetFv already have free space, move the new free
> space into it.
> + if TargetFv.Data.Free_Space:
> + TargetFv.Child[-1].Data.Data += b'\xff' *
> New_Free_Space
> + TargetFv.Data.Free_Space += New_Free_Space
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + self.Status = True
> + # If TargetFv do not have free space, create free space for
Fv.
> + else:
> + New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
> + New_Free_Space_Tree.type = FFS_FREE_SPACE
> + New_Free_Space_Tree.Data = FfsNode(b'\xff' *
> New_Free_Space)
> + TargetFv.Data.Free_Space = New_Free_Space
> + TargetFv.insertChild(New_Free_Space)
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + self.Status = True
> + # Modify TargetFv Header and ExtHeader info.
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + return self.Status
> +
> + def AddFfs(self) -> bool:
> + # NewFfs parsing will not calculate the PadSize, thus
recalculate.
> + self.NewFfs.Data.PadData = b'\xff' *
> GetPadSize(self.NewFfs.Data.Size, 8)
> + if self.TargetFfs.type == FFS_FREE_SPACE:
> + TargetLen = self.NewFfs.Data.Size +
> len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> len(self.TargetFfs.Data.PadData)
> + TargetFv = self.TargetFfs.Parent
> + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY,
> Child Ffs Header State need be reversed.
> + if TargetFv.Data.Header.Attributes &
> EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + # If TargetFv have enough free space, just move part of the
> free space to NewFfs, split free space to NewFfs and new free space.
> + if TargetLen < 0:
> + self.Status = True
> + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
> + TargetFv.Data.Free_Space = (-TargetLen)
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + TargetFv.insertChild(self.NewFfs, -1)
> + ModifyFfsType(self.NewFfs)
> + elif TargetLen == 0:
> + self.Status = True
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs)
> + ModifyFfsType(self.NewFfs)
> + # If TargetFv do not have enough free space, need move part
> of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> + else:
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + elif TargetFv.type == SEC_FV_TREE:
> + # Recalculate TargetFv needed space to keep it
> match the BlockSize setting.
> + BlockSize =
> TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - TargetLen%BlockSize
> + if New_Add_Len % BlockSize:
> + self.TargetFfs.Data.Data = b'\xff' *
> New_Add_Len
> + self.TargetFfs.Data.Size = New_Add_Len
> + TargetLen += New_Add_Len
> + TargetFv.insertChild(self.NewFfs, -1)
> + TargetFv.Data.Free_Space = New_Add_Len
> + else:
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs)
> + TargetFv.Data.Free_Space = 0
> + ModifyFfsType(self.NewFfs)
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data +
> item.Data.PadData
> + else:
> + TargetFv.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + # Encapsulate the Fv Data for update.
> + TargetFv.Data.Size += TargetLen
> + TargetFv.Data.Header.FvLength =
> TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # Start free space calculating and moving process.
> + self.ModifyTest(TargetFv.Parent, TargetLen)
> + else:
> + # If TargetFv do not have free space, need directly move part
> of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> + TargetLen = self.NewFfs.Data.Size +
> len(self.NewFfs.Data.PadData)
> + TargetFv = self.TargetFfs.Parent
> + if TargetFv.Data.Header.Attributes &
> EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + elif TargetFv.type == SEC_FV_TREE:
> + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - TargetLen%BlockSize
> + if New_Add_Len % BlockSize:
> + New_Free_Space = BIOSTREE('FREE_SPACE')
> + New_Free_Space.type = FFS_FREE_SPACE
> + New_Free_Space.Data = FreeSpaceNode(b'\xff' *
> New_Add_Len)
> + TargetLen += New_Add_Len
> + TargetFv.Data.Free_Space = New_Add_Len
> + TargetFv.insertChild(self.NewFfs)
> + TargetFv.insertChild(New_Free_Space)
> + else:
> + TargetFv.insertChild(self.NewFfs)
> + ModifyFfsType(self.NewFfs)
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data +
> item.Data.PadData
> + else:
> + TargetFv.Data.Data +=
> struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + TargetFv.Data.Size += TargetLen
> + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + self.ModifyTest(TargetFv.Parent, TargetLen)
> + return self.Status
> +
> + def DeleteFfs(self) -> bool:
> + Delete_Ffs = self.TargetFfs
> + Delete_Fv = Delete_Ffs.Parent
> + Add_Free_Space = Delete_Ffs.Data.Size +
> len(Delete_Ffs.Data.PadData)
> + if Delete_Fv.Data.Free_Space:
> + if Delete_Fv.type == SEC_FV_TREE:
> + Used_Size = Delete_Fv.Data.Size -
> Delete_Fv.Data.Free_Space - Add_Free_Space
> + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> + New_Free_Space = BlockSize - Used_Size % BlockSize
> + self.Remain_New_Free_Space +=
> Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
> + Delete_Fv.Child[-1].Data.Data = New_Free_Space *
> b'\xff'
> + Delete_Fv.Data.Free_Space = New_Free_Space
> + else:
> + Used_Size = Delete_Fv.Data.Size -
> Delete_Fv.Data.Free_Space - Add_Free_Space
> + Delete_Fv.Child[-1].Data.Data += Add_Free_Space *
> b'\xff'
> + Delete_Fv.Data.Free_Space += Add_Free_Space
> + New_Free_Space = Delete_Fv.Data.Free_Space +
> Add_Free_Space
> + else:
> + if Delete_Fv.type == SEC_FV_TREE:
> + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> + New_Free_Space = BlockSize - Used_Size % BlockSize
> + self.Remain_New_Free_Space += Add_Free_Space -
> New_Free_Space
> + Add_Free_Space = New_Free_Space
> + else:
> + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> + New_Free_Space = Add_Free_Space
> + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
> + New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
> + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
> + New_Ffs_Tree.type = FFS_FREE_SPACE
> + New_Ffs_Tree.Data = New_Free_Space_Info
> + Delete_Fv.insertChild(New_Ffs_Tree)
> + Delete_Fv.Data.Free_Space = Add_Free_Space
> + Delete_Fv.Child.remove(Delete_Ffs)
> + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
> + Delete_Fv.Data.ModFvExt()
> + Delete_Fv.Data.ModFvSize()
> + Delete_Fv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(Delete_Fv)
> + Delete_Fv.Data.ModCheckSum()
> + self.CompressData(Delete_Fv)
> + self.Status = True
> + return self.Status
> diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py
> b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> new file mode 100644
> index 000000000000..e21d8e0406ae
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> @@ -0,0 +1,152 @@
> +## @file
> +# This file is used to define the FMMT dependent external tool management
> class.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import glob
> +import logging
> +import os
> +import shutil
> +import sys
> +import tempfile
> +import uuid
> +from PI.Common import *
> +from utils.FmmtLogger import FmmtLogger as logger
> +import subprocess
> +
> +def ExecuteCommand(cmd: list) -> None:
> + subprocess.run(cmd,stdout=subprocess.DEVNULL)
> +
> +class GUIDTool:
> + def __init__(self, guid: str, short_name: str, command: str) -> None:
> + self.guid: str = guid
> + self.short_name: str = short_name
> + self.command: str = command
> +
> + def pack(self, buffer: bytes) -> bytes:
> + """
> + compress file.
> + """
> + tool = self.command
> + if tool:
> + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> + ToolInputFile = os.path.join(tmp,
> "pack_uncompress_sec_file")
> + ToolOuputFile = os.path.join(tmp, "pack_sec_file")
> + try:
> + file = open(ToolInputFile, "wb")
> + file.write(buffer)
> + file.close()
> + command = [tool, '-e', '-o', ToolOuputFile,
> + ToolInputFile]
> + ExecuteCommand(command)
> + buf = open(ToolOuputFile, "rb")
> + res_buffer = buf.read()
> + except Exception as msg:
> + logger.error(msg)
> + return ""
> + else:
> + buf.close()
> + if os.path.exists(tmp):
> + shutil.rmtree(tmp)
> + return res_buffer
> + else:
> + logger.error(
> + "Error parsing section: EFI_SECTION_GUID_DEFINED
> cannot be parsed at this time.")
> + logger.info("Its GUID is: %s" % self.guid)
> + return ""
> +
> +
> + def unpack(self, buffer: bytes) -> bytes:
> + """
> + buffer: remove common header
> + uncompress file
> + """
> + tool = self.command
> + if tool:
> + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> + ToolInputFile = os.path.join(tmp, "unpack_sec_file")
> + ToolOuputFile = os.path.join(tmp,
> "unpack_uncompress_sec_file")
> + try:
> + file = open(ToolInputFile, "wb")
> + file.write(buffer)
> + file.close()
> + command = [tool, '-d', '-o', ToolOuputFile,
ToolInputFile]
> + ExecuteCommand(command)
> + buf = open(ToolOuputFile, "rb")
> + res_buffer = buf.read()
> + except Exception as msg:
> + logger.error(msg)
> + return ""
> + else:
> + buf.close()
> + if os.path.exists(tmp):
> + shutil.rmtree(tmp)
> + return res_buffer
> + else:
> + logger.error("Error parsing section:
> EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
> + logger.info("Its GUID is: %s" % self.guid)
> + return ""
> +
> +class GUIDTools:
> + '''
> + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools
> and provide interfaces to access those tools.
> + '''
> + default_tools = {
> +
> struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779
> ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO",
> "TianoCompress"),
> +
> struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf
> ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA",
> "LzmaCompress"),
> +
> struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083
> ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32",
> "GenCrc32"),
> +
> struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889
> ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86",
> "LzmaF86Compress"),
> +
> struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")
> ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI",
> "BrotliCompress"),
> + }
> +
> + def __init__(self, tooldef_file: str=None) -> None:
> + self.dir = os.path.dirname(__file__)
> + self.tooldef_file = tooldef_file if tooldef_file else
os.path.join(
> + self.dir, "FMMTConfig.ini")
> + self.tooldef = dict()
> + self.load()
> +
> + def VerifyTools(self) -> None:
> + """
> + Verify Tools and Update Tools path.
> + """
> + path_env = os.environ.get("PATH")
> + path_env_list = path_env.split(os.pathsep)
> + path_env_list.append(os.path.dirname(__file__))
> + path_env_list = list(set(path_env_list))
> + for tool in self.tooldef.values():
> + cmd = tool.command
> + if os.path.isabs(cmd):
> + if not os.path.exists(cmd):
> + print("Tool Not found %s" % cmd)
> + else:
> + for syspath in path_env_list:
> + if glob.glob(os.path.join(syspath, cmd+"*")):
> + break
> + else:
> + print("Tool Not found %s" % cmd)
> +
> + def load(self) -> None:
> + if os.path.exists(self.tooldef_file):
> + with open(self.tooldef_file, "r") as fd:
> + config_data = fd.readlines()
> + for line in config_data:
> + try:
> + guid, short_name, command = line.split()
> + new_format_guid =
> struct2stream(ModifyGuidFormat(guid.strip()))
> + self.tooldef[new_format_guid] = GUIDTool(
> + guid.strip(), short_name.strip(),
> command.strip())
> + except:
> + print("GuidTool load error!")
> + continue
> + else:
> + self.tooldef.update(self.default_tools)
> +
> + self.VerifyTools()
> +
> + def __getitem__(self, guid) -> None:
> + return self.tooldef.get(guid)
> +
> +
> +guidtools = GUIDTools()
> diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> new file mode 100644
> index 000000000000..18f0cff96e4b
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> @@ -0,0 +1,18 @@
> +## @file
> +# This file is used to define the Fmmt Logger.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +##
> +
> +import logging
> +import sys
> +
> +FmmtLogger = logging.getLogger('FMMT')
> +FmmtLogger.setLevel(logging.INFO)
> +
> +lh=logging.StreamHandler(sys.stdout)
> +lf=logging.Formatter("%(levelname)-8s: %(message)s")
> +lh.setFormatter(lf)
> +FmmtLogger.addHandler(lh)
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> new file mode 100644
> index 000000000000..1a6c67056266
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> @@ -0,0 +1,54 @@
> +## @file
> +# This file is used to define the printer for Bios layout.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +def GetFormatter(layout_format: str):
> + if layout_format == 'json':
> + return JsonFormatter()
> + elif layout_format == 'yaml':
> + return YamlFormatter()
> + elif layout_format == 'html':
> + return HtmlFormatter()
> + else:
> + return TxtFormatter()
> +
> +class Formatter(object):
> + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
> + raise NotImplemented
> +
> +class JsonFormatter(Formatter):
> + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
str=None) ->
> None:
> + try:
> + import json
> + except:
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> + return
> + print(outputfile)
> + if outputfile:
> + with open(outputfile,"w") as fw:
> + json.dump(layoutdict, fw, indent=2)
> + else:
> + print(json.dumps(layoutdict,indent=2))
> +
> +class TxtFormatter(Formatter):
> + def LogPrint(self,layoutlist: list) -> None:
> + for item in layoutlist:
> + print(item)
> + print('\n')
> +
> + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
str=None) ->
> None:
> + print(outputfile)
> + with open(outputfile, "w") as f:
> + for item in layoutlist:
> + f.writelines(item + '\n')
> +
> +class YamlFormatter(Formatter):
> + def dump(self,layoutdict, layoutlist, outputfile = None):
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> +
> +class HtmlFormatter(Formatter):
> + def dump(self,layoutdict, layoutlist, outputfile = None):
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> \ No newline at end of file
> --
> 2.27.0.windows.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming
@ 2021-12-06 8:34 ` Yuwei Chen
2021-12-06 9:44 ` 回复: " gaoliming
0 siblings, 1 reply; 6+ messages in thread
From: Yuwei Chen @ 2021-12-06 8:34 UTC (permalink / raw)
To: devel@edk2.groups.io, gaoliming@byosoft.com.cn; +Cc: Feng, Bob C
Hi Liming,
Need your helps on the first and third issues:
1. As the PI spec defined, for Fv Header "The first 16 bytes are reserved to allow for the reset vector of processors whose reset vector is at address 0." The FVSEC.Fv generated did not follow the Spec definition, is this the issue of GenFv or FMMT, are there any references for this issue?
3. The PEIM rebase way follows which rules?
Thanks,
Christine (Yuwei)
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> gaoliming
> Sent: Friday, December 3, 2021 11:19 AM
> To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>
> Cc: Feng, Bob C <bob.c.feng@intel.com>
> Subject: 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
>
> Yuwei:
> I did some test and meet three problems. I submit BZ
> https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check.
>
> Thanks
> Liming
> > -----邮件原件-----
> > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen
> > 发送时间: 2021年12月1日 9:29
> > 收件人: devel@edk2.groups.io
> > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>
> > 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
> >
> > The FMMT python tool is used for firmware files operation, which has
> > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function:
> >
> > 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files)
> > 2.Add a new FFS into a FV file (both included in a FD file or not)
> > 3.Replace an FFS in a FV file with a new FFS file
> > 4.Delete an FFS in a FV file (both included in a FD file or not)
> > 5.Extract the FFS from a FV file (both included in a FD file or not)
> >
> > Currently the FMMT C tool is saved in edk2-staging repo, but its
> > quality and coding style can't meet the Edk2 quality, which is hard to
> > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
> >
> > The new Python version keeps same functions with origin C version. It
> > has higher quality and better coding style, and it is much easier to
> > extend new functions and to maintain.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847
> > PR Link: https://github.com/tianocore/edk2-basetools/pull/12
> > RFC Link: https://edk2.groups.io/g/devel/message/82877
> > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
> >
> > Cc: Bob Feng <bob.c.feng@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
> > ---
> > V4 fixed the Linux file format issue and known bugs.
> > BaseTools/BinWrappers/PosixLike/FMMT | 14 +
> > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
> > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
> > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 +
> > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
> > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes
> > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
> > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++
> > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++
> > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++
> > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
> > BaseTools/Source/Python/FMMT/README.md | 180 ++++++
> > BaseTools/Source/Python/FMMT/__init__.py | 0
> > .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
> > BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++
> > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
> > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
> > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++
> > .../Source/Python/FMMT/core/FvHandler.py | 521
> > ++++++++++++++++++
> > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++
> > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
> > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
> > 22 files changed, 2432 insertions(+)
> > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
> > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
> > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > create mode 100644
> > BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > create mode 100644
> > BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
> > create mode 100644 BaseTools/Source/Python/FMMT/README.md
> > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
> > create mode 100644
> > BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
> > create mode 100644
> > BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > create mode 100644
> > BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > create mode 100644
> > BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> >
> > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT
> > b/BaseTools/BinWrappers/PosixLike/FMMT
> > new file mode 100644
> > index 000000000000..5f5519e1e1b6
> > --- /dev/null
> > +++ b/BaseTools/BinWrappers/PosixLike/FMMT
> > @@ -0,0 +1,14 @@
> > +#!/usr/bin/env bash
> > +#python `dirname $0`/RunToolFromSource.py `basename $0` $*
> > +
> > +# If a ${PYTHON_COMMAND} command is available, use it in preference
> to
> > python
> > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
> > + python_exe=${PYTHON_COMMAND}
> > +fi
> > +
> > +full_cmd=${BASH_SOURCE:-$0} # see
> > http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not
> a
> > good choice here
> > +dir=$(dirname "$full_cmd")
> > +cmd=${full_cmd##*/}
> > +
> > +export
> >
> PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY
> > THONPATH:+:"$PYTHONPATH"}"
> > +exec "${python_exe:-python}" -m $cmd.$cmd "$@"
> > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > new file mode 100644
> > index 000000000000..f0551c4ac54a
> > --- /dev/null
> > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > @@ -0,0 +1,4 @@
> > +@setlocal
> > +@set ToolName=%~n0%
> > +@set
> >
> PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA
> > SE_TOOLS_PATH%\Source\Python\FMMT
> > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
> > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py
> > b/BaseTools/Source/Python/FMMT/FMMT.py
> > new file mode 100644
> > index 000000000000..5028d8446ee0
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/FMMT.py
> > @@ -0,0 +1,117 @@
> > +# @file
> > +# Firmware Module Management Tool.
> > +#
> > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +# Import Modules
> > +#
> > +import argparse
> > +import sys
> > +from core.FMMTOperation import *
> > +
> > +parser = argparse.ArgumentParser(description='''
> > +View the Binary Structure of FD/FV/Ffs/Section, and
> > Delete/Extract/Add/Replace a Ffs from/into a FV.
> > +''')
> > +parser.add_argument("--version", action="version", version='%(prog)s
> > Version 1.0',
> > + help="Print debug information.")
> > +parser.add_argument("-v", "--View", dest="View", nargs='+',
> > + help="View each FV and the named files within
> > each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
> > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
> > + help="Delete a Ffs from FV: '-d inputfile
> > TargetFfsName outputfile TargetFvName(Optional,\
> > + If not given, wil delete all the existed target
> Ffs)'")
> > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
> > + help="Extract a Ffs Info: '-e inputfile TargetFfsName
> > outputfile'")
> > +parser.add_argument("-a", "--Add", dest="Add", nargs='+',
> > + help="Add a Ffs into a FV:'-a inputfile
> > TargetFvName newffsfile outputfile'")
> > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
> > + help="Replace a Ffs in a FV: '-r inputfile
> > TargetFfsName newffsfile outputfile TargetFvName(Optional,\
> > + If not given, wil replace all the existed target
> > Ffs with new Ffs file)'")
> > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
> > + help="The format of log file which saves Binary
> > layout. Currently supports: json, txt. More formats will be added in the
> > future")
> > +
> > +def print_banner():
> > + print("")
> > +
> > +class FMMT():
> > + def __init__(self) -> None:
> > + self.firmware_packet = {}
> > +
> > + def CheckFfsName(self, FfsName:str) -> str:
> > + try:
> > + return uuid.UUID(FfsName)
> > + except:
> > + return FfsName
> > +
> > + def View(self, inputfile: str, logfiletype: str=None, outputfile:
> str=None) ->
> > None:
> > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
> > + filetype = os.path.splitext(inputfile)[1].lower()
> > + if filetype == '.fd':
> > + ROOT_TYPE = ROOT_TREE
> > + elif filetype == '.fv':
> > + ROOT_TYPE = ROOT_FV_TREE
> > + elif filetype == '.ffs':
> > + ROOT_TYPE = ROOT_FFS_TREE
> > + elif filetype == '.sec':
> > + ROOT_TYPE = ROOT_SECTION_TREE
> > + else:
> > + ROOT_TYPE = ROOT_TREE
> > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
> > +
> > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile:
> str,
> > Fv_name: str=None) -> None:
> > + if Fv_name:
> > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> > outputfile, uuid.UUID(Fv_name))
> > + else:
> > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> > outputfile)
> > +
> > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) ->
> None:
> > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
> > +
> > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str,
> outputfile: str) ->
> > None:
> > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile,
> > outputfile)
> > +
> > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str,
> outputfile:
> > str, Fv_name: str=None) -> None:
> > + if Fv_name:
> > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
> newffsfile,
> > outputfile, uuid.UUID(Fv_name))
> > + else:
> > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
> newffsfile,
> > outputfile)
> > +
> > +
> > +def main():
> > + args=parser.parse_args()
> > + status=0
> > +
> > + try:
> > + fmmt=FMMT()
> > + if args.View:
> > + if args.LogFileType:
> > + fmmt.View(args.View[0], args.LogFileType[0])
> > + else:
> > + fmmt.View(args.View[0])
> > + if args.Delete:
> > + if len(args.Delete) == 4:
> > +
> > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
> > + else:
> > +
> > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
> > + if args.Extract:
> > + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
> > + if args.Add:
> > + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
> > + if args.Replace:
> > + if len(args.Replace) == 5:
> > +
> >
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> > 3],args.Replace[4])
> > + else:
> > +
> >
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> > 3])
> > + # TODO:
> > + '''Do the main work'''
> > + except Exception as e:
> > + print(e)
> > +
> > + return status
> > +
> > +
> > +if __name__ == "__main__":
> > + exit(main())
> > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > new file mode 100644
> > index 000000000000..aa2444f11b38
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > @@ -0,0 +1,11 @@
> > +## @file
> > +# This file is used to define the FMMT dependent external tool guid.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
> > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
> > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
> > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
> > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
> > diff --git
> a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..7cc806a0133413a4aa037
> > f1d43d80000546a5246
> > GIT binary patch
> > literal 29515
> > zcmcG$bySpZzxIs{h;*kQ-
> QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+
> > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@-
> mueX!oILX!ky#
> > KL)-b
> >
> z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx
> > mKL
> > z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K
> > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A-
> ~0
> > Os
> > zomQa`7xm?Vn1W*P-%s-
> jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK
> > u0
> > zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{)
> > abe
> > z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He
> > 5*9B
> > z*-Jfk;((ApOh<DBpW00KVT-
> d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_
> > e
> > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU-
> u*mWM
> > w)
> >
> zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK
> > !@Kal=
> >
> zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04
> > 1
> >
> z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^
> > W
> > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy-
> 4#Vx^C$n*R(S2#<fkNRn8K6C!26<
> > O
> > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<-
> BdBP<AmFX)1
> > _0^
> > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt-
> C5{L_
> >
> zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@
> > YoAv$
> > zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o%
> >
> z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT
> > oZlL
> > z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk`
> > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@-
> nrRU
> >
> zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr
> > k
> > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX-
> Sd(_WJqP_|B0b^CxF|AoL+M;CA
> > Vm
> >
> zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT
> +
> > 5
> >
> z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu
> > D}JIY
> >
> zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY
> > y
> > z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk
> > znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h
> > W653
> > zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz
> > z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8
> > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B-
> 8MDTh)0*RC#EN#u!^
> > nVH$m
> > zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd
> > m$
> >
> zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^|
> > 1l
> > zs#*3J+AHPINX8;)QiLwy6-Z2S$&-
> jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep
> >
> z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l
> > As
> > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$-
> *{a=n
> > ?K!V
> > zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb}
> > rWM
> > zKu}~4YZm`$e$42-
> HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k
> > sy
> >
> z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU
> > CN$
> >
> z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG
> > |Lx3X6
> >
> zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt
> > P
> > z4}!3MY9t1~*EvD4lR~M)=-
> uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P!
> >
> zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b
> > 3+@WmhX
> > z>ZGUkb+ts3Tk&n$W-
> n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C
> > Qkvs@
> > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)-
> !o_k?1CJInjgyPOhp1A%MDgUMftCS$J~
> > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA-
> 1pvp;SGObla#%wB7pN+^fnJc#a?jT)B
> > 8
> > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&-
> l~CT@#e0@&
> > vmX7
> > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*-
> 7<1UbT|>O|@l;?iY=`N4
> > z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*%
> > zg_$H!-
> &YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW
> >
> z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^(
> > F<T-(}
> >
> zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy`
> > TJt!CY
> > zZezN}4wz=94~>e){&{8Z-
> !pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c
> > PC
> >
> z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4|
> > bv
> >
> zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb
> > HJ6Kn
> > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78-
> 3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq
> > ;E
> > zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9
> > uN5=1
> >
> z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu
> > S
> >
> zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D
> > p?;
> > zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)%
> >
> zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw
> > Z%2
> > z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl;
> > utt
> > z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5
> > W0`!
> >
> z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59
> > {es93C0D
> > zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@>
> > 3g{x5
> > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^-
> 1kaKB+d7T
> > Drx2
> >
> ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB
> > (wX
> > zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u?
> > 3XkOqt
> >
> zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX
> > DU
> > z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy
> > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y-
> oCVYo9xaw1S?6YWT`9V^=h<QFr
> > Q}
> > zHAIHMg-
> ^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0
> > NyW
> > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t-
> !imMfLU8CUGd)w
> > ^
> >
> zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ
> > L
> > zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j}
> > *
> > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r-
> rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb
> > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ-
> ?%k;$V^R5XclbB
> > !ZjD
> > zt=UY&?7-X9<AFk^dEO%~_#P&-
> r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(=
> > tOwMb
> >
> z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0
> > lL_
> >
> z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+
> > YC
> >
> zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc
> > OCnX
> > za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss
> > @v
> > zSgaMn{Kb=7It4nMlG8iA*-
> tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH
> > Y<UT
> >
> zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M
> > y7^
> >
> zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf
> > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS-
> w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR
> > A2ii
> >
> z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB
> > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V-
> {XCZzitML(}hGq&W
> >
> zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q
> > zeC@D`Bk`qD-
> *FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS
> > bRs
> >
> zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw
> >
> z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0
> >
> zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9<
> > 3
> >
> zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO
> > 7{FtVq
> > zO<`-
> jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT
> > -Ie5
> >
> z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg
> > u
> >
> zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV
> > aGRj!
> >
> z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D
> > h
> > z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o
> > M(_fvkH
> > zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY
> > $
> > z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H
> > @@5TTQn
> > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|-
> *^dW
> > 5
> > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG-
> =t3xx
> > w9x1s>
> > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)-
> ^X=?*fdvD
> > OD
> > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ-
> h^Vc`*v)kGJbP?dUI5
> > #x
> >
> z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o
> > S
> >
> zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5
> > sA
> >
> zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A
> > -H_
> >
> zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq
> > Cg}S
> > zLrkk-
> #H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB
> > $or-
> >
> z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{
> > }W
> >
> zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo
> > wW$
> > znAFU~_wY4f2q?dP-
> TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D
> > &U93
> > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>-
> &vpdCAooZEI#
> > wk{a
> > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T)
> >
> z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c#
> > ~d
> >
> zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt
> > z0zq
> > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5-
> iu6O
> > P@(+
> > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p-
> UTYHHHGHJ
> > a^R
> > z4e9LSAJ3h-
> L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR
> >
> zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO<
> > C
> > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B-
> aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad
> > u
> > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<-
> CE_@x)deTU#?kEtpbb>pf
> > JQ
> > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#-
> <B(*%Baj
> > w8bG
> >
> z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4
> > pUp
> > z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j
> > kUEqfGQeE
> > zsxs)ys+*k-
> a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j
> >
> zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G*
> > Aw_D
> > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb-
> 9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1
> > D
> >
> z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7
> > X^
> >
> zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe
> > pj>)
> >
> z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID<
> > <
> >
> z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(`
> > 3v
> >
> zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@
> > Y8EQ
> > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>-
> &_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar
> > }<t
> >
> zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+
> > -Xd
> > zF@iS2N;c?&GGNFv1f-
> nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF
> > lqL!
> >
> z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$
> >
> zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M
> > TTEJ1
> > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+-
> iRa;O_hx8v1
> > pM
> >
> zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ
> > i-E
> > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{-
> <qQVg#k>78
> > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#-
> fvwHu8795}6
> > W
> >
> z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-`
> > X2@$m4(
> >
> zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r
> > A*%
> > zYs#3InBRHdV-
> hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L
> >
> zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09
> > 9|n
> >
> zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@
> > u
> > zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6%
> > Ib
> > zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU
> > *R)a;LqQ
> >
> zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w
> > vUtt
> > zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c
> > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE-
> {)&!(C4TBm|f@H
> > Qxf
> >
> zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx
> > &
> > zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%=
> > WmbM0
> > z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl-
> q3
> > 6
> > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6-
> LubB
> > c
> > z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha
> >
> zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh
> > g
> > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$
> >
> z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB
> > k2bs
> >
> zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#(
> > t_TQ<~
> > zPpkWLsyFv=kpB8wMCMJ461d6-
> pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB
> > WqSJV
> > zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u
> > w9Z
> > zIQm^k)g4d<<I-`XDjPImuOoV3k-
> fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@
> > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ-
> q&>D;Lu4Y*65q
> > 0=*^{N
> >
> zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT
> > bF
> >
> ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv<
> >
> z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv
> > L
> >
> zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5
> > g^7sU
> > zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*>
> > 4
> >
> zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t`
> > !
> > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$-
> 5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In
> > Z;K
> > z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u=
> > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H-
> JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V
> > J)p
> > zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3#
> > MZ@o
> > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G-
> ;I<V5t?h0H4ZJmY{X!kNZmp3
> > lj
> > zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo#
> > 0G7mqVU
> >
> zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx|
> > C^
> > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os-
> Y*<Arj
> > @T
> >
> zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U
> > zv&u^91`JfQ*$6*pQVC-
> u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z
> > T
> > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB-
> Dh>thr$2oA7josXpNOr1+
> > 57
> >
> z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~
> > zUK--
> r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd
> > V-z
> >
> zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY
> > VB&
> > zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w*
> > oz
> > z@o`0!-
> ;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe`
> > m
> > zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B-
> {
> > Y
> > z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T
> > nb329
> > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY-
> w@fzc7$VQ4tNhm5V8N(S
> > dPS
> > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8-
> C&&+<Zy65#V5
> >
> z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw
> > hf!j
> > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j-
> W2=miHT
> > no
> > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1-
> qeL<q;^=2F}
> > T|
> >
> zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC
> > pwM(WO
> > z`0>B1JR`+)ZDiuFC!F7Fv-
> o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF
> > =-
> >
> zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP
> > (nm$
> > zgn7NXKD%P4(&M*qR-
> (Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c
> > <p
> > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av-
> 4<bCdT@wTC>GBy~|DLthW;7TX
> > boX
> > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C-
> ixZ#a}(P
> > %71
> > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg-
> Xm`x2Xg
> > z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA
> > qe
> >
> z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4
> > z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8
> > z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH
> > T-
> > zH|7YArh@+FLkg-
> WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3
> > UO`cs
> >
> zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB)
> > 0
> >
> zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25
> > zwYj@;E^4?Qbs%M^x|g>zUX-
> moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A!
> > IRJo
> > zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL
> > wpm5C
> > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd-
> 6Ob;XHAbX$!ujWY~NcR
> > 9fz?
> > zA{m&^E5y==&`JNCtrsVh*i&iF-
> ?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj
> > mI
> > zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r
> > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi-
> 6N<6qBRAbW>R|5Yvc<6M7$K
> > w`6V
> > zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2
> > q4`
> >
> z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^
> > |E7=&
> > zinFr&rqO5i{Cmn-
> mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U
> > ab
> > zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO
> >
> zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw
> > n>R7
> > zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc#
> > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)-
> %FkT
> > XOBB
> >
> zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`&
> > uLj
> >
> zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({|
> > *p
> > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X-
> Z#BGRQr2o
> > aKQ
> >
> zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt(
> > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q-
> =mGP;tP2mL@wi(xnoq6<%Cb76W9}f
> > Ny@K
> >
> zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O
> > pL)Fq>4
> >
> zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf
> > Mt
> > z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@
> > @Yi
> >
> zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v
> > E`
> > zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u
> > Q@)u
> >
> zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4
> > PQQA
> > z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4
> > ~<o<8e
> >
> zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D
> > <J
> >
> z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F`
> > F4&
> >
> zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb
> > E5
> >
> z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z
> > #~g=O
> > zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k
> > e1
> > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi-
> O@I~^x{;?=(JqlKKAP)z9
> > zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF%
> > *F9!4P^
> > zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N)
> > x`
> >
> zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82#
> > hx6wR
> > z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp%
> > FUzQ
> >
> zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb
> > 4G2Su$
> > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&-
> TpdZ4Sm%Z^!(mu%Q
> > -d6
> > z8CSq{iA^TAM+Sba`K-
> HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd
> > qw
> > z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci
> > zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;>
> > m
> >
> zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW
> > DlU4VKO$Q7#
> >
> zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF
> > m!6A
> > z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s
> > 2
> >
> zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq
> > uX
> >
> zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b
> > URoM
> > z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T;
> > dh
> > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b-
> +I~rxJ^NTX^hUZQ_xQHPN@RYRbv=
> > OAaP0<
> >
> z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv
> > Yry
> > zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls>
> > &a*
> > z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8-
> K
> > z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m
> > zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j
> > >
> >
> zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW
> > d@XHe
> > zvn*f~#Zp|_nC%d-
> |J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`<
> > x-t
> >
> zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc
> > ny<
> > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d-
> chHgloB
> > Wr|bA
> > zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v
> >
> z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH
> > y
> >
> z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ
> > u7Dn
> > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_-
> YI>c&n(Yp>Lyir
> > ~@
> > zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-<
> > h!%=
> > z*&>EVOnq&ad$05T2-
> 6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7
> > Tcf_kK
> > zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve
> > HMi
> > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?-
> }0}e(EkUQx{gt5Qv2GI}9K
> > s
> >
> z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~
> > |
> > zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y
> > *YvY
> > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW-
> `VxgtihK5w!+4bR%e5W4fcRUBu
> > t}=3
> > z-
> )H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*&
> > MCZ
> > zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&-
> > zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}#
> > (sm;
> >
> zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzc
> E
> > -_;{w
> >
> zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0
> > R!C
> >
> z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h
> > o5lF
> >
> z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+
> > &#`
> >
> zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD-
> > m$*V
> >
> zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt
> > a
> >
> zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+&
> > `~cD
> > zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@>
> > U5(
> > zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#>
> > i8(
> > zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV
> > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ
> >
> zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw
> > JY7J-w
> >
> zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^
> > NQcQ
> > zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~
> >
> z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o
> > m
> > zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y
> > C
> > z<!BcWm*#gI)Q;$>P(-
> ^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$
> > VQ0FW
> > zGH;^fyr(a?>xrm&;uh2hKqp>D-
> AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7
> > aZ
> > ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z?
> > !Ajpt
> >
> z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha
> > 7z
> >
> z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ
> > @Ox
> >
> zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0
> > l
> > zVjM=Qw37|BK0|)-
> NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj
> > z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II
> > Uz
> > zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt}
> > MtL
> > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr-
> NH4*=bhL7Tc<AKzmQSP`%KB$^O6d
> > paf~!
> > zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE-
> 1A
> > zv1;CZ!z3UqKTUkaP--
> mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw*
> > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO-
> t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs
> > Eg
> > z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$
> > ^*M}
> >
> zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v
> >
> z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr
> > Z?;v@B
> > zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_
> > zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb)
> > OG
> >
> z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK
> > n{X
> >
> z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1
> > pZ%wkIe6
> >
> zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY-
> > pR
> > zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75!
> > sSCv
> > zOI0V)+9b%8^ak8NWz6d-
> k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW&
> > !*&3(
> > zh6=X0QmwWX9XHj5l1@tYGXVhG)-
> Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+
> > HQzlwT
> > z8x|ZZV|V(-
> wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH
> > Psf
> >
> z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs
> > s8V7
> > z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj
> > z5_5g=+O$i$k;%-
> 1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO
> > 5%a
> > z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z-
> > qZ)Dr
> >
> z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E
> > NpfA
> > zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0
> > zd*)2v-
> xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k
> > XtIl50
> >
> zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F
> > Um
> > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}-
> _g|Ab91$j2ad2jnt
> > +=M
> >
> znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg
> >
> zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY
> > QmA
> >
> zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf
> > HM#
> > zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5
> > VI=
> > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL-
> `KrNzBi@nX
> > eF
> >
> z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r
> > ;!F
> > z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t
> > xQ
> >
> z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y|
> > p
> >
> zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e
> > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp-
> =DEZ9aDLwe&emQpH(ng8O8f|
> > N|b
> >
> zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO
> > -%SX
> > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm-
> Et@op
> > ^sZ
> >
> z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW
> > 5K
> >
> zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes
> > )B
> > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o-
> 9JRkFbj^Cvi9
> > l63
> >
> z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v
> > +d4T
> >
> z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^
> > `QF}Y
> > zTI!eAjaQV1M2^`)i<P>gsTGz-
> UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew<
> > 3
> > z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V
> > mt<0
> >
> zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^
> > +
> > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=-
> Jy}m
> > Zu
> > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^-
> &~y
> > sjCF
> > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC-
> gE$~l!e
> > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^-
> Xvwp0G$Ypd!Rc|ZQdfy
> > )>q
> > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d-
> LF2U(
> > N;ve
> > z`|0v08lJhE-
> 43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK|
> > T
> >
> z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`(
> > m
> > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<-
> L*AxFh1pz<SsamItVw$U*
> > KSpI
> > z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ
> > G;
> >
> zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G
> > iy|~
> > z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw>
> > 1jO
> > zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR
> > ~#6
> >
> z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W
> > ;)#
> > zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb
> > z$n8i2c(^-
> EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN
> > 9%7z
> > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J-
> iap7Ma
> > 7+~R
> > zr)wN#;gC`Q+R-
> b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7
> > sn
> > zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw
> > HK
> >
> zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz
> > zM
> > zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c*
> > wq)=
> >
> z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF
> > S*
> >
> z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk-
> > _@X*
> >
> za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~
> > I4
> > zMe~hi*!yt-
> e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW
> > B@
> >
> ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z
> > aMs11
> > zN|%vFr}N@XKRz-
> JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW&
> > XA7Ak
> > z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY
> > M
> > z{((;&-
> ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB
> >
> z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S
> > KDX
> > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`-
> jSejso!@e^uJ
> > <
> > zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG
> > HTu
> >
> znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH
> > d+
> > zMY-
> =jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+
> > k&+m
> > z%ZWm1z4nMfO?(4A8G8!-
> oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+-
> > ^I
> > z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4
> > e|4?
> >
> ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj#
> > ^0e
> > zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E;
> > aO
> > zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI)
> > d
> > z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B
> > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA-
> +T`x7hrGd7
> > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G-
> tP(~dNEPPRy<$X2&|cAe5A
> > }bI
> >
> z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C
> >
> zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM#
> > g8_@a_!
> > z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0
> > 06
> >
> zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q#
> > N
> > zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@
> > M4b@Z
> > zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A
> > W
> > zDssgPVVyB-*vr3ad5~B-
> )<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f
> > wo)
> > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H-
> BNMSM32B_HnUIx=z%Fof0ntPF#j9W
> > WX+
> >
> zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u
> >
> ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L
> > D0
> > z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$
> > T2!
> > zdK(Bjx%p|zQnoY<UWi-
> I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb
> > Nki
> > zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP>
> > u{Cu
> > z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA
> > z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a
> > @W=
> > zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p
> >
> zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b
> > aP~U
> > z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS?
> > dZ
> > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T-
> wQgkxi3VLQjxyVy
> >
> zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod
> > Up5h
> > zqp!T4LK?<KJ()xH%)kcP!N1qc-
> swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n
> > rr|
> > z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g
> > $M
> >
> zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG
> > nyO9
> >
> z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<=
> > QC
> >
> z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO
> > 2Oi
> > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl
> >
> zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI
> > +uw!;
> > zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL
> >
> z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2
> > )p
> >
> zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B
> > c;i!
> > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV-
> Hkg6e~c%ayO
> > }6e
> > z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf
> >
> zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx
> > yhi
> >
> zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE
> > FSC
> > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz-
> *>o*46xhGpS8Y;XQ
> > *+
> > z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_;
> > $3Q
> > zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9
> > d
> >
> zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq
> > b-|
> > zOx|zYa;20oYTSb^$f*puP6`{=@+R-
> cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs
> > C^
> >
> zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv
> > $0gQ
> > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#-
> a+SMQ@Tv59b7zfSbF`J@FL3|c(?~
> > Mw6
> >
> zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva
> > Y
> > z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK
> > J}o!
> >
> zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y
> > GYg
> > zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE
> >
> z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ
> > QYoK
> > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ-
> ~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M
> > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{-
> p3I!HZ(Q(cX|
> > H6u
> >
> zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@
> > wl
> > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_-
> `ds;ZHWg<At
> > o
> > z_!d&4;KL)krKVbM_-
> %V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3
> > zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW?
> > s&KLw+
> >
> zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB(
> > ~6l
> > z==pSlrsfT~2W{Zj-
> #*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU
> > Xk
> >
> zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1(
> > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$-
> Ow%eFF$z!@
> > J+-
> > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R
> > zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR
> > +Kh}Lr
> > zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2
> >
> zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{a
> Q
> > z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n
> > C)ZrQ
> >
> zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7
> > 6h
> > zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW
> >
> z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C
> > Wu8yz
> > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{)
> > zw7h-
> b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{
> > $z*$
> > z=zlg}>gO`p-
> 0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i
> > B
> > z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul
> > @}
> > z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6
> > nc`
> > z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU
> > z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7
> > 2C@
> > zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM
> > e
> > zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2
> >
> z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg
> > 7
> >
> z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP
> > Su5
> > z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{
> > 2
> >
> z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^
> > h{bn+
> > zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4
> > uNZt+
> > z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH
> > @17p
> > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@-
> 1E
> > 7@!
> > z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv
> > UZA3
> > ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13
> > z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq
> > z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2
> > zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH
> > zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY
> > Ep}s
> >
> z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox
> >
> zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n
> > z{aj
> > zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT
> > zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC&
> > Q*
> > z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@
> > 1dFnWtdD
> > zNVk1t_y;mT-
> k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr
> > q=F
> > zDjf9;-
> DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu
> > WqN
> > zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM
> > o0
> >
> zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p
> > h-@
> > z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK
> > HW
> >
> z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y
> > nKla
> > zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D!
> > B
> > z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp
> > Zw$e
> > zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c;
> > za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g%
> > mO
> > zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_-
> Hx
> > _2|
> > zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6
> > R4Rr
> >
> zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N
> > zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd
> >
> zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6&
> > u@Wv
> > z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6
> > 9Jd_v
> >
> zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a
> > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56-
> 8|HN!VHDt?X!7%VRV8^)x
> > U0D
> > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e-
> h|F2yMD^>eWe)o2zdCq!a(n?9
> > >#f
> >
> z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO}
> > F
> >
> z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ
> #
> > qTm(t
> > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;-
> }$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG(
> > 6c
> >
> zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr
> > a
> > zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU
> > zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h
> > <pq
> > zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC
> > Mb
> > zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn?
> > G
> > z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm!
> > &o
> >
> zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem
> > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e-
> RM%C;1ods}_Dy6=&aE!DH&yZe}Po
> > l_s&^
> > ztt&=Z6-
> Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D}
> > 1
> >
> zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6
> > Vm*0jD
> > zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS
> > z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|>
> > `XAJs
> >
> z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL&
> > z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A-
> > Mf
> > z<-7K<$G6OrXCLF&g-
> X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN
> >
> z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il
> > {Aw9
> >
> zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87
> > CC@??
> > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo-
> ^_Ot?JdLg|1aj$ifpl{V^
> > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C-
> R#Vcu^1XBSkb
> > =
> > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o--
> &31)1TQ|Q%EAhuIXZd?<`#d
> > Hj
> > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1-
> k2y^JQ>&e<>!r+45@!bqRS
> > D
> > zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#=
> > z8@e(3tmNqVWq`wXV!qG<JTY-
> Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3
> > e-e`uBA
> > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq-
> a`x7HIXwJ=fQf_ro@BbDbjW+5A=13
> > ?M
> > zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A
> > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71-
> xIa;QyQ+A+=ch*hu
> > DSEC
> > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0&
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..6335653ece1605cd0c53b
> > d2cc2bc21d57d213dae
> > GIT binary patch
> > literal 79906
> > zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$
> > C9i
> >
> zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c
> > }
> >
> zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I
> > {
> > z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7
> > MH&Y
> > zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM|
> > NThc
> > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M-
> DQkUsiWm_>>F`39z{F@w
> > QiMSjA
> >
> zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^
> > -oj
> > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB-
> Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY
> > zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1>
> >
> z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o
> > OF-(
> > ze(GY+PNz-|cTO$duNND)-
> {Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR&
> > %J
> > zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{
> > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb-
> jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD
> > z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW
> > %3^
> >
> zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k
> > vG
> >
> zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3
> d
> > R&s7P
> > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq-
> u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt
> > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm-
> &}GK
> > x(<
> >
> zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n
> > -t?
> >
> z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9
> > *
> > z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V
> > 4Ni
> >
> zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu
> > ^%
> >
> z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4
> > C=
> > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+-
> DI^9d~!WoYX0A1$
> > X%
> > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=-
> ;cGp&
> > 30
> > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X-
> )f2nzV!Q^qU_$m?x3Qsm
> > ex3w
> > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j-
> #eg0l|9C)@T=sxzA
> > k
> >
> zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E
> > NK9U!c
> > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4-
> eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb
> > nmP
> > zDdg?>-
> mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a
> > R`2d(
> > zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|<
> > D<#}
> >
> zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o
> > 8
> > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e-
> W7
> >
> zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_
> > P
> > zLL$x|O2|$4_>pUK%4O!a-6#4-
> alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT
> > z`*O5L^inXLpWTzaUm%TSE<U`-
> Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs
> > p!
> > z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{
> > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR-
> #Ov6((s
> > C#V
> >
> zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T
> > @9C
> > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&-
> x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4
> > n=
> >
> z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ
> > e
> > zuk|Q9*5!@y$-
> x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF
> > 8^
> > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G-
> <BptWKsIz=W_P31e
> >
> zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2
> > &++Q{
> >
> zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv
> > Y!Bo}
> >
> z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8
> > P<
> > zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z
> > RAE+
> > z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K
> >
> z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e
> > g
> > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA-
> UumgF$+yN
> > ^{w
> >
> zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR
> > {j
> > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0-
> 9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N
> > XFE
> > zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj
> > zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z
> > v^+
> >
> zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)#
> > Yhjbc;
> >
> z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_
> > Rx-k$
> > zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r
> > !n
> > z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#};
> > @Voub
> >
> ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX
> > #p{~VSr
> >
> zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2
> > 6z*3T
> > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^-
> D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d
> > NUT
> > zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s
> > zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ
> >
> znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp
> > utI
> > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg-
> y}h%yHH_0H
> > a8<A
> >
> zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps
> > >6Mc?h
> >
> z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e
> > TQ%X
> > zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M-
> G
> > 2{M
> >
> znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u&
> > Jp
> > zum8=!r+B_~0&G%_%VRj-TC~2mL-
> ot07njmvdGDQXScyh?WMt%s_phdFXEx;v
> > A6W{j
> > z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam
> > `+(0
> >
> z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29
> > @
> > z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On
> > @-tU=bw%s
> >
> zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{
> > YugQ}
> > zM8N()%W_L~2Da%^cIAH-<-
> an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v*
> > wES
> > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H-
> AhOC|1BQKucrND=U^;)jo
> > OarT+
> > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s-
> 8ymFk^)c%duzJ;nL)3Nu
> > }
> > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx-
> &f`Khm=*XOz
> > ?S<B}
> > z%8w-r#pfF@&BNC-
> fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2
> > 2QC!aZ
> >
> ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP
> > W
> > z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!%
> > U)1gME
> > zXaJ!`N#R-
> _I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk
> >
> z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@
> > ZQJwxv
> > zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM
> > |FT
> >
> z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M
> > Re<Cff;
> >
> z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{
> > P5
> > zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L
> >
> zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg
> > uoJJp
> >
> zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^
> > AC
> >
> z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f
> > z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7-
> rV
> > rF
> > zg3F-R(c*YRq-@%swU!k`8-
> wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R(
> > 9R2;h
> >
> z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs
> > 08Z
> > zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r
> > wY
> > zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a
> > %KM75
> > zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2
> >
> z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW
> > G
> >
> zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K
> > 9+X
> >
> zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S
> >
> z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ
> > pa
> >
> zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds
> >
> zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^
> > rj9
> >
> z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI
> > 7hE2
> >
> z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U
> > Qp
> >
> zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P
> > u^kAGC
> >
> zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p
> > &qx
> > zu6PAe_-
> |zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce
> > Wy}o-
> > zDVg;W`B&bT@-
> K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~
> >
> zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV
> > >9
> > zsE<cJl8QUANXMMXD!_@-
> n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P
> > q
> > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC-
> =%ubEfAZ
> > @
> >
> zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^
> > zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA
> > R5My
> >
> zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v
> > adA
> > z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L
> > ~M
> > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW-
> e{py@
> > Z9m
> > zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d
> >
> zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G
> > %
> >
> zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y
> > 1
> > zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI>
> > pGi
> > z+_V-
> c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+
> > X
> >
> zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj
> > !|*
> >
> z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU
> > M9o^q
> > zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k
> > z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y
> >
> zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G
> > tq
> > z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp%
> > wS#
> >
> zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2
> > iu$
> >
> zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^
> > Q
> >
> zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{
> > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x
> > z-
> axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b
> > zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d
> >
> zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi
> > GxV
> > zW+Xgk^iMPoaLhyqRlH?kt-
> @DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~
> > z
> > z?VV;!_jL_mlUw;2nHl-
> WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4-
> > %
> >
> zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+
> > UJ
> >
> z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2
> > >D
> >
> z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{(
> > <dC
> > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i-
> 6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2
> > %
> >
> z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7
> > D~m%
> >
> zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU
> > wS<o
> >
> z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT
> > h8Q
> > zoJ6nV;1DH2O4gK#e-
> q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO
> > zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y-
> ?g
> > mho5+
> > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane-
> R8v5Z3OKYwF7I{995>T{A1a4Im!
> > )_
> > zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q
> > wBco
> >
> zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8=
> > %Fv%A
> >
> zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl
> > ZU<
> > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0-
> }=OWCI_3x@
> > 9
> >
> zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz
> > hw
> > z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*)
> >
> z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_
> >
> z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC
> > DNWo
> >
> zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T
> > !
> > z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T
> >
> z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s
> > B
> > zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7
> > zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ>
> > TQCm
> > znzg-
> `v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a
> > 0J
> > zIkAk(wATQFU}lxojL8BaMgpS*sZF-
> `Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y
> > z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e
> >
> zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n
> > >SOcM
> >
> zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ
> > %4x)R
> > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}-
> 7DJqPTCn{7Nz>p0rZlI4~7mz
> > zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|!
> > g`?g
> >
> zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO
> > cr
> >
> zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb
> > Z!t
> >
> zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3
> > l8e%
> >
> z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O
> > (n
> >
> zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O
> > pc>
> >
> zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>|
> > 3uW
> > zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{
> > UyAaR~g
> > zku^pl=~dP2`Zfc98X!v015wP-
> Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd
> > r
> >
> zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j
> > 9
> >
> zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so
> > Gf%c@
> >
> zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62
> > 5bew
> > z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG
> >
> zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN
> > ^
> > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=-
> Y=I$JBF{x__)9E*zZEmcCFhV9%@A
> > |;C;
> > z0dw89i-
> PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%-
> > &
> > z>Q=`%q>K==&;cust-
> ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV
> > z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9
> > XLis
> > zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P
> > 1}jc
> > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k-
> w~FY#E${v
> > @rK
> >
> zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp
> > -fr0oM
> > zeqF9y$w4I3?w-
> jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU
> > Fr1!2
> > z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~;
> > mLh?
> > z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj
> > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1-
> (p9OWCabzpEq45mFF
> > oK|H
> > z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+-
> O
> > Y}tK
> > zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a
> > zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa
> > +|BJf
> > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo-
> {zTWc%6}gM|{b`5lyb8()nn?Zf
> >
> zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9
> > +T
> > z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u
> > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%-
> (}mcvBi24si~mkArbb_~r3o|KZf^n7Uy
> > E
> >
> z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{
> > $e
> > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H-
> 8)+593lMa!6m;Ey~fbc
> > ;@zbu
> > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g-
> `zSeHh*X@cob
> > g_J
> > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H-
> $azMlS<h3_eAd0+EVB
> > ViPF*q=w
> > zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS
> > Tw
> > zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K`
> > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;-
> q=U!pbpr~8VdgFOFb
> > 5t^9
> > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9-
> 6O1aqUt
> >
> zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9
> > QDz?mSX5
> >
> z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l
> > QHSl
> > z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F
> > C#
> >
> znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1
> > zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~
> > H
> > zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_
> > oz
> > z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K
> > DGp
> > zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o
> >
> zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C#
> > v9
> > zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s`
> > S
> > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E-
> y8jBnk?{Kg<Q(rP
> > ?aP
> >
> zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M
> > #<y@7X
> >
> zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P
> > e
> >
> z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf}
> > Dot
> > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)-
> tXUE^B;?g$~2}e
> > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr-
> h5P};PfpB7o>k|p
> > #
> >
> zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5
> > tV
> > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz-
> o1WNRw7&EKpp!}70%&c^b
> > 4h<X*
> > z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ<
> > GAqMM
> > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q-
> 5QmskD?C29B1Pr&(c@s&e+uwi>ijiC
> >
> zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz
> > 6I
> >
> zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2
> > p^z
> > z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3
> > z<50dfE9+W7#lo(K-
> r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+
> > CCm
> > zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7
> > 2*<<s
> > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}-
> rVwE?y%~_n0~M
> > }
> >
> zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m
> > &MC4
> > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw-
> XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL
> > -MC
> >
> zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY
> > h39ZZ}0
> > zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb!
> > L
> > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v-
> s0rJQC*k<wIAScDz1q_$t
> > 67V9
> > z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M
> > @O5t
> >
> zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X
> > NW
> > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3-
> Je!ymF9!@&)jg5>?2{8NsyKmZu
> > 0v4vt
> > z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6
> > m~9%
> >
> zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$
> > 4
> > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls-
> oKS&kVw270i?>6=6@nEFRC5Es`
> > ~
> > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*-
> LqT
> > F>U
> > z^KiUZAYXWSxqM(C(C=Zy<<Qa-
> QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r
> > G
> > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=-
> 4|~9MCtID_85v
> > Yp
> > zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W}
> > hq
> > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<-
> JnxxY)Hg
> > z?YX0XeW;3-
> 48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n
> > >i
> >
> z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU<
> > pvY2
> > zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb%
> > W=j
> >
> zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re
> > %CCQ<r
> >
> z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1#
> > &l`5
> > z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2?
> > |b4
> >
> zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx
> > E)m#
> >
> zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV
> > >xj
> >
> zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o
> > b|>
> >
> zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB
> > wX}s$
> > z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw
> > m=%XJu
> >
> zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf
> > XFK
> >
> z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87
> > omSx
> >
> z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v
> > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#-
> 8~w<KRe>5t8O19tX
> > VdlKcX
> > zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X|
> > zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s
> > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza-
> 27uAu?{)Oh
> >
> zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1
> > u
> >
> zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll
> > Tnbb(?(
> >
> z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L
> > W5JPe
> > zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT
> > G
> >
> zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x||
> > &@
> > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B-
> qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y
> > Sa
> >
> zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw
> > (
> > zY^$M(f1CD!4Fn3S@`Lx%c?j-
> wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac
> > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7-
> Yq$
> > gRd
> > z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA
> > z8K_Ar&HHJwu<-S7^&Tz-
> z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D
> > Q{Qdr
> > z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz
> >
> zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l
> > h|`
> > zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H
> > d>
> >
> zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+
> > p8T
> >
> zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi
> > Z`#p
> >
> z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK
> > G
> > zO!{{Gr-
> ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N
> > z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E
> > QFcnaYc^
> > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe-
> {}E&CO6a@=<Y;tXT*n
> > V6
> >
> zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC#
> > 52^
> >
> zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j(
> > V7D7
> > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u-
> U{
> > b
> >
> z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t
> > ^wM9?
> > zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs
> > K25^
> > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff-
> KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt
> > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|-
> EFP&Y*s>3Yf2)ZCTs)~
> > gJ+
> > zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{
> > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G-
> PPJ0
> > ?Kf3
> >
> z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o
> > Qo<
> > zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o
> > UA=
> > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD-
> X_KaBxie|nwb|o$l{eH#^hvv27<
> > Qn
> > zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn
> > D@
> > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb-
> jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U(
> > z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ
> >
> zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$
> > %Qo3*6
> >
> zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m
> > 9{p
> >
> z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ
> > +Y
> > zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl
> >
> z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE
> > 9&
> > z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$
> > &>8io
> > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb-
> OZgaoXUvS83(PBK8FLxH<rd+PcVL
> > z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr
> > @>iU79
> > zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl<
> > @
> > zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth*
> > NP
> > z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_
> > <h1r2
> >
> z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U
> > U^
> >
> zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S
> > a#=2pN
> >
> z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T
> > KI
> > za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp
> > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh-
> `^5g98TqP_j#KdfRYD|0YNGFhOt4
> > #(
> > z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy%
> > MXI4g
> >
> zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc
> > v
> >
> zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA
> 6
> > 3
> > z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L
> > P`
> > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&-
> acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z
> > G
> >
> zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF
> > Xihx
> >
> zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg
> > ~d{ri!Y
> >
> zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{
> >
> z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_
> > z)
> >
> ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi
> > x|!
> > z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G;
> > *KA
> > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a-
> 2i*w9Y1kWggcE
> > Az
> > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz-
> Yc~Qsu2kWQ?O0sIz*2Ug$6lF
> > 7j$V
> >
> zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN
> > bAk
> >
> ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc
> > @
> > zi|8mSqO-MoaYaqA_#}w?c-
> >nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G
> > 65>`
> > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog-
> (Rz@ruT7zBf!)UI
> > W~
> >
> z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T
> > `E
> > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^-
> ^WD
> > %
> > zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf
> > zTyu*%V(L_|%5}>KD68-
> 34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy
> > 2
> >
> zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr
> > ^+)zfc4
> > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#-
> Uk>=DjJl057_mpgxax|_Z7^eE
> > *fBXa
> > z5_DRyRueL^-
> #{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;(
> > z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg
> > &
> >
> zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB
> > z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&}
> > h
> > z32!E$+=MZ91HfdyI-J-
> l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$
> > zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m
> > @
> > z7tPMl@iqfxzh@Lj$xc-Z{m@G-
> GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P
> > nn4<
> > zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX)
> > q(
> > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb-
> qV@_uT2r9>Pn}r5o@L|E
> > Y*YV
> > z0`B%7x?w2<&7x>az-
> wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1
> > m0yoPLQ
> > zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y
> >
> z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W
> > mG
> >
> zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j
> > sD@ZJ
> > z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28
> > 9!|
> > zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR*
> > r7a77
> >
> zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG-
> > z-
> 09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e
> > WrXO
> >
> zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC
> > TI
> > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk-
> v)o<J5KbA=o=@`(r5hoYx
> > Mi^
> > z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6
> > 6N
> >
> z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO
> > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#-
> IZ<w4%qoDyYF%VJC8
> > ue
> > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n-
> wj*c)&TK
> > 0t?
> > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm-
> qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~
> > z!
> > z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56
> > MWm-
> > z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92
> > W=k
> > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?-
> nog7X%sk_s<Y+v
> > *t
> > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo-
> `!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F
> > zbCM2u?}yBTP-|YUP+qtE+N-
> $^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8
> > 3OR
> >
> zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc|
> > ej
> > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{-
> f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~
> > Y
> >
> z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5
> > mBp
> > z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K-
> 6r
> > 9Of1
> >
> z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB
> > H*
> > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX-
> uT&S
> >
> z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B
> > Z5=er
> > zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c
> > sNof`
> > z=Hs3R{$%c!jWY-
> L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP
> > `
> > z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0
> > bt
> > zlnR+ZB=thb?WfT~!j<x<0-
> aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u|
> > vh
> >
> zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7;
> > J|z
> > z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0&
> > z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N
> > YbY!ry
> > zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX
> > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2-
> <QnUzm@<!39peL;+M
> > Bzl|M
> >
> z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_
> > EO7gN
> >
> zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6
> > $i
> >
> zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX
> > n{Of
> > z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R
> > @dv8E
> >
> zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@
> > YK
> > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We-
> #w4(vmfn?Vr
> > u
> > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6-
> 4f(+RJub`mui!
> > Dw
> > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl-
> }yeK=rbpE2k2X
> > KXQx
> > zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&!
> > 6
> > zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj
> > N
> > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf-
> y^iZn3c@baZ{@GX$an^4lQ&IToF+y
> > zyt
> >
> z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd
> > z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a?
> > S
> > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di-
> #FqXjnSNMO_Y*e|TkzT6w
> > L
> > z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N
> > L
> > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!-
> s9+9*KOCp;tUhBW(x32
> > DqHX
> >
> z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+
> > (
> > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y-
> Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w
> > X
> > z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq%
> > K
> > zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel
> >
> z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j#
> > +q&
> > zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t)
> > MFP
> > z2e~I-K~cSXx8EG)lzE+7@73IePhx-
> ;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL
> > #F
> >
> zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5
> > ~|o
> >
> z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f
> > zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf
> >
> zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af
> > A<3
> >
> zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw
> > FM4a
> >
> zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD
> > >YZ7`
> >
> zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd
> > W<i*
> > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q-
> dnOip*0`sN2T
> > a~yG
> > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk-
> (q@M
> > TF-Nx
> >
> zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{
> > `
> >
> zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra
> > OZX
> > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW-
> kGO+`xCf>(h{Mcc
> > %|2
> > zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE
> >
> zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV
> > -5^$B
> > zPbdR=b%2-
> pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L
> > ?
> > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2-
> pNELfG(uNbq{doFM5MP7xlb)Rgq
> > <
> >
> zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N
> > DpUF
> >
> zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q
> > %wi~ga
> > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW-
> 3aN5iiL|
> > `
> >
> zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$
> > z
> > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+-
> lbp!I4w9ZnT_6aMT~=LLkg!$R
> > l#
> > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c-
> lmKVwD
> > 3GSE9z(
> > z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE
> >
> zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw
> > bk
> >
> z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo
> > a9>Y
> >
> zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(#
> > R
> >
> z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@
> > K
> >
> zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9
> > N?
> >
> z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw
> > K
> > zdildOB}k13;#BI@N5b9u5s-
> {=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp
> > z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w
> > 64j
> >
> znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>|
> > sB
> > zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r
> > zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL-
> $T
> > m>
> >
> zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1
> > 3i$
> >
> z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k
> > G5`&V
> > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng--
> HdhvEg
> > EU
> >
> z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4
> > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$-
> Q%t!bC
> > $cv!
> > z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO)
> > Br-
> > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C-
> 8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ
> > 9x`@
> >
> z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB
> > Hp}
> > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r-
> 2YOPxyr*
> > b}>
> >
> z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A
> > DU;X
> >
> zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@
> > bS
> > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|-
> W+1H2CZtdm
> > OT(s
> >
> zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J
> > zwr
> > ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$?
> > Zisq
> > z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo
> >
> zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp
> > <
> >
> z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~
> > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x-
> |BgIJfi=ju7@WZg-
> > yi
> >
> z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW
> > N<+%Xc6
> >
> z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v
> > Gh
> > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep-
> 0s*6L=4RuZ>k3UeD`pkpd=
> > K6
> >
> zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8
> > a1HxFs
> >
> zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY
> > yJ6
> >
> z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR*
> > &
> > z-
> =>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk
> > f
> >
> z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJ
> G
> > f
> > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C-
> m=TI!deWV<@u@B+g9zOd!H<h7
> > 6
> > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H-
> !7w?@Nm!4fF|H&)>RG9@xH#
> > VA%Kj
> > zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M
> > 3@
> > zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x
> > zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL
> > m2
> > z`KG6~&Y4#$-
> >{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO
> > KIXO
> >
> z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L
> > NUGvT
> >
> z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr|
> > %C
> > z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S
> > $~q
> > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o-
> IzYg)#61qGsUJ
> > @X>V
> > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY-
> L2ha3l(|O
> > P
> > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=-
> neefemATL|%SeTj
> > 7KM
> >
> zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc
> > e
> >
> zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u
> > L7
> > z!mV(@!YY)C1EI1tx4-
> 6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x
> > $AP
> > zwpSBL-
> W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu
> > yMC6_
> > zOF$m<BQ-
> 2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI<
> > T&4!
> > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~-
> ^iTXueIx8byvHT>hu$|i_OeooSft
> > n
> > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV?
> > zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1
> > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%-
> W88*^zKTEx>j2)~V
> > 9UTQ`*
> > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V--
> kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL
> > 57
> > ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V
> > z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL)
> > $Zo2
> > za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I
> > e~kMH
> > zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?!
> > %!FY6
> > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K-
> s2WN^ui3C{($wPhZa^$pzWR^Hl
> > 3F
> >
> zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw
> > 4<G
> > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt-
> M7|}+UXRU7h?~TB=)5(t0^!(
> > %P
> > z-
> F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc
> > )h3ea
> > z6-
> G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W
> > Nvtc
> > z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O
> > B-A
> >
> zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV
> > vU`(H
> >
> zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW
> > E37a#
> > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o-
> gou2?WYbb69sCMC}^w$$jzUo!Y&
> > !
> >
> zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm
> > z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z
> > #
> > zq-
> Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV
> > L
> > zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;|
> >
> z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO(
> > 9zDJE
> > z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p
> > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p-
> ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I
> > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6-
> fqr2rZ=VYP@rHCOq9pf8B0xw@Y0
> > Q|UG
> >
> zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY
> >
> zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#-
> > G
> > zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X!
> > we
> > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)-
> H!*m0eZZ!QVFvyXV^=j}!Z?!plq
> >
> zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h
> > 3
> >
> zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43
> > 0oJ
> > zI(_U{Z0qELvqlo1zMy(-
> joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq
> > I+
> >
> z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+
> > VXJD)
> > z-
> q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV
> > YY0B
> > zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC!
> > P|
> > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r-
> *H*VR4`LaS<<C1W7hg&
> > ~pO+K-
> >
> zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM*
> > ANN
> > zUz%6;oPCB&&k^}WT*2fbT-
> rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)(
> > t{
> >
> zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z
> > 4P
> > z{MfuNHeOI7d~NQbki>Wa*r?}Ta-
> }c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw
> > nR7
> > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&-
> v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0`
> > %z
> > zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y
> > O|w1&
> > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih-
> 2{<n)!I+;AHbRo*RPPJ<gUm%2
> > u
> > za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP
> > d~+Gh
> > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj-
> > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?-
> BXUNalABrN}l?3DDjuoNkTNq%YT7
> > 3F~h
> > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV-
> S%|a7B=tS!rdlDQnw_~vR
> > NG+
> >
> z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI
> > TI9~
> > z80}SbU~>FO|9I4K$=-
> QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@
> > JW;6
> > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=-
> TSOTON|2ebg0xls`JM}%@O`g
> > K
> > zmH+=v*cCg)>)6&*G74T9ntba~IB-
> 18Gfz;WMB^neWL%=F6kixs3>vAmMHr<#
> > a{F%5
> > zSV4%6rVjJ{9oXWh7>e;x_5=7-
> ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@
> > Cxn#6
> > zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4
> > z!jPQ@A+Wb%GhI-
> D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av
> > QoVl
> > zpg?U5sxJ^-
> s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU
> > u2u
> >
> zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH
> > Y16t
> > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l-
> Fr_U^mpQywF
> > 7_%T
> > z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a
> > mi%
> > z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j#
> > @z5(
> > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi-
> XyKLb
> > hKa
> >
> zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p
> >
> zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt
> > i-
> >
> zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K
> > 9fOo`p
> > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs-
> ui){uM_Y;pwOERO_
> > ?nhh
> >
> zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp
> > !5R#S
> > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q-
> UO22MYfNY
> > *&sB
> >
> zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1
> >
> zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN
> > 1K
> > zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt
> > zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr
> > |TU+
> > zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@}
> > qgr0T7w
> > z<XUd9YdH`MV%gjTsUwYem-
> CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2#
> > 7kIj!)
> >
> zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D
> > z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx<
> > D`^2
> > z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0
> > O
> >
> zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w
> > )9*
> > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz-
> xEr*zAK9
> > <N?Y
> > z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F
> > &Xs
> >
> z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx
> > qkyHve
> >
> z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp
> > E(bW+
> >
> zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II
> > z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a
> >
> z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K
> > 127i
> > zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe
> > WR1yd=
> > zOy+GS3N+k-
> ;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X
> > 8KHw
> >
> zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM
> > wuHG
> > z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T
> > NTye@
> > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+-
> 8Mp5YQRWhyS@`gIr&htF@U
> > =BD#r6X7
> >
> zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp
> > i=M9v
> >
> zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9
> > f4
> > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f-
> C*U
> > }T
> >
> z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2
> > T=@i
> >
> zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_
> > &ip
> > z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED
> > M
> >
> zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F
> > Ya5e
> > zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A?
> > N>
> >
> zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n-
> > -MxQ
> > zG1h%OC9O9yC%If5t*4BIdz)$gh>-
> Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q
> > MQ
> >
> zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV
> > SbVYbX
> > zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`%
> > WvX
> > zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS
> > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d-
> XA~5}VSN6cplAA%P=_p4Y
> > qn~a
> > zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q%
> > 9};T
> >
> zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w#
> > X`^h
> >
> zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_}
> > Ln=
> > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw-
> J{yCA}t$O?2Gbro_S0%@6bE|NUO7
> > 3JAX4o
> > zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM-
> 0
> > <2
> >
> zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT
> > D9y$
> > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4-
> pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ
> > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW-
> 8FRu~9(wk+ock12GT_
> > Ja
> > zM^?ezBrqptKLHwLt1X-
> 1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0
> > #5
> >
> zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82
> > +`
> > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF-
> GVJ3Or!j$S_H;Jw
> > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!-
> _c(_oR
> > c|
> > zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu
> > ma=
> >
> zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW
> > Kn#~-
> >
> zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO
> > XKo0`
> >
> zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f&
> > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v-
> Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3;
> > (
> > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y-
> BrsYiU;W<x<Ea;>dpU
> > @
> > zmR>$-PfosIWz(r5(5<wxPbjmo;#-
> XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE
> > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N-
> z3e*X4)s#1kO^g=a
> > {~c
> > zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl
> > z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84}
> > qZ
> >
> zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1
> > vI2
> >
> zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP
> > |K
> >
> zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@
> > +3pvf
> >
> zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc
> > 7
> > zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l
> > WtAe
> > z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$
> > w2^;3
> > z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7(
> > zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844
> >
> z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP
> > oM
> >
> zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+
> > zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j>
> > aq
> > zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`;
> > L2G
> > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu-
> hUH$wa
> > RbE
> > z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6
> > mTGS
> > z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz
> > w=
> >
> z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID;
> > @
> > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb-
> Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix
> > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F-
> ?Au{0G5tdd)TPX1hakJ3TvR90rM<^
> > Y
> > z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa
> > @~k)f
> >
> zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m
> > L4-Kc
> > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!-
> _hOdW0;F-
> > OTOp
> >
> zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!=
> > X+}$
> > zFuvZ~++1ipISzO)2)RT}D;-
> aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7
> > =
> >
> z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7
> > GW
> >
> zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU
> > ePA~
> > z_hxdvS8-
> a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E
> > z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e
> > zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(-
> > C#Ha|I
> > z=C2Ea@CE*LYY3?FwL2-
> o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn
> > be
> >
> z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A
> > W=XSe-
> > zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns
> > zM-
> {9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs
> > 456yTg
> > z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U
> > XC
> > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_-
> =gt@_z#8g{&FBl60M
> > 8q
> > z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl
> > <
> >
> z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+
> > <`F
> >
> zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v|
> > da*
> > zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv?
> > e
> >
> zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM
> > P?$BB
> > zOd-J<xYW8H1RRa|E>kVw-
> `TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da
> > kHuGSr
> >
> zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z)
> > P
> > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r#
> >
> z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl
> > bN}<
> > zqLB8`-
> ^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX
> > u{1
> >
> zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ
> > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq
> >
> zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX
> > )z(Tp
> > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD-
> jHBwcr%2
> > 0bUM~
> >
> zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm
> > n
> > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f-
> bCjEDTbbkioa3
> > AvU
> > zTgs{woXY3O-
> Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw
> > FPeX
> > zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh;
> > z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G
> > 86v
> >
> zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu
> > JvQk4
> >
> zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An
> > t>wSc
> > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af-
> Xuf0lKfuTpKFA04
> > 1
> >
> zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I;
> > hr
> > z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+
> > wHXl
> > zz&1Drp|7~EN?!zH5pKw!JvbXK-
> ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B
> > C!KO
> >
> z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug
> > B$R
> > zx6k>}-
> ^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg
> >
> zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD
> > ;>-$c
> > zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM}
> >
> zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO
> > P{<K
> > zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB
> > G7
> > zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln
> > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7-
> kO_`Up!D&o+Zeo37N~wiT
> > 81j
> > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e-
> +C(B!Y<Aj46`65i%71cYGD{
> > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;-
> TI~;
> > EW
> > zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n}
> > xK
> >
> z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I
> >
> z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd
> > nlbj
> >
> zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05
> >
> z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j-
> > Y
> >
> zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^
> > 7
> > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0-
> O=A5+6B7bE
> > #7
> >
> zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ
> > !$pK^xF
> > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn>
> >
> z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf
> > ma;W
> >
> zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i
> > xTr
> > zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X}
> > ms
> > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D-
> ^e94<`cGBaYaA!4zd=KEsJn
> > eJ
> > zd%}Zl026m#*+6#l9yFz!8d8<-
> XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i
> > }
> >
> zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+
> > zD#6R=4Z52d(S5iva$jQAz=xFyN-
> q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~
> > (
> > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe
> > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG-
> UmfNcjAaL
> > Epl$S
> >
> z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7
> > m#Z
> > z1f>)aDLDPf#(_xvLI-
> F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g
> > XhRr
> >
> zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f
> > zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_
> > <Ne~e
> > zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S
> >
> znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p
> > 2%fV|*A
> >
> zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F
> > +?=
> >
> zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D
> > 0
> > zIugZZoN&hDJvgzTn^^1-
> d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X
> > uR
> > zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y
> > wh4&L
> > zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9
> > v
> > z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y?
> > @d>R
> > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO-
> x&lC0KfJO|C8kgnlMCC`W~^izTp?
> > z
> >
> zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$
> > )4
> >
> z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj
> > NU_
> >
> zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L
> > wJy
> > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o-
> D+M
> > C?
> >
> zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R
> > @B3p
> > zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p;
> > pe#
> >
> z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg
> > Gu
> > z<x;1&YdE7!dLGg3LR#-
> vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H
> > xN>
> > z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45%
> > zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh}
> > R
> > zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!;
> > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`-
> <Skpc
> >
> zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI(
> > zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck>
> >
> zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1=
> > O7
> >
> zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ
> > Q
> > z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$
> > &S(O@
> > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{-
> gM3Y^a
> > D&p
> >
> zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C
> > 9
> >
> zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw
> > R
> > z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA
> > Ms?
> > zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l;
> > EF=S
> > zx7~>-e--
> gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi
> > fo
> >
> zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d
> > P
> > z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx
> > RVQs
> > z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e-
> eJ
> > (bu7W
> >
> z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY
> > jt9
> >
> zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW
> >
> zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M
> > M>h@k1
> > zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^
> > zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7
> > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2-
> Z~r3V
> > 4w4#M}^k
> > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7-
> #MPr;?r3h8
> > kN
> > zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF
> > ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p
> > 4&oPZ
> > zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V
> > W1
> > zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?*
> > 5gM
> > z-dO<=pUw9Hu!6VH-
> $5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^
> > P$
> > zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D?
> > W@}5
> > zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8
> > _Vr
> > zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G
> > Uu
> > zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M%
> > 7_V&j
> >
> zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ`
> >
> z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG
> > z--mu$ZE#I*Q8<#GJ~-
> LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts
> > 5J#$S
> > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`-
> h@bk9
> > O3s
> > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S-
> y+h<
> > ?#Y
> > zk-Qk=flDo-
> RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu
> > z+C9W1IPvuo^Z|-
> GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw
> > VT0
> > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy-
> t?t~fVXzqFG>P(y1EoKn
> > x2hb
> >
> z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b|
> > +mG
> >
> zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D
> > !#34
> > z-*FDsO~mox-
> k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93-
> > 5v$t
> >
> zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO
> > CE
> >
> zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z(
> Y
> > z)aDR~xD1dzXmhus5Q??fihY8I-
> ?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1
> > QMq
> >
> zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@
> > H~~
> > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT-
> h%26Z
> > X#
> > z7~{-@v;G{8Lxo0@cHdz4T{-
> P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur
> > +Z
> > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6-
> Xr9n
> > R6
> > zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf
> > w^
> > zZ3$IK{RGVZe9g9-
> KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul
> > qu_{W
> > zTj#6IYv<7-
> Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7
> > AD
> > z{ZzN7#^JAPYu-X7Y-
> 03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{
> > uPf9
> >
> zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f
> > 4A>iW
> > zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d
> > &(
> >
> zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l
> > #
> >
> zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_
> > _~%;
> > zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki
> > M#a
> >
> zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D
> > vAn@
> > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0
> > zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l
> > zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~
> > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_-
> EP9=wZkWSqwPf`a`R&_k
> > |@1@
> > zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj((
> > |{)
> > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$-
> (zx$a
> > ^1S
> > zX!<JR+joeIbZEYtIBvgBnl#LV4-
> NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g
> > |
> >
> z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp
> > zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b
> > z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg%
> > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz-
> khs!4b#@5QjP>U9%zLiUFG
> > ~av?
> > zeUJ9-Dv~3N$B!appHtL@3-
> IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q
> > 46kGa
> >
> zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y
> > E
> > zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm
> > ppAB<
> > zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+)
> > 7
> >
> z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v
> > bV
> > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT-
> 57V;K;+syy?R+C30w{q70#TZ1
> > (Ev
> > zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V
> > @y@+N~R
> > zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I
> >
> zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k<
> > >s
> > z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ
> > G+U
> > zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U
> > S
> >
> zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q
> > HH0-&U
> > zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn
> > znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt
> >
> zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9
> > _?krc
> > zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF%
> > zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(|
> >
> z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW
> > p_`g?
> > zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^
> > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof}
> > z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^--
> >
> zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x
> > `m
> > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA-
> cq+Wq%`jv
> > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i-
> +%|*Ny&
> > A
> > z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA
> > &6k{Fd
> > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5-
> JAQI7W$
> > CZ<;`
> > zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S
> > OsN
> >
> zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj
> > mz-w
> > z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR
> > 7~
> >
> z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3
> > D{
> >
> zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S
> > UN
> > zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs
> > mu
> > zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m;
> > Nu2W
> >
> z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk
> > V!}}
> > zz+g-
> u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y
> > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC-
> xL=Y(
> > GRx
> > zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q
> > zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii
> >
> zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM
> > XGy
> >
> zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc
> > zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q
> > VM
> >
> z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU
> >
> zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E;
> > iUxRR
> > zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v
> >
> zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s
> > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<-
> rUD)H9&S
> > f@E
> > zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn
> > >#iM
> > zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5
> > wX%
> > zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@
> >
> zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP
> > z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298}
> > 0gs
> >
> zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM-
> > rJhB%
> > z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k
> > zPBTLqcmk>G0PwmJ^W#xC-
> O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6
> > 7AvC
> >
> zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=;
> > ?!
> > zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*%
> > J?t7L
> >
> zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D
> > K(~
> > zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL
> > zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD
> > z*w1fD++$^@e$D7^UGJgf-
> rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3
> > <D
> > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p-
> @)*^
> > N(5Ei!
> > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$-
> P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu
> > ~
> > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP-
> wj@j!4#6iMbDW)MruAkHCb1Nqxw
> > NM{
> >
> z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb;
> > P_l#tb4g
> > z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P
> > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57-
> ^*tCzH+>d*z@3AV|%h%!1NOg+zH
> > >^N55
> >
> zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h
> > E5}(1<
> >
> zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t
> > @BwZ
> >
> zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t
> > ag
> > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ
> > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA-
> S)#DE
> > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe-
> +OTZJW>x%V
> > y
> > z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz!
> > Q?
> >
> zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW
> > VJ
> > zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT
> > @L_3c
> >
> zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq
> > w?L
> > zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw-
> G<
> > ~n&
> >
> zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC
> > {22
> > zX-
> I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4
> > dD%
> > z<YEj;4*V+0;|M-
> rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes
> > #~
> > zqZrF<mFWvzkmFGC{3-
> LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d
> > G1&
> > z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v;
> > ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA
> > z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+
> >
> z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd
> > ppY;|*f
> > zdVc@~A9~wr5$E1you*)8n4i?F--
> }{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l&
> > wBh
> >
> zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o
> > wnE
> >
> zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54
> > +~m
> >
> ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R
> > Z>
> > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z-
> WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B&
> > MMf
> >
> z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)|
> 2
> > aiA
> >
> zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8
> > ~=75zos
> > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g-
> QOrn
> > %{
> >
> zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$
> > Wvx
> > zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P
> > Q5^
> > zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q
> > AJ(0a~#
> >
> zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D
> > O*
> > z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN
> > #0-*
> > z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD
> > NuPv
> > z8A&gM+yWoI3+p-
> Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm
> > Rd
> > z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki
> > No!Ys
> >
> zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S(
> > B7X}h
> > zVR;Et%eD@V5-
> g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3
> > #N
> > zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx
> > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}-
> 8k0{FELICbyZM7w
> > lN
> > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{-
> JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb
> > iKo8
> > z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV
> > hw$
> >
> z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz
> > =
> > zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe
> > Mux8;
> > z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*;
> > =YK
> > zjl$=}dcQ-
> TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr
> >
> zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj
> > c
> >
> z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY
> > 3VqP
> > ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^
> > b4_
> >
> zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k
> >
> ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC
> > 6Q_?
> >
> zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{
> > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;-
> zV}=Ffb;y0
> > z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV
> > 9?w%
> >
> zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$
> > `2Z9
> > z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK
> > MQo
> >
> zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$
> > #|)V;RX
> > zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@
> > Ox5H
> > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD-
> VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{
> > #
> > ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv
> > <E={9
> >
> zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua
> > {h
> > z1c&pk*C&s-u!f*^mD<d?d91-
> {0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{
> > 71|@f
> > zqyCdPYA>=Yf_ZfXdKIQ7K-
> BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS=
> > *8
> > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz--
> =+yEpn0V;dyO#f3
> > quY*
> >
> z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN
> > n#x
> > zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7)
> > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp-
> >DBbJFmh
> > ~
> >
> zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc
> > 359
> > z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP
> >
> z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42
> > R
> >
> z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR-
> > }t
> > zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc
> > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E-
> c!f2kMR<>)RwV=hmWjbJxmB
> > OGSp>
> > z=zoS%q90`C_3r-1I|(vxy$L|<-
> ~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53#
> > E3
> > zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o
> > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm-
> eR5re6n!d6@_6hyx(
> > I78k
> > zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY
> > Wssf9!
> > zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ
> >
> zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P-
> > %+f<
> > zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G`
> >
> zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd
> > j+el
> > zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G%
> > >t
> > zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@%
> > Il^r=
> > zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg
> > 6d?0S
> > zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c>
> > }u
> >
> zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh
> > +5
> >
> ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V
> > bfpO
> > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W-
> !~C&zci
> > |?
> >
> z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT
> > h?j
> >
> zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4
> > 8K^U
> >
> z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+
> > 9a
> > zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM-
> > Wn
> > z9YL6MHz1*R`Ebg>i(85{!WP-
> zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M
> > $<
> > z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<?
> >
> zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk
> > zjcnO0FC<-
> zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP
> > c8Q1
> > z>8<aHYtJ``M!kq=@76^J=2^>e*+-
> ?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS
> > z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb-
> > KY
> > zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@)
> > {}ye
> > zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H
> > X$b5|#j
> > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee-
> d!ko~1?$I;0XQ0Lcy}V_T
> > M9HH
> > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M-
> xe{E>sl9(>CA<_JNmMi
> > xd
> > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP-
> t~(*7E<kqy26Hww<ma171sv
> > !t#Q
> > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X-
> XGl*%Q0ElH2aXP)|ASi9~aI8
> > )Vn
> >
> zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s
> > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;-
> *c4|rL<x*=v#r8
> >
> zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$
> > AaI
> >
> zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M
> > -hX
> > z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x
> > B
> >
> zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x
> > kdv8
> >
> zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH
> > Z
> > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm
> > z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv
> > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g-
> dTo#iWkSVwCW1XNNk>DTg
> > aD;g
> >
> zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF
> > WS_L$5
> > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk-
> &zLAxDgQMl#h~
> > l)AM;
> > z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK
> > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm-
> $hEIpj?<LiYD}ov|o=<+m77@%`dhAH~
> > ua
> >
> zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5
> >
> zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf
> > }$y^xf
> > z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y
> > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk-
> N;TT
> > N~tt
> > zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o
> > zQ-15yS^!}n-
> @U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M
> > Y69Y
> > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A-
> Rih9xWf6KdR0%$1u!qOps1C2Q#
> > ANP
> > z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u!
> > Dqgb3Ca
> > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86-
> gbBvpzX
> > R
> >
> z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5
> > T
> > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj-
> hIrr3a)n*V>r6m=eJo=M3#L3_
> > &Y
> >
> zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7
> > z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^
> > =n
> >
> zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ
> > IJm
> > z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9
> > z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz
> > g5f7(M
> > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG-
> kU
> > G*
> >
> zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no
> > Oj
> > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)-
> 2TC_XY^XyU+7`Q)it$=yI_HeO$|
> > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}-
> n<&rw6V{rKB|$Og
> > GoBpL
> > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf-
> ;e_A#;c07yl@emICdlfx6?S
> > zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9-
> W
> > Pr4Do
> > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x-
> OHJh=>^
> > %$z
> > zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf
> > R=j_i)
> > zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb->
> > N#*
> > zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_
> > zLs>gSMg&%IxgXVsk+G<1aLQyI;+-
> (x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p
> > 4d
> >
> z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a
> > O?%3UXP
> > zmxkemLOe-bD%O81OOdPv56yFNIJswr)-
> r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR
> > n
> > zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W
> > 5H`Q
> > zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=)
> > @EPJJ
> > z!!F00iIqj9<FImx<-
> TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu
> > Z
> > zA@6GBn_*`<fZu;fKyYcdsVz-
> LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb
> > JP
> >
> zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD
> >
> z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o
> > &q
> > zxj*LqEY-ZnACrceN-
> ~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573
> > zN&n5k9DfdGDn-n*utQW4V{X-
> IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP
> > Mq2Z
> > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4-
> Y(zEt0m3<zZQzZOBUz
> > lhe
> >
> z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i
> > !
> >
> zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v=
> > 5E
> > zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2
> > U3cy
> > zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL%
> > @Pb
> >
> zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W
> > T~0Y
> >
> zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f
> > 3EE
> >
> z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt<
> > {8Z-8
> > zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE
> > m16
> >
> z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4
> > LVb1o
> >
> z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@
> > x0z
> >
> z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn
> > ~4&d
> >
> zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu
> > G$}Tz
> > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ-
> Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@
> > =?WW
> > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I-
> )fwRt3qD8qt(
> > {
> > z<P<KF=}PJ1#r#`jS-C-
> BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a
> > (X
> > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB-
> $@AJqDd(YoB@ZYfK6vP54O
> > =^o2
> >
> z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN
> > g
> > zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(;
> > P
> > zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD
> > mu
> >
> z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF
> > {3
> > zwPHdUsL_Emi-
> |sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx
> > tn
> > zbrc)1<0dX~X#twYtTp`&I-
> K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ
> > n
> >
> zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5
> > +#Xc
> > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%-
> xVei
> > qO1Hf
> >
> z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU
> > <cW
> > zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c-
> > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?-
> up`F97
> > _
> >
> zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e
> > PVQj
> > z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT
> > z4)s@IGNTe?4-@J{iz-J0sXQl-
> t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P
> > U}
> >
> zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}&
> > jB
> >
> zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9
> > XPvK
> > z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck
> > N
> > zH}9#C6|qJ(-
> ~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb
> > 5c
> > zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx
> > C
> > z(-
> KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr
> > |
> >
> zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS
> > n)edp
> >
> zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh
> > 94r
> >
> z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk
> > Q;
> >
> zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS
> > z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B!
> > zLKgK@^uHSZLNEF1>n3-
> )R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP
> > T*O
> > z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL?
> > zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB>
> > 4f|!
> > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF-
> f1_RXCi@Ib*0
> > z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4
> > 8XtM
> >
> z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi
> > Vn
> > zP5ZAFYbCS1g7-
> `&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G
> > uEt
> >
> zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N
> > Vpdll
> > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a-
> 3`@t)z}?8R=?u@$Rw&yc>*^x
> >
> zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{
> > %xn
> > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0
> > zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5
> > B
> >
> zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm
> > 5jhv7qJ6
> > zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs
> > G&n
> > zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc
> > X7Yw
> > zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*-
> s7
> > b^
> > zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm
> > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR-
> qjhh
> > O
> >
> zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)|
> > CS
> > z^GD&-H%jsm7i~c(IDGo_-
> ?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y
> > w
> > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h-
> %XTOuIK%jeRlC4YOaKdYsipAm+
> > WrxJ
> >
> z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_
> > emtz|
> >
> zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alV
> q
> > N6
> >
> zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ
> > 9VH
> >
> zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td
> > R
> > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm-
> z5jm=aFjj$na3>$mvN|33HD3iFuOn0
> > va3
> >
> z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k
> >
> zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic
> > ;
> > zO)ScHYd^W4>p1IZF-
> rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I
> > nuw
> >
> zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq
> > ~p!H
> >
> zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR
> > z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH
> > @xAy1o
> > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;-
> FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq
> > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb-
> d5Kj>373=4;|gla3^9<xGWqY!YN
> > zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF
> > ^
> >
> z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe
> > z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)%
> > 6TeU
> > zDai3Q)sDP}fd8!F4@GgYGt3O#w-
> T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=&
> > !#
> > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ
> > zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A>
> > JLS
> >
> zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B
> > ^2@xF
> > zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo-
> 1(
> > TU>k
> > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q-
> I>Wsn^_=%oN0?9m<2++S;$}<NQ
> > !2w
> > z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y
> > @4wr+
> >
> z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW
> > igCND
> >
> zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G
> > f
> >
> zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM
> > +HRe
> > zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7>
> > za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!-
> N|
> > -
> > z;QcJ-
> _4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2
> > Vq6r2
> > zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y(
> >
> z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X
> > ^
> > zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL
> > z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o
> > @ew
> > zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij%
> > 2fn_q4
> > zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`>
> > =!
> > z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw%
> > <b
> >
> zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d
> > {;+cG)
> > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z-
> 9KqzX4ywpKgSlL&Lplu
> > #f5K
> >
> zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN
> > Be
> >
> zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb
> > `1J
> >
> zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6
> > h9#
> >
> z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW
> > Ts
> > z@juu7-
> 1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS
> > pa}
> > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;-
> DANP
> > e-
> > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O-
> 5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5
> > 6
> > z4%Obc4bQ}m#H`ZWui1dCf-
> 8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q
> > a
> > zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K>
> > Mz
> > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4-
> gIH0R$|yhL0%iyEWP)
> > -dMFq
> > zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4;
> > zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(-
> #
> > w5
> > zSQe21-
> iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH
> >
> zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=-
> > h3
> > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#-
> u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6
> >
> zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V
> > B
> >
> z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii
> > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C-
> NcZPpT3FT+YGkGFM
> > 6L6
> > zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3>
> > 49;t
> >
> z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@
> > ZoU
> > z1o^bK^-
> i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e
> > <06
> >
> zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23
> > |;
> > zI-
> 8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0
> > p%hX
> > z-z&;-
> 5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{
> > O2
> > zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(*
> >
> znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf
> >
> zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL
> > mu
> > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt-
> )j9cW`J=^32#Q
> > _0v=
> > zYuS>-
> !$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4
> > T3
> > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d-
> y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%(
> > U
> > z6;SpLK}$lNH+Qlh-cKR-
> YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>&
> > oV-UQQh
> >
> zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U(
> > c{
> > zfIZlR!@-
> s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld*
> >
> zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e<
> > WpJJ
> > z-
> `$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ
> > N;@<uUxT
> > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@-
> auQ<`tj
> > RFOs
> >
> z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A
> > m
> >
> zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A
> > G
> >
> zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB
> > e+D$Sx
> > zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-|
> > z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7<
> > K
> > zTOHkDcgdOyfsEiOu%WtEi(>#Z-
> ~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY
> > u|
> > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG-
> KacrZ
> > _
> > zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG>
> > N9F
> > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U-
> w88FH|Vp0NA28vf|sjS
> > i!
> > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt-
> fK$0VNHs&Mk>^C1D
> >
> zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce
> > z$GM4
> > zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV?
> > ?+@e
> > zg`wK!-l8aDa_m35OpOA{bq~|+%F-
> ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ
> > {
> > zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY
> >
> zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE
> > f!T<
> > z2ci!iV-wM?Bu7s^Huqb-
> 4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C
> > Ct6d4
> >
> z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p;
> > %j)
> >
> z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu
> > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%-
> (2Z`Wl
> > @e
> >
> zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1
> > Smv
> > z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE
> > TIA
> > zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH-
> #T
> > #5p
> > z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV
> > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS-
> W4+WUsh43&>4RG*{QQ#GI!w
> > phN<ut
> >
> z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O!
> > 8
> >
> z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC
> > li
> > zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF
> > no2|(R
> >
> zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS
> > 4D;
> > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R-
> Jpx~r9!pm?4kz;k|ao%zB@5Hbe
> > <
> >
> z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV
> > $~Mw0
> > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM-
> j_UaA
> > x<g;
> > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu-
> o$d)MnXpluW?a_({zl
> > g
> >
> zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^
> > Nsh
> > zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^
> > H>
> > z@#^-
> Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5#
> > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd-
> Ge_d>@
> > =&
> >
> zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK<
> > zN_8RoATaW}d{5!m3i1gyT+$O()xZN-
> q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n
> > z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8`
> > AC$53
> >
> zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d
> > 7^x3lQL
> >
> zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t
> > ^
> > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n-
> ;m<n!p%lxe5r|
> > zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD)
> > S*
> > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8-
> 9ip&dZ
> > 5@B
> > z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja
> >
> zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D
> > @Lj
> > zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_`
> > ?(Q=eq
> >
> zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su
> > !
> >
> zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n`
> > lly-i
> > z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77-
> ?_
> > D
> > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=-
> #ZF|U1if%4r0!Fqa4AKSYGr=Bp4
> > wS;j
> >
> zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f
> > B
> > zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w
> > SvXa
> >
> zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg
> > @KJ
> > zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL`
> > =`
> > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q-
> |Gt8<U$^Rmw`&o%H;FN+S+(N
> > H@-}E
> > z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx
> > qT
> >
> z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ&
> > z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7
> > v#qf
> > z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp*
> > M&
> >
> z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf
> > zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!%
> > R0i
> >
> z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C
> > m*DkC
> > zHs9kcukmSQnY-`;FsIMBQNgVP-
> Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd
> > 6
> > zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU
> > 7F@}
> > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI-
> W354EXdcSk^K;5aK
> > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)-
> a48PghrZ+3AO}YN
> > &bdTo
> >
> ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk
> > ce
> > zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c;
> > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO-
> KB7MVoi
> > X`~8>
> >
> z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E
> > h
> > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe-
> jybQSioRnO
> > 6
> > zpm;JeMEQciVCPbow+)K59-
> z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs
> > X$9
> >
> zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps
> > 19
> > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM-
> V3W7dJ0WrB4
> > !!+0k
> > z;zYZk1x)Y5=+Q4I`1dZe_-
> J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~
> > h
> >
> zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY
> > ^|^o
> >
> zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY
> > w
> > z8&-
> yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_
> > Pl}l
> > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn-
> cjsU7u?E8Rr%=Go&yh&47sj4
> > @fk~gw
> >
> zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz;
> > Vn
> > z-
> 7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH-
> > #bB
> > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W-
> 7Me#XrQ^Tzt>kfFu8R(s
> > Yw
> > zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi
> > G
> >
> z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=|
> > B
> > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU-
> `l%kXo|H)KHVD6KW
> > h*Rz
> > zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx=
> > &<
> >
> zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT
> >
> zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr
> > 1>
> > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx-
> gL}d<c_Mn^@%_FE+g
> > ?M
> > zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB
> > m<8{
> >
> zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB
> > rHu
> > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB-
> gw(`|azE*a<_S1weMZAOo%w(L
> > )Kl
> > z-
> dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_
> > 3&$$E$
> > z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3-
> B{
> > GV
> > zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s
> >
> z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d
> > N
> >
> zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f
> > E#
> > ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l
> > 27AMD
> >
> z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql
> > amYM
> > zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE?
> > zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7
> > W<MJ
> > z%-
> SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH
> > R8=T
> > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo-
> @a)b+Ml`1F<g{$T*e1di)$*fQ5m
> > |)PQDO
> > ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8>
> > ;g4
> > zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF
> > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA-
> k%PLdC*dz
> > w1?
> > z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c<
> > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G-
> H!u*oMbA8
> > 4$
> > zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q|
> >
> z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd
> > WSp
> >
> z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK
> > !+9
> > zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq%
> > zw_MRqd{G)1`B`l*-
> mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg
> > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~
> >
> zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA
> > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6-
> 9?bOShFo2W$of{J{
> > gHl
> > zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y
> > $TzS4WWp
> > z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_}
> >
> zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7#
> > T9bz
> >
> zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r;
> > 7VlOw;
> > z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g;
> >
> zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@
> > ~Q`G
> > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s-
> 2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v
> > z8QwfoitD*@-
> 5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j
> > ~x
> >
> zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o
> > }${B{GLO@
> > z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO
> > >
> > zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@(
> > W
> > z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r#
> > JmFX
> >
> zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0
> > TYK
> > z-`2+H1Yr#7j9>-
> Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M
> > $i
> > zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@}
> > 8Q-
> >
> zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB
> > {d;Z$
> > z>%q~GMLth%$)7kc<>-
> ;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX
> > =3xm
> >
> zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2
> > eba=c
> >
> zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn
> > vLvp4*
> >
> zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mM
> J
> > XCoBHnW
> > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1
> > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f
> > zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO-
> 2
> > |a}K?r
> > zFo(mo@$6w!RCO;!k{m2{z-
> _`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C
> > _9
> >
> ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u
> > G8
> >
> z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o|
> > p
> >
> z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK
> > pU
> > zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G
> > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`-
> GBdrly&WQ1*?kDL@
> > pG<V!
> > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3-
> JyC<keh(WCoDi(@n0xqm`@&*0R>;
> > SVa
> > zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?-
> i$S
> > )
> > z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj
> > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#-
> 5>lJ2jXZ|?d~C=
> > n*V
> >
> zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR
> > 6na4
> > zw-
> T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L
> > i
> > zajQH#9E-
> re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L
> > 675^
> > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T-
> 5)vkqIFntDZMA1VMOHjx#|#
> > gp
> > z<=jzFhYH`U9&O8-fDan`-
> Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ
> > s9
> > z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+
> > B<
> > zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(-
> AS
> > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W-
> JCA@y|<k2?s=otq
> > kXs
> > zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf%
> > 6
> > ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg
> > V>
> > z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}-
> >
> zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP
> > e+{
> > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b-
> LbUdRv*H4Cj>iO=b6AU_W
> > kt_g
> > zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><}
> > &(L
> > ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~
> >
> zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCA
> I
> > uWDE
> >
> z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy
> > WSRlcK
> > zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL
> > =h8r
> >
> z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L
> > M^W
> > z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7?
> > _YY
> > zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf(
> >
> zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W
> > u$Jn
> >
> zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j
> > Uyi#
> > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1-
> 7wk8y&7D+XUbG
> > qc
> >
> zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{
> > B?
> > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR-
> `ynB}GDY7)z8WdiaOz1?
> > $
> >
> z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2
> > w_fKH^bO
> >
> zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C>
> > r
> >
> z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Y
> b
> > }g
> > zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi
> > zXl`9?-
> $MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29
> > @(BH
> > zQPs%IT;9S({?mP*=Qnc|D5J-
> |w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf=
> > c
> > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4-
> F^%90(P&<beWqvDXsg0?i
> > WV^Yr
> > zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz
> > m*iO
> > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv-
> 0T#hDV!d
> > ^^pp
> >
> zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{
> > zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I;
> >
> zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu
> > G
> > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da-
> R)wUYvP#%R8D{%W4M3=p@E&YpC5Y
> > <^3Ym
> > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%-
> wXl_NyC`0qB
> > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr-
> wIc*7P
> > U)!KE
> > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek-
> a?2dg6PVM6GVX~3`oj
> > %%M;
> >
> z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je
> > zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i
> > z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`>
> > g
> > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T-
> 2DeQ#fI
> > 0ra
> > zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90%
> > U2ISK
> > z7k~rD4m&7xFAX&{$U-
> )37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA
> > m&$g3
> >
> z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n
> > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;-
> d#*zW#Tye9hV)P&G*REZ2he+xK461i
> > S
> > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+-
> @izT8*fdO5W<a
> > <>h=
> > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O-
> U`a;Yy~M(7
> > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0-
> *)&Q!XszxM?Zk
> > c
> > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>-
> Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s
> >
> z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB
> > ^
> > z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y
> > mQ9
> > z7-54~(UFH?f-
> J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V
> > zmVbN(^|1#(h+-lD+oK-
> PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W
> > b
> > zObewKL-
> P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E
> > ~AL
> > zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ
> > mE}
> >
> zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS
> > Ar
> >
> zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{
> > eM#TotF
> > zf2^1WUw|=jGZ{M_KC6YOEM6I@-
> R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ>
> > -!8~
> > zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G
> > w
> >
> z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ
> > vh0
> > z2yd+qIez;p={X=o?0-
> ^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F
> > 9F
> > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi-
> 7AsygbO%g|<oo|
> > F
> >
> zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7
> > mcGpsI
> >
> zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z
> > eLf}n
> > z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_
> > V58p
> >
> z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE;
> > _G
> > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?-
> MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC
> > uL|
> >
> zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y
> > 7
> > z*L9AUT{ijtMS0dcKOCKHpr-
> +xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR
> > p+
> > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi-
> eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS
> > Q!<O&
> > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r-
> sKrwU
> > sCLRyE
> >
> z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1
> > shL
> > zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U
> > e@
> > zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r
> >
> za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp`
> > zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4
> > +q
> > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D-
> B$kndG=Y6ir}mBr@$2Y+D1hg2`
> > HSFo?UV4
> > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs-
> U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73
> > t+H6
> > z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W
> > 0@Pm_Y
> > zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j)
> > zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK
> > zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3
> > z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P
> > z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH
> > z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t
> > $g7Mc
> >
> z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw
> > g4XT
> > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2-
> &x>7Mi3KPo##3Vi5A!D
> > ~zVd
> >
> zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ
> > )g}U
> > zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo
> > aKg
> > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y-
> AD^;!g
> > x|
> > z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3
> > R
> > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V-
> O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v
> > OZ
> >
> z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz-
> > DH
> > z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52
> > m?
> > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET-
> fIoOZ<f~u
> > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol-
> KEmeMx`wo+msu_i=!gCUc5
> > aAFo
> > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o-
> UlMiBIpwFoxSL(w@3J7A9556*;P>na
> > q(Up`
> > z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7
> > zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr
> >
> zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5
> > k7
> >
> zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i
> > ?0^U
> > zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C
> > zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq
> > $
> >
> zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm`
> > `jz`
> >
> zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr
> > T%2I
> > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69-
> HYb
> >
> z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9
> >
> zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh*
> > !tsx
> > zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C
> >
> z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD
> > &
> > zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X
> > @*1fT
> > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr-
> G6WS1r9|13yh@
> > Y{v
> > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6-
> {$zk^x|sZJl
> > O+j
> > zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x
> > LE}S
> > zE-
> yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9`
> > UBK8
> > zQ#_-
> WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s
> > HLzP7
> >
> zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om*
> > TH
> > zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&=
> > w*FLg
> > zsI<EKP=R6SqF-
> IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D
> > k*l
> > z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt
> > gvZ`h
> > zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW?
> > MMr
> > zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j%
> > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u-
> _fVYHP%QJS6G+)Vr9%12
> > >J
> > z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw
> > Mk8(V
> > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)-
> ?sMK$L?>Ng)`3v
> > `R
> >
> z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl
> > NJlM
> > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi-
> f1#Bw(VP<qeg{%cT1IJ97@nLSx
> > z_X-
> ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4
> > 5
> > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4-
> kyiVyjuy47$
> > @|
> > z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk
> > q6<X@
> > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu-
> b=1;<A1a(HF7
> > `i
> > z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y-
> <
> > @
> > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb-
> %NnQFS!>!e+)H<J7
> > %
> >
> z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq
> > )L
> > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh-
> @%MC4@d
> > 0h&s<FN
> > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V-
> _M01I|
> > m8wTMI
> >
> zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld
> > (#T`
> > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK-
> OFjWJG?jVvSoZ_a6
> > jbw
> > zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa
> > qQ
> > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX-
> B8hJF!+PDU)2Ng~^@q8b
> > e+U
> > zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk
> >
> zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo
> >
> zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L
> > cp
> > zKSVWp#RY$Lhkns{H6-
> Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x
> > d}
> >
> zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f
> > zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*-
> i8
> > r$$4
> > zZOqr7#;sW-
> rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_;
> > 4Fzt
> > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob-
> K5PWDTzJUeq*If}X<4`_2c(`X*0
> > z6;L!+h$=hX6x?t-
> Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY
> > <t#vw;
> >
> z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG
> > zsy
> > z&r3>eq@*BKMfN&W*>mt#-
> zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d
> > 4t+{
> >
> zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf
> > is
> >
> ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U;
> > ?2
> >
> zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv
> > *TAdi
> > zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS
> > zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I
> >
> zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l
> > hv
> >
> z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK
> > z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K
> > B(|Tz
> > z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+
> > XbfG
> > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^-
> ;pwarlq8+@E8O5*D1MF
> > F1&w
> > zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud
> >
> zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA
> > ^H
> >
> z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv
> > jX2
> > RBat2OV|2<CTVmi8`9DHIo&o>>
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py
> > b/BaseTools/Source/Python/FMMT/PI/Common.py
> > new file mode 100644
> > index 000000000000..efab874ee08b
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py
> > @@ -0,0 +1,81 @@
> > +## @file
> > +# This file is used to define the common C struct and functions.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from ctypes import *
> > +import uuid
> > +
> > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
> > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> > uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
> > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> > uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
> > +# EFI_FFS_VOLUME_TOP_FILE_GUID =
> > uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
> > +
> > +EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> > uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> > EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
> > +EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> > uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> > b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
> > +EFI_SYSTEM_NVDATA_FV_GUID =
> > uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
> > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE =
> > b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
> > +EFI_FFS_VOLUME_TOP_FILE_GUID =
> > uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
> > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE =
> > b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
> > +ZEROVECTOR_BYTE =
> > b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
> > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
> > +FVH_SIGNATURE = b'_FVH'
> > +
> > +class GUID(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Guid1', c_uint32),
> > + ('Guid2', c_uint16),
> > + ('Guid3', c_uint16),
> > + ('Guid4', ARRAY(c_uint8, 8)),
> > + ]
> > +
> > + def from_list(self, listformat: list) -> None:
> > + self.Guid1 = listformat[0]
> > + self.Guid2 = listformat[1]
> > + self.Guid3 = listformat[2]
> > + for i in range(8):
> > + self.Guid4[i] = listformat[i+3]
> > +
> > + def __cmp__(self, otherguid) -> bool:
> > + if not isinstance(otherguid, GUID):
> > + return 'Input is not the GUID instance!'
> > + rt = False
> > + if self.Guid1 == otherguid.Guid1 and self.Guid2 ==
> otherguid.Guid2
> > and self.Guid3 == otherguid.Guid3:
> > + rt = True
> > + for i in range(8):
> > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
> > + return rt
> > +
> > +def ModifyGuidFormat(target_guid: str) -> GUID:
> > + target_guid = target_guid.replace('-', '')
> > + target_list = []
> > + start = [0,8,12,16,18,20,22,24,26,28,30]
> > + end = [8,12,16,18,20,22,24,26,28,30,32]
> > + num = len(start)
> > + for pos in range(num):
> > + new_value = int(target_guid[start[pos]:end[pos]], 16)
> > + target_list.append(new_value)
> > + new_format = GUID()
> > + new_format.from_list(target_list)
> > + return new_format
> > +
> > +
> > +# Get data from ctypes to bytes.
> > +def struct2stream(s) -> bytes:
> > + length = sizeof(s)
> > + p = cast(pointer(s), POINTER(c_char * length))
> > + return p.contents.raw
> > +
> > +
> > +
> > +def GetPadSize(Size: int, alignment: int) -> int:
> > + if Size % alignment == 0:
> > + return 0
> > + Pad_Size = alignment - Size % alignment
> > + return Pad_Size
> > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > new file mode 100644
> > index 000000000000..33c49ffb50bc
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > @@ -0,0 +1,66 @@
> > +## @file
> > +# This file is used to define the Ffs Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +EFI_FFS_FILE_HEADER_LEN = 24
> > +EFI_FFS_FILE_HEADER2_LEN = 32
> > +
> > +class CHECK_SUM(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Header', c_uint8),
> > + ('File', c_uint8),
> > + ]
> > +
> > +class EFI_FFS_INTEGRITY_CHECK(Union):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Checksum', CHECK_SUM),
> > + ('Checksum16', c_uint16),
> > + ]
> > +
> > +
> > +class EFI_FFS_FILE_HEADER(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Name', GUID),
> > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > + ('Type', c_uint8),
> > + ('Attributes', c_uint8),
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('State', c_uint8),
> > + ]
> > +
> > + @property
> > + def FFS_FILE_SIZE(self) -> int:
> > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > +
> > + @property
> > + def HeaderLength(self) -> int:
> > + return 24
> > +
> > +class EFI_FFS_FILE_HEADER2(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Name', GUID),
> > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > + ('Type', c_uint8),
> > + ('Attributes', c_uint8),
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('State', c_uint8),
> > + ('ExtendedSize', c_uint64),
> > + ]
> > +
> > + @property
> > + def FFS_FILE_SIZE(self) -> int:
> > + return self.ExtendedSize
> > +
> > + @property
> > + def HeaderLength(self) -> int:
> > + return 32
> > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > new file mode 100644
> > index 000000000000..aae2feae844a
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > @@ -0,0 +1,112 @@
> > +## @file
> > +# This file is used to define the FV Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from ast import Str
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +class EFI_FV_BLOCK_MAP_ENTRY(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('NumBlocks', c_uint32),
> > + ('Length', c_uint32),
> > + ]
> > +
> > +
> > +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > + _fields_ = [
> > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > + ('FileSystemGuid', GUID),
> > + ('FvLength', c_uint64),
> > + ('Signature', c_uint32),
> > + ('Attributes', c_uint32),
> > + ('HeaderLength', c_uint16),
> > + ('Checksum', c_uint16),
> > + ('ExtHeaderOffset', c_uint16),
> > + ('Reserved', c_uint8),
> > + ('Revision', c_uint8),
> > + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY,
> > 1)),
> > + ]
> > +
> > +def Refine_FV_Header(nums):
> > + class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > + _fields_ = [
> > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > + ('FileSystemGuid', GUID),
> > + ('FvLength', c_uint64),
> > + ('Signature', c_uint32),
> > + ('Attributes', c_uint32),
> > + ('HeaderLength', c_uint16),
> > + ('Checksum', c_uint16),
> > + ('ExtHeaderOffset', c_uint16),
> > + ('Reserved', c_uint8),
> > + ('Revision', c_uint8),
> > + ('BlockMap',
> > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
> > + ]
> > + return EFI_FIRMWARE_VOLUME_HEADER
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
> > + _fields_ = [
> > + ('FvName', GUID),
> > + ('ExtHeaderSize', c_uint32)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
> > + _fields_ = [
> > + ('ExtEntrySize', c_uint16),
> > + ('ExtEntryType', c_uint16)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32),
> > + ('Types', ARRAY(GUID, 1))
> > + ]
> > +
> > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) ->
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
> > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32),
> > + ('Types', ARRAY(GUID, nums))
> > + ]
> > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID),
> > + ('Data', ARRAY(c_uint8, 1))
> > + ]
> > +
> > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) ->
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
> > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID),
> > + ('Data', ARRAY(c_uint8, nums))
> > + ]
> > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr',
> > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('UsedSize', c_uint32)
> > + ]
> > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > new file mode 100644
> > index 000000000000..c2cc8e0172fb
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > @@ -0,0 +1,110 @@
> > +## @file
> > +# This file is used to define the Section Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +EFI_COMMON_SECTION_HEADER_LEN = 4
> > +EFI_COMMON_SECTION_HEADER2_LEN = 8
> > +
> > +class EFI_COMMON_SECTION_HEADER(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('Type', c_uint8),
> > + ]
> > +
> > + @property
> > + def SECTION_SIZE(self) -> int:
> > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > +
> > + def Common_Header_Size(self) -> int:
> > + return 4
> > +
> > +class EFI_COMMON_SECTION_HEADER2(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('Type', c_uint8),
> > + ('ExtendedSize', c_uint32),
> > + ]
> > +
> > + @property
> > + def SECTION_SIZE(self) -> int:
> > + return self.ExtendedSize
> > +
> > + def Common_Header_Size(self) -> int:
> > + return 8
> > +
> > +class EFI_COMPRESSION_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('UncompressedLength', c_uint32),
> > + ('CompressionType', c_uint8),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 5
> > +
> > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('SubTypeGuid', GUID),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 16
> > +
> > +class EFI_GUID_DEFINED_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('SectionDefinitionGuid', GUID),
> > + ('DataOffset', c_uint16),
> > + ('Attributes', c_uint16),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 20
> > +
> > +def Get_USER_INTERFACE_Header(nums: int):
> > + class EFI_SECTION_USER_INTERFACE(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('FileNameString', ARRAY(c_uint16, nums)),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 2 * nums
> > +
> > + def GetUiString(self) -> str:
> > + UiString = ''
> > + for i in range(nums):
> > + if self.FileNameString[i]:
> > + UiString += chr(self.FileNameString[i])
> > + return UiString
> > +
> > + return EFI_SECTION_USER_INTERFACE
> > +
> > +def Get_VERSION_Header(nums: int):
> > + class EFI_SECTION_VERSION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('BuildNumber', c_uint16),
> > + ('VersionString', ARRAY(c_uint16, nums)),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 2 * (nums+1)
> > +
> > + def GetVersionString(self) -> str:
> > + VersionString = ''
> > + for i in range(nums):
> > + if self.VersionString[i]:
> > + VersionString += chr(self.VersionString[i])
> > + return VersionString
> > +
> > + return EFI_SECTION_VERSION
> > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py
> > b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > new file mode 100644
> > index 000000000000..4e8296fad1ba
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > @@ -0,0 +1,6 @@
> > +## @file
> > +# This file is used to define the FMMT dependent external tool
> management
> > class.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/README.md
> > b/BaseTools/Source/Python/FMMT/README.md
> > new file mode 100644
> > index 000000000000..e14dfa34ea66
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/README.md
> > @@ -0,0 +1,180 @@
> > +# FMMT
> > +## Overview
> > +This FMMT tool is the python implementation of the edk2 FMMT tool
> which
> > locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
> > +This implementation has the same usage as the edk2 FMMT, but it's more
> > readable and relaiable.
> > +
> > +# FMMT User Guide
> > +
> > +#### Last updated October 13, 2021
> > +
> > +Important Changes and Updates:
> > +
> > +- Oct 13, 2021 Initial Draft of FMMT Python Tool
> > +
> > +#### Note:
> > +
> > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is
> > much easier to maintain and extend other functions.
> > +
> > +
> > +
> > +# 1. Introduction
> > +
> > +## 1.1 Overview
> > +
> > +The Firmware Device is a persistent physical repository that contains
> > firmware code and/or data. The firmware code and/or data stored in
> > Firmware Volumes. Detail layout of Firmware Volumes is described in
> ?Figure
> > 1. The Firmware Volume Format?.
> > +
> > +![](Img/FirmwareVolumeFormat.png)
> > +
> > +<center>Figure 1. The Firmware Volume Format</center>
> > +
> > +In firmware development, binary file has its firmware layout following
> the
> > Platform-Initialization Specification. Thus, operation on FV file / FFS
> file
> > (Firmware File) is an efficient and convenient way for firmware function
> > testing and developing. FMMT Python tool is used for firmware files
> > operation.
> > +
> > +## 1.2 Tool Capabilities
> > +
> > +The FMMT tool is capable of:
> > +
> > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware
> > Files)
> > +
> > +- Add a new FFS into a FV file (both included in a FD file or not)
> > +
> > +- Replace an FFS in a FV file with a new FFS file
> > +
> > +- Delete an FFS in a FV file (both included in a FD file or not)
> > +
> > +- Extract the FFS from a FV file (both includ-v < Inputfile > <
> Outputfile >ed
> > in a FD file or not)
> > +
> > +## 1.3 References
> > +
> > +| Document |
> > +| ------------------------------------------------ |
> > +| UEFI Platform Initialization (PI) Specification |
> > +
> > +
> > +
> > +# 2. FMMT Python Tool Usage
> > +
> > +## 2.1 Required Files
> > +
> > +### 2.1.1 Independent use
> > +
> > +When independent use the FMMT Python Tool, the following files and
> > settings are required:
> > +
> > +- GuidTool executable files used for Decompress/Compress Firmware data.
> > +
> > +- Environment variables path with GuidTool path setting.
> > +
> > +### 2.1.2 Use with Build System
> > +
> > +When use the FMMT Python Tool with Build System:
> > +
> > +- If only use Edk2 based GuidTool, do not need other preparation.
> > +
> > +- If use other customized GuidTool, need prepare the config file with
> GuidTool
> > info. The syntax for GuidTool definition shown as follow:
> > +
> > + ***ToolsGuid ShortName Command***
> > +
> > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI
> > BrotliCompress***
> > +
> > +## 2.2 Syntax
> > +
> > +### 2.2.1 Syntax for Parse file
> > +
> > +***-v < Inputfile > < Outputfile > -l < LogFileType >***
> > +
> > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile*
> is
> > optional, if inputs, the *Inputfile* will be encapsulated into
> *Outputfile*
> > following the parsed firmware layout. *"-l LogFileType"* is optional, it
> decides
> > the format of log file which saves Binary layout. Currently supports:
> json, txt.
> > More formats will be added in the future.
> > +
> > +### 2.2.2 Syntax for Add a new FFS
> > +
> > +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > <
> > Outputfile >***
> > +
> > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid*
> > (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
> > +
> > +### 2.2.3 Syntax for Delete an FFS
> > +
> > +***-d < Inputfile > < TargetFfsName > < Outputfile > <
> > TargetFvName/TargetFvGuid >***
> > +
> > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs
> > which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is
> the
> > parent of TargetFfs*.*
> > +
> > +### 2.2.4 Syntax for Replace an FFS
> > +
> > +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > <
> > TargetFvName/TargetFvGuid >***
> > +
> > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the
> TargetFfs
> > which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is
> > the parent of TargetFfs*.*
> > +
> > +### 2.2.5 Syntax for Extract an FFS
> > +
> > +***-e < Inputfile > < TargetFfsName > < Outputfile >***
> > +
> > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the
> TargetFfs
> > which will be extracted.
> > +
> > +
> > +
> > +# 3. FMMT Python Tool Design
> > +
> > +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each
> > Node have its Data field, which saves the
> > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the
> > parse/add/delete/replace/extract operations are based on the NodeTree
> > (adjusting the layout and data).
> > +
> > +## 3.1 NodeTree
> > +
> > +A whole NodeTree saves all the Firmware info.
> > +
> > +- Parent & Child relationship figured out the Firmware layout.
> > +
> > +- Each Node have several fields. ?Data? field saves an FirmwareClass
> > instance which contains all the data info of the info.
> > +
> > +### 3.1.1 NodeTree Format
> > +
> > +The NodeTree will be created with parse function. When parse a file, a
> Root
> > Node will be initialized firstly. The Data split and Tree construction
> process is
> > described with an FD file shown as ?Figure 2. The NodeTree format?:
> > +
> > +- A Root Node is initialized.
> > +
> > +- Use the ?FV Signature? as FV key to split Whole FD
> > Data. ?FV0?, ?FV1?, ?FV2?? Node created.
> > +
> > +- After FV level Node created, use the ?Ffs Data Size? as FFS key to
> split each
> > FV Data. ?Ffs0?...Node created.
> > +
> > +- After FFS level Node created, use the ?Section Data Size? as Section
> key to
> > split each Ffs Data. ?Section0?...Node created.
> > +
> > +- If some of Section includes other Sections, continue use the ?Section
> Data
> > Size? as Section key to split each Section Data.
> > +
> > +- After all Node created, the whole NodeTree saves all the info. (Can be
> used
> > in other functions or print the whole firmware layout into log file)
> > +
> > +![](Img/NodeTreeFormat.png)
> > +
> > +<center>Figure 2. The NodeTree format</center>
> > +
> > +### 3.1.2 Node Factory and Product
> > +
> > +As 3.1.1, Each Node is created by data split and recognition. To extend
> the
> > NodeTree usage, Factory pattern is used in Node created process.
> > +
> > +Each Node have its Factory to create Product and use Product ParserData
> > function to deal with the data.
> > +
> > +## 3.2 GuidTool
> > +
> > +There are two ways to set the GuidTool. One from Config file, another
> from
> > environment variables.
> > +
> > +Current GuidTool first check if has Config file.
> > +
> > +- If have, load the config GuidTool Information.
> > +
> > +- Else get from environment variables.
> > +
> > +### 3.2.1 Get from Config file
> > +
> > +- Config file should in same folder with FMMT.py or the path in
> environment
> > variables.
> > +
> > +- Content should follow the format:
> > +
> > + ***ToolsGuid ShortName Command***
> > +
> > +### 3.2.2 Get from Environment Variables
> > +
> > +- The GuidTool Command used must be set in environment variables.
> > +
> > +### 3.2.3 Edk2 Based GuidTool
> > +
> > +| ***Guid*** | ***ShortName***
> > | ***Command*** |
> > +| ------------------------------------------ | --------------- |
> --------------------- |
> > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** |
> > ***TianoCompress*** |
> > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** |
> > ***LzmaCompress*** |
> > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** |
> > ***GenCrc32*** |
> > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** |
> > ***LzmaF86Compress*** |
> > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** |
> > ***BrotliCompress*** |
> > diff --git a/BaseTools/Source/Python/FMMT/__init__.py
> > b/BaseTools/Source/Python/FMMT/__init__.py
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > new file mode 100644
> > index 000000000000..33ffe73cab27
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > @@ -0,0 +1,371 @@
> > +## @file
> > +# This file is used to implement of the various bianry parser.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from re import T
> > +import copy
> > +import os
> > +from PI.Common import *
> > +from core.BiosTreeNode import *
> > +from core.BiosTree import *
> > +from core.GuidTools import *
> > +
> > +ROOT_TREE = 'ROOT'
> > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > +
> > +FV_TREE = 'FV'
> > +DATA_FV_TREE = 'DATA_FV'
> > +FFS_TREE = 'FFS'
> > +FFS_PAD = 'FFS_PAD'
> > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > +SECTION_TREE = 'SECTION'
> > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > +BINARY_DATA = 'BINARY'
> > +Fv_count = 0
> > +
> > +## Abstract factory
> > +class BinaryFactory():
> > + type:list = []
> > +
> > + def Create_Product():
> > + pass
> > +
> > +class BinaryProduct():
> > + ## Use GuidTool to decompress data.
> > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
> > + ParPath =
> >
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
> ")
> > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > + guidtool =
> > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > + DecompressedData = guidtool.unpack(Section_Data)
> > + return DecompressedData
> > +
> > + def ParserData():
> > + pass
> > +
> > +class SectionFactory(BinaryFactory):
> > + type = [SECTION_TREE]
> > +
> > + def Create_Product():
> > + return SectionProduct()
> > +
> > +class FfsFactory(BinaryFactory):
> > + type = [ROOT_SECTION_TREE, FFS_TREE]
> > +
> > + def Create_Product():
> > + return FfsProduct()
> > +
> > +class FvFactory(BinaryFactory):
> > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
> > +
> > + def Create_Product():
> > + return FvProduct()
> > +
> > +class FdFactory(BinaryFactory):
> > + type = [ROOT_FV_TREE, ROOT_TREE]
> > +
> > + def Create_Product():
> > + return FdProduct()
> > +
> > +class SectionProduct(BinaryProduct):
> > + ## Decompress the compressed section.
> > + def ParserData(self, Section_Tree, whole_Data: bytes,
> > Rel_Whole_Offset: int=0) -> None:
> > + if Section_Tree.Data.Type == 0x01:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + self.ParserFfs(Section_Tree, b'')
> > + # Guided Define Section
> > + elif Section_Tree.Data.Type == 0x02:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + DeCompressGuidTool =
> > Section_Tree.Data.ExtHeader.SectionDefinitionGuid
> > + Section_Tree.Data.Data =
> > self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
> > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) +
> > Section_Tree.Data.HeaderLength
> > + self.ParserFfs(Section_Tree, b'')
> > + elif Section_Tree.Data.Type == 0x03:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + self.ParserFfs(Section_Tree, b'')
> > + # SEC_FV Section
> > + elif Section_Tree.Data.Type == 0x17:
> > + global Fv_count
> > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
> > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
> > + Sec_Fv_Tree.type = SEC_FV_TREE
> > + Sec_Fv_Tree.Data = Sec_Fv_Info
> > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
> > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset +
> > Sec_Fv_Tree.Data.Header.HeaderLength
> > + Sec_Fv_Tree.Data.Data =
> > Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
> > + Section_Tree.insertChild(Sec_Fv_Tree)
> > + Fv_count += 1
> > +
> > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > int=0) -> None:
> > + Rel_Offset = 0
> > + Section_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get
> it
> > from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Section_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Section recorded in its
> Parent
> > Section.
> > + while Rel_Offset < Data_Size:
> > + # Create a SectionNode and set it as the SectionTree's Data
> > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > + Section_Tree = BIOSTREE(Section_Info.Name)
> > + Section_Tree.type = SECTION_TREE
> > + Section_Info.Data =
> > Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> > Rel_Offset+Section_Info.Size]
> > + Section_Info.DOffset = Section_Offset +
> > Section_Info.HeaderLength + Rel_Whole_Offset
> > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> > + Section_Info.ROffset = Rel_Offset
> > + if Section_Info.Header.Type == 0:
> > + break
> > + # The final Section in parent Section does not need to add
> > padding, else must be 4-bytes align with parent Section start offset
> > + Pad_Size = 0
> > + if
> > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> Data_Size):
> > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > + Section_Info.PadData = Pad_Size * b'\x00'
> > + if Section_Info.Header.Type == 0x02:
> > + Section_Info.DOffset = Section_Offset +
> > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > + Section_Info.Data =
> > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > Rel_Offset+Section_Info.Size]
> > + if Section_Info.Header.Type == 0x14:
> > + ParTree.Data.Version =
> > Section_Info.ExtHeader.GetVersionString()
> > + if Section_Info.Header.Type == 0x15:
> > + ParTree.Data.UiName =
> > Section_Info.ExtHeader.GetUiString()
> > + Section_Offset += Section_Info.Size + Pad_Size
> > + Rel_Offset += Section_Info.Size + Pad_Size
> > + Section_Tree.Data = Section_Info
> > + ParTree.insertChild(Section_Tree)
> > +
> > +class FfsProduct(BinaryProduct):
> > + # ParserFFs / GetSection
> > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > int=0) -> None:
> > + Rel_Offset = 0
> > + Section_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get
> it
> > from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Section_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Section recorded in Ffs.
> > + while Rel_Offset < Data_Size:
> > + # Create a SectionNode and set it as the SectionTree's Data
> > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > + Section_Tree = BIOSTREE(Section_Info.Name)
> > + Section_Tree.type = SECTION_TREE
> > + Section_Info.Data =
> > Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> > Rel_Offset+Section_Info.Size]
> > + Section_Info.DOffset = Section_Offset +
> > Section_Info.HeaderLength + Rel_Whole_Offset
> > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> > + Section_Info.ROffset = Rel_Offset
> > + if Section_Info.Header.Type == 0:
> > + break
> > + # The final Section in Ffs does not need to add padding, else
> > must be 4-bytes align with Ffs start offset
> > + Pad_Size = 0
> > + if
> > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> Data_Size):
> > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > + Section_Info.PadData = Pad_Size * b'\x00'
> > + if Section_Info.Header.Type == 0x02:
> > + Section_Info.DOffset = Section_Offset +
> > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > + Section_Info.Data =
> > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > Rel_Offset+Section_Info.Size]
> > + # If Section is Version or UI type, it saves the version and
> UI
> > info of its parent Ffs.
> > + if Section_Info.Header.Type == 0x14:
> > + ParTree.Data.Version =
> > Section_Info.ExtHeader.GetVersionString()
> > + if Section_Info.Header.Type == 0x15:
> > + ParTree.Data.UiName =
> > Section_Info.ExtHeader.GetUiString()
> > + Section_Offset += Section_Info.Size + Pad_Size
> > + Rel_Offset += Section_Info.Size + Pad_Size
> > + Section_Tree.Data = Section_Info
> > + ParTree.insertChild(Section_Tree)
> > +
> > +class FvProduct(BinaryProduct):
> > + ## ParserFv / GetFfs
> > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > int=0) -> None:
> > + Ffs_Offset = 0
> > + Rel_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get
> it
> > from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Ffs_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Ffs recorded in Fv.
> > + while Rel_Offset < Data_Size:
> > + # Create a FfsNode and set it as the FFsTree's Data
> > + if Data_Size - Rel_Offset < 24:
> > + Ffs_Tree = BIOSTREE('Free_Space')
> > + Ffs_Tree.type = FFS_FREE_SPACE
> > + Ffs_Tree.Data =
> > FreeSpaceNode(Whole_Data[Rel_Offset:])
> > + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
> > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
> > + ParTree.Data.Free_Space = Data_Size - Rel_Offset
> > + ParTree.insertChild(Ffs_Tree)
> > + Rel_Offset = Data_Size
> > + else:
> > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
> > + Ffs_Tree = BIOSTREE(Ffs_Info.Name)
> > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
> > + Ffs_Info.DOffset = Ffs_Offset +
> > Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
> > + Ffs_Info.ROffset = Rel_Offset
> > + if Ffs_Info.Name == PADVECTOR:
> > + Ffs_Tree.type = FFS_PAD
> > + Ffs_Info.Data =
> > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> > Rel_Offset+Ffs_Info.Size]
> > + Ffs_Info.Size = len(Ffs_Info.Data) +
> > Ffs_Info.Header.HeaderLength
> > + # if current Ffs is the final ffs of Fv and full of
> b'\xff',
> > define it with Free_Space
> > + if struct2stream(Ffs_Info.Header).replace(b'\xff',
> b'')
> > == b'':
> > + Ffs_Tree.type = FFS_FREE_SPACE
> > + Ffs_Info.Data = Whole_Data[Rel_Offset:]
> > + Ffs_Info.Size = len(Ffs_Info.Data)
> > + ParTree.Data.Free_Space = Ffs_Info.Size
> > + else:
> > + Ffs_Tree.type = FFS_TREE
> > + Ffs_Info.Data =
> > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> > Rel_Offset+Ffs_Info.Size]
> > + # The final Ffs in Fv does not need to add padding, else
> > must be 8-bytes align with Fv start offset
> > + Pad_Size = 0
> > + if Ffs_Tree.type != FFS_FREE_SPACE and
> > (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) !=
> Data_Size):
> > + Pad_Size = GetPadSize(Ffs_Info.Size, 8)
> > + Ffs_Info.PadData = Pad_Size * b'\xff'
> > + Ffs_Offset += Ffs_Info.Size + Pad_Size
> > + Rel_Offset += Ffs_Info.Size + Pad_Size
> > + Ffs_Tree.Data = Ffs_Info
> > + ParTree.insertChild(Ffs_Tree)
> > +
> > +class FdProduct(BinaryProduct):
> > + type = [ROOT_FV_TREE, ROOT_TREE]
> > +
> > + ## Create DataTree with first level /fv Info, then parser each Fv.
> > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset:
> int=0) ->
> > None:
> > + # Get all Fv image in Fd with offset and length
> > + Fd_Struct = self.GetFvFromFd(whole_data)
> > + data_size = len(whole_data)
> > + Binary_count = 0
> > + global Fv_count
> > + # If the first Fv image is the Binary Fv, add it into the tree.
> > + if Fd_Struct[0][1] != 0:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset = 0 + offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > + # Add the first collected Fv image into the tree.
> > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
> > + Cur_node.type = Fd_Struct[0][0]
> > + Cur_node.Data = FvNode(Fv_count,
> > whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
> > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
> > + Cur_node.Data.DOffset =
> > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > + Cur_node.Data.Data =
> >
> whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct
> > [0][1]+Cur_node.Data.Size]
> > + WholeFvTree.insertChild(Cur_node)
> > + Fv_count += 1
> > + Fv_num = len(Fd_Struct)
> > + # Add all the collected Fv image and the Binary Fv image between
> > them into the tree.
> > + for i in range(Fv_num-1):
> > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data =
> > whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset =
> > Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
> > + Cur_node.type = Fd_Struct[i+1][0]
> > + Cur_node.Data = FvNode(Fv_count,
> > whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
> > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
> > + Cur_node.Data.DOffset =
> > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > + Cur_node.Data.Data =
> >
> whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru
> > ct[i+1][1]+Cur_node.Data.Size]
> > + WholeFvTree.insertChild(Cur_node)
> > + Fv_count += 1
> > + # If the final Fv image is the Binary Fv, add it into the tree
> > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data =
> > whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset =
> > Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > +
> > + ## Get the first level Fv from Fd file.
> > + def GetFvFromFd(self, whole_data: bytes=b'') -> list:
> > + Fd_Struct = []
> > + data_size = len(whole_data)
> > + cur_index = 0
> > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV
> > image offset and length.
> > + while cur_index < data_size:
> > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in
> > whole_data[cur_index:]:
> > + target_index =
> > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE)
> +
> > cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > ZEROVECTOR_BYTE:
> > + Fd_Struct.append([FV_TREE, target_index - 16,
> > unpack("Q", whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + cur_index = 0
> > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV
> > image offset and length.
> > + while cur_index < data_size:
> > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in
> > whole_data[cur_index:]:
> > + target_index =
> > whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE)
> +
> > cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > ZEROVECTOR_BYTE:
> > + Fd_Struct.append([FV_TREE, target_index - 16,
> > unpack("Q", whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + cur_index = 0
> > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image
> > offset and length.
> > + while cur_index < data_size:
> > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in
> > whole_data[cur_index:]:
> > + target_index =
> > whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) +
> > cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > ZEROVECTOR_BYTE:
> > + Fd_Struct.append([DATA_FV_TREE, target_index -
> > 16, unpack("Q", whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + # Sort all the collect Fv image with offset.
> > + Fd_Struct.sort(key=lambda x:x[1])
> > + tmp_struct = copy.deepcopy(Fd_Struct)
> > + tmp_index = 0
> > + Fv_num = len(Fd_Struct)
> > + # Remove the Fv image included in another Fv image.
> > + for i in range(1,Fv_num):
> > + if tmp_struct[i][1]+tmp_struct[i][2][0] <
> > tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
> > + Fd_Struct.remove(Fd_Struct[i-tmp_index])
> > + tmp_index += 1
> > + return Fd_Struct
> > +
> > +class ParserEntry():
> > + FactoryTable:dict = {
> > + SECTION_TREE: SectionFactory,
> > + ROOT_SECTION_TREE: FfsFactory,
> > + FFS_TREE: FfsFactory,
> > + ROOT_FFS_TREE: FvFactory,
> > + FV_TREE: FvFactory,
> > + SEC_FV_TREE: FvFactory,
> > + ROOT_FV_TREE: FdFactory,
> > + ROOT_TREE: FdFactory,
> > + }
> > +
> > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
> > + if Tree_type in self.FactoryTable:
> > + return self.FactoryTable[Tree_type]
> > +
> > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data:
> > bytes, Offset: int) -> None:
> > + New_Product = TargetFactory.Create_Product()
> > + New_Product.ParserData(Tree, Data, Offset)
> > +
> > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
> > + TargetFactory = self.GetTargetFactory(Tree.type)
> > + if TargetFactory:
> > + self.Generate_Product(TargetFactory, Tree, Data, Offset)
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > new file mode 100644
> > index 000000000000..0b6252ecc1bb
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > @@ -0,0 +1,198 @@
> > +## @file
> > +# This file is used to define the Bios layout tree structure and related
> > operations.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import collections
> > +from PI.Common import *
> > +
> > +ROOT_TREE = 'ROOT'
> > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > +
> > +FV_TREE = 'FV'
> > +DATA_FV_TREE = 'DATA_FV'
> > +FFS_TREE = 'FFS'
> > +FFS_PAD = 'FFS_PAD'
> > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > +SECTION_TREE = 'SECTION'
> > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > +BINARY_DATA = 'BINARY'
> > +
> > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE,
> > ROOT_SECTION_TREE]
> > +FvType = [FV_TREE, SEC_FV_TREE]
> > +FfsType = FFS_TREE
> > +SecType = SECTION_TREE
> > +
> > +class BIOSTREE:
> > + def __init__(self, NodeName: str) -> None:
> > + self.key = NodeName
> > + self.type = None
> > + self.Data = None
> > + self.Child = []
> > + self.Findlist = []
> > + self.Parent = None
> > + self.NextRel = None
> > + self.LastRel = None
> > +
> > + def HasChild(self) -> bool:
> > + if self.Child == []:
> > + return False
> > + else:
> > + return True
> > +
> > + def isFinalChild(self) -> bool:
> > + ParTree = self.Parent
> > + if ParTree:
> > + if ParTree.Child[-1] == self:
> > + return True
> > + return False
> > +
> > + # FvTree.insertChild()
> > + def insertChild(self, newNode, pos: int=None) -> None:
> > + if len(self.Child) == 0:
> > + self.Child.append(newNode)
> > + else:
> > + if not pos:
> > + LastTree = self.Child[-1]
> > + self.Child.append(newNode)
> > + LastTree.NextRel = newNode
> > + newNode.LastRel = LastTree
> > + else:
> > + newNode.NextRel = self.Child[pos-1].NextRel
> > + newNode.LastRel = self.Child[pos].LastRel
> > + self.Child[pos-1].NextRel = newNode
> > + self.Child[pos].LastRel = newNode
> > + self.Child.insert(pos, newNode)
> > + newNode.Parent = self
> > +
> > + # lastNode.insertRel(newNode)
> > + def insertRel(self, newNode) -> None:
> > + if self.Parent:
> > + parentTree = self.Parent
> > + new_index = parentTree.Child.index(self) + 1
> > + parentTree.Child.insert(new_index, newNode)
> > + self.NextRel = newNode
> > + newNode.LastRel = self
> > +
> > + def deleteNode(self, deletekey: str) -> None:
> > + FindStatus, DeleteTree = self.FindNode(deletekey)
> > + if FindStatus:
> > + parentTree = DeleteTree.Parent
> > + lastTree = DeleteTree.LastRel
> > + nextTree = DeleteTree.NextRel
> > + if parentTree:
> > + index = parentTree.Child.index(DeleteTree)
> > + del parentTree.Child[index]
> > + if lastTree and nextTree:
> > + lastTree.NextRel = nextTree
> > + nextTree.LastRel = lastTree
> > + elif lastTree:
> > + lastTree.NextRel = None
> > + elif nextTree:
> > + nextTree.LastRel = None
> > + return DeleteTree
> > + else:
> > + print('Could not find the target tree')
> > + return None
> > +
> > + def FindNode(self, key: str, Findlist: list) -> None:
> > + if self.key == key or (self.Data and self.Data.Name == key) or
> > (self.type == FFS_TREE and self.Data.UiName == key):
> > + Findlist.append(self)
> > + else:
> > + for item in self.Child:
> > + item.FindNode(key, Findlist)
> > +
> > + def GetTreePath(self):
> > + BiosTreePath = [self]
> > + while self.Parent:
> > + BiosTreePath.insert(0, self.Parent)
> > + self = self.Parent
> > + return BiosTreePath
> > +
> > + def parserTree(self, TargetDict: dict=None, Info: list=None, space:
> int=0,
> > ParFvId="") -> None:
> > + Key = list(TargetDict.keys())[0]
> > + if TargetDict[Key]["Type"] in RootType:
> > + Info.append("Image File: {}".format(Key))
> > + Info.append("FilesNum:
> > {}".format(TargetDict.get(Key).get('FilesNum')))
> > + Info.append("\n")
> > + elif TargetDict[Key]["Type"] in FvType:
> > + space += 2
> > + if TargetDict[Key]["Type"] == SEC_FV_TREE:
> > + Info.append("{}Child FV named {} of {}".format(space*" ",
> > Key, ParFvId))
> > + space += 2
> > + else:
> > + Info.append("FvId: {}".format(Key))
> > + ParFvId = Key
> > + Info.append("{}FvNameGuid: {}".format(space*" ",
> > TargetDict.get(Key).get('FvNameGuid')))
> > + Info.append("{}Attributes: {}".format(space*" ",
> > TargetDict.get(Key).get('Attributes')))
> > + Info.append("{}Total Volume Size: {}".format(space*" ",
> > TargetDict.get(Key).get('Size')))
> > + Info.append("{}Free Volume Size: {}".format(space*" ",
> > TargetDict.get(Key).get('FreeSize')))
> > + Info.append("{}Volume Offset: {}".format(space*" ",
> > TargetDict.get(Key).get('Offset')))
> > + Info.append("{}FilesNum: {}".format(space*" ",
> > TargetDict.get(Key).get('FilesNum')))
> > + elif TargetDict[Key]["Type"] in FfsType:
> > + space += 2
> > + if TargetDict.get(Key).get('UiName') != "b''":
> > + Info.append("{}File: {} / {}".format(space*" ", Key,
> > TargetDict.get(Key).get('UiName')))
> > + else:
> > + Info.append("{}File: {}".format(space*" ", Key))
> > + if "Files" in list(TargetDict[Key].keys()):
> > + for item in TargetDict[Key]["Files"]:
> > + self.parserTree(item, Info, space, ParFvId)
> > +
> > + def ExportTree(self,TreeInfo: dict=None) -> dict:
> > + if TreeInfo is None:
> > + TreeInfo =collections.OrderedDict()
> > +
> > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or
> > self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
> > + key = str(self.key)
> > + TreeInfo[self.key] = collections.OrderedDict()
> > + TreeInfo[self.key]["Name"] = key
> > + TreeInfo[self.key]["Type"] = self.type
> > + TreeInfo[self.key]["FilesNum"] = len(self.Child)
> > + elif self.type == FV_TREE or self.type == SEC_FV_TREE:
> > + key = str(self.Data.FvId)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + if self.Data.FvId != self.Data.Name:
> > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Attributes"] =
> hex(self.Data.Header.Attributes)
> > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
> > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self.type == FFS_TREE:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
> > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self.type == SECTION_TREE and self.Data.Type == 0x02:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) +
> > self.Data.HeaderLength)
> > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self is not None:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > +
> > + for item in self.Child:
> > + TreeInfo[key].setdefault('Files',[]).append(
> item.ExportTree())
> > +
> > + return TreeInfo
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > new file mode 100644
> > index 000000000000..cfb711eea5a2
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > @@ -0,0 +1,191 @@
> > +## @file
> > +# This file is used to define the BIOS Tree Node.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from PI.FvHeader import *
> > +from PI.FfsFileHeader import *
> > +from PI.SectionHeader import *
> > +from PI.Common import *
> > +import uuid
> > +
> > +SectionHeaderType = {
> > + 0x01:'EFI_COMPRESSION_SECTION',
> > + 0x02:'EFI_GUID_DEFINED_SECTION',
> > + 0x03:'EFI_SECTION_DISPOSABLE',
> > + 0x10:'EFI_SECTION_PE32',
> > + 0x11:'EFI_SECTION_PIC',
> > + 0x12:'EFI_SECTION_TE',
> > + 0x13:'EFI_SECTION_DXE_DEPEX',
> > + 0x14:'EFI_SECTION_VERSION',
> > + 0x15:'EFI_SECTION_USER_INTERFACE',
> > + 0x16:'EFI_SECTION_COMPATIBILITY16',
> > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
> > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
> > + 0x19:'EFI_SECTION_RAW',
> > + 0x1B:'EFI_SECTION_PEI_DEPEX',
> > + 0x1C:'EFI_SECTION_MM_DEPEX'
> > +}
> > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
> > +
> > +class BinaryNode:
> > + def __init__(self, name: str) -> None:
> > + self.Size = 0
> > + self.Name = "BINARY" + str(name)
> > + self.HOffset = 0
> > + self.Data = b''
> > +
> > +class FvNode:
> > + def __init__(self, name, buffer: bytes) -> None:
> > + self.Header =
> > EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
> > + Map_num = (self.Header.HeaderLength - 56)//8
> > + self.Header =
> > Refine_FV_Header(Map_num).from_buffer_copy(buffer)
> > + self.FvId = "FV" + str(name)
> > + self.Name = "FV" + str(name)
> > + if self.Header.ExtHeaderOffset:
> > + self.ExtHeader =
> >
> EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Heade
> r
> > .ExtHeaderOffset:])
> > + self.Name =
> > uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
> > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
> > + if self.ExtHeader.ExtHeaderSize != 20:
> > + self.ExtEntryExist = 1
> > + self.ExtEntry =
> >
> EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry
> > Offset:])
> > + self.ExtTypeExist = 1
> > + if self.ExtEntry.ExtEntryType == 0x01:
> > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16
> > + self.ExtEntry =
> >
> Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[
> s
> > elf.ExtEntryOffset:])
> > + elif self.ExtEntry.ExtEntryType == 0x02:
> > + nums = self.ExtEntry.ExtEntrySize - 20
> > + self.ExtEntry =
> >
> Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer
> [
> > self.ExtEntryOffset:])
> > + elif self.ExtEntry.ExtEntryType == 0x03:
> > + self.ExtEntry =
> >
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b
> > uffer[self.ExtEntryOffset:])
> > + else:
> > + self.ExtTypeExist = 0
> > + else:
> > + self.ExtEntryExist = 0
> > + self.Size = self.Header.FvLength
> > + self.HeaderLength = self.Header.HeaderLength
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + if self.Header.Signature != 1213613663:
> > + print('Invalid! Fv Header Signature {} is not
> > "_FVH".'.format(self.Header.Signature))
> > + with open(str(self.Name)+'.fd', "wb") as f:
> > + f.write(struct2stream(self.Header))
> > + assert False
> > + self.PadData = b''
> > + self.Free_Space = 0
> > + self.ModCheckSum()
> > +
> > + def ModCheckSum(self) -> None:
> > + # Fv Header Sums to 0.
> > + Header = struct2stream(self.Header)[::-1]
> > + Size = self.HeaderLength // 2
> > + Sum = 0
> > + for i in range(Size):
> > + Sum += int(Header[i*2: i*2 + 2].hex(), 16)
> > + if Sum & 0xffff:
> > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum -
> > self.Header.Checksum)[-4:], 16)), 16)
> > +
> > + def ModFvExt(self) -> None:
> > + # If used space changes and self.ExtEntry.UsedSize exists,
> > self.ExtEntry.UsedSize need to be changed.
> > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and
> > self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03:
> > + self.ExtEntry.UsedSize = self.Header.FvLength -
> > self.Free_Space
> > +
> > + def ModFvSize(self) -> None:
> > + # If Fv Size changed, self.Header.FvLength and
> > self.Header.BlockMap[i].NumBlocks need to be changed.
> > + BlockMapNum = len(self.Header.BlockMap)
> > + for i in range(BlockMapNum):
> > + if self.Header.BlockMap[i].Length:
> > + self.Header.BlockMap[i].NumBlocks =
> > self.Header.FvLength // self.Header.BlockMap[i].Length
> > +
> > + def ModExtHeaderData(self) -> None:
> > + if self.Header.ExtHeaderOffset:
> > + ExtHeaderData = struct2stream(self.ExtHeader)
> > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset -
> > self.HeaderLength
> > + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData
> > + self.Data[ExtHeaderDataOffset+20:]
> > + if self.Header.ExtHeaderOffset and self.ExtEntryExist:
> > + ExtHeaderEntryData = struct2stream(self.ExtEntry)
> > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset +
> > 20 - self.HeaderLength
> > + self.Data = self.Data[:ExtHeaderEntryDataOffset] +
> > ExtHeaderEntryData +
> > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
> > +
> > +class FfsNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
> > + # self.Attributes = unpack("<B", buffer[21:22])[0]
> > + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes !=
> 0xff
> > and self.Header.Attributes & 0x01 == 1:
> > + print('Error Ffs Header! Ffs Header Size and Attributes is
> not
> > matched!')
> > + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes &
> > 0x01 == 1:
> > + self.Header =
> > EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
> > + self.Name =
> > uuid.UUID(bytes_le=struct2stream(self.Header.Name))
> > + self.UiName = b''
> > + self.Version = b''
> > + self.Size = self.Header.FFS_FILE_SIZE
> > + self.HeaderLength = self.Header.HeaderLength
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + self.PadData = b''
> > +
> > + def ModCheckSum(self) -> None:
> > + HeaderData = struct2stream(self.Header)
> > + HeaderSum = 0
> > + for item in HeaderData:
> > + HeaderSum += item
> > + HeaderSum -= self.Header.State
> > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File
> > + if HeaderSum & 0xff:
> > + Header = self.Header.IntegrityCheck.Checksum.Header +
> > 0x100 - int(hex(HeaderSum)[-2:], 16)
> > + self.Header.IntegrityCheck.Checksum.Header =
> > int(hex(Header)[-2:], 16)
> > +
> > +class SectionNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + if buffer[0:3] != b'\xff\xff\xff':
> > + self.Header =
> > EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
> > + else:
> > + self.Header =
> > EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
> > + if self.Header.Type in SectionHeaderType:
> > + self.Name = SectionHeaderType[self.Header.Type]
> > + elif self.Header.Type == 0:
> > + self.Name = "EFI_SECTION_RAW"
> > + else:
> > + self.Name = "SECTION"
> > + if self.Header.Type in HeaderType:
> > + self.ExtHeader = self.GetExtHeader(self.Header.Type,
> > buffer[self.Header.Common_Header_Size():],
> > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
> > + self.HeaderLength = self.Header.Common_Header_Size() +
> > self.ExtHeader.ExtHeaderSize()
> > + else:
> > + self.ExtHeader = None
> > + self.HeaderLength = self.Header.Common_Header_Size()
> > + self.Size = self.Header.SECTION_SIZE
> > + self.Type = self.Header.Type
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + self.OriData = b''
> > + self.OriHeader = b''
> > + self.PadData = b''
> > +
> > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) ->
> None:
> > + if Type == 0x01:
> > + return
> > EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
> > + elif Type == 0x02:
> > + return
> > EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
> > + elif Type == 0x14:
> > + return Get_VERSION_Header((nums -
> > 2)//2).from_buffer_copy(buffer)
> > + elif Type == 0x15:
> > + return
> > Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
> > + elif Type == 0x18:
> > + return
> > EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
> > +
> > +class FreeSpaceNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + self.Name = 'Free_Space'
> > + self.Data = buffer
> > + self.Size = len(buffer)
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.PadData = b''
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > new file mode 100644
> > index 000000000000..a0432c4093cf
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > @@ -0,0 +1,140 @@
> > +## @file
> > +# This file is used to define the functions to operate bios binary file.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from core.FMMTParser import *
> > +from core.FvHandler import *
> > +from utils.FvLayoutPrint import *
> > +
> > +global Fv_count
> > +Fv_count = 0
> > +
> > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE',
> 'ROOT_FFS_TREE',
> > 'ROOT_SECTION_TREE'
> > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None,
> outputfile:
> > str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # 3. Log Output
> > + InfoDict = FmmtParser.WholeFvTree.ExportTree()
> > + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
> > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
> > + if logfile:
> > + GetFormatter(logfile.lower()).dump(InfoDict,
> >
> FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile
> ),
> > ".{}".format(logfile.lower())))
> > + # 4. Data Encapsultion
> > + if outputfile:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str,
> Fv_name:
> > str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # 3. Data Modify
> > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name,
> > FmmtParser.WholeFvTree.Findlist)
> > + # Choose the Specfic DeleteFfs with Fv info
> > + if Fv_name:
> > + for item in FmmtParser.WholeFvTree.Findlist:
> > + if item.Parent.key != Fv_name and
> > item.Parent.Data.Name != Fv_name:
> > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
> > + FfsMod = FvHandler(None, Delete_Ffs)
> > + Status = FfsMod.DeleteFfs()
> > + else:
> > + print('Target Ffs not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile:
> str) ->
> > None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # Get Target Fv and Target Ffs_Pad
> > + FmmtParser.WholeFvTree.FindNode(Fv_name,
> > FmmtParser.WholeFvTree.Findlist)
> > + # Create new ffs Tree
> > + with open(newffsfile, "rb") as f:
> > + new_ffs_data = f.read()
> > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
> > + Status = False
> > + # 3. Data Modify
> > + if FmmtParser.WholeFvTree.Findlist:
> > + for TargetFv in FmmtParser.WholeFvTree.Findlist:
> > + TargetFfsPad = TargetFv.Child[-1]
> > + if TargetFfsPad.type == FFS_FREE_SPACE:
> > +
> > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> > new_ffs_data, TargetFfsPad.Data.HOffset)
> > + else:
> > +
> > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> > new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
> > + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0],
> > TargetFfsPad)
> > + Status = FfsMod.AddFfs()
> > + else:
> > + print('Target Fv not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str,
> outputfile: str,
> > Fv_name: str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + with open(newffsfile, "rb") as f:
> > + new_ffs_data = f.read()
> > + newFmmtParser = FMMTParser(newffsfile, FV_TREE)
> > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree,
> > new_ffs_data)
> > + Status = False
> > + # 3. Data Modify
> > + new_ffs = newFmmtParser.WholeFvTree.Child[0]
> > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
> > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> > FmmtParser.WholeFvTree.Findlist)
> > + if Fv_name:
> > + for item in FmmtParser.WholeFvTree.Findlist:
> > + if item.Parent.key != Fv_name and
> > item.Parent.Data.Name != Fv_name:
> > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + for TargetFfs in FmmtParser.WholeFvTree.Findlist:
> > + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0],
> > TargetFfs)
> > + Status = FfsMod.ReplaceFfs()
> > + else:
> > + print('Target Ffs not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> > FmmtParser.WholeFvTree.Findlist)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + TargetNode = FmmtParser.WholeFvTree.Findlist[0]
> > + TargetFv = TargetNode.Parent
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + TargetNode.Data.Header.State = c_uint8(
> > + ~TargetNode.Data.Header.State)
> > + FinalData = struct2stream(TargetNode.Data.Header) +
> > TargetNode.Data.Data
> > + with open(outputfile, "wb") as f:
> > + f.write(FinalData)
> > + else:
> > + print('Target Ffs not found!!!')
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > new file mode 100644
> > index 000000000000..6e54b860a9c9
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > @@ -0,0 +1,86 @@
> > +## @file
> > +# This file is used to define the interface of Bios Parser.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from PI.Common import *
> > +from core.BinaryFactoryProduct import ParserEntry
> > +from core.BiosTreeNode import *
> > +from core.BiosTree import *
> > +from core.GuidTools import *
> > +
> > +class FMMTParser:
> > + def __init__(self, name: str, TYPE: str) -> None:
> > + self.WholeFvTree = BIOSTREE(name)
> > + self.WholeFvTree.type = TYPE
> > + self.FinalData = b''
> > + self.BinaryInfo = []
> > +
> > + ## Parser the nodes in WholeTree.
> > + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'',
> > Reloffset: int=0) -> None:
> > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type ==
> > ROOT_FV_TREE:
> > + ParserEntry().DataParser(self.WholeFvTree, whole_data,
> > Reloffset)
> > + else:
> > + ParserEntry().DataParser(WholeFvTree, whole_data,
> > Reloffset)
> > + for Child in WholeFvTree.Child:
> > + self.ParserFromRoot(Child, "")
> > +
> > + ## Encapuslation all the data in tree into self.FinalData
> > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
> > + # If current node is Root node, skip it.
> > + if rootTree.type == ROOT_TREE or rootTree.type ==
> > ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type ==
> > ROOT_SECTION_TREE:
> > + print('Start at Root !')
> > + # If current node do not have Header, just add Data.
> > + elif rootTree.type == BINARY_DATA or rootTree.type ==
> > FFS_FREE_SPACE:
> > + self.FinalData += rootTree.Data.Data
> > + rootTree.Child = []
> > + # If current node do not have Child and ExtHeader, just add its
> > Header and Data.
> > + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> > rootTree.Data.Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + if ParTree.type != 'ROOT':
> > + self.FinalData += ParTree.Data.PadData
> > + rootTree.Child = []
> > + # If current node is not Section node and may have Child and
> > ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data.
> > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or
> > rootTree.type == SEC_FV_TREE:
> > + if rootTree.HasChild():
> > + self.FinalData += struct2stream(rootTree.Data.Header)
> > + else:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> > rootTree.Data.Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + if ParTree.type != 'ROOT':
> > + self.FinalData += ParTree.Data.PadData
> > + # If current node is Section, need to consider its ExtHeader,
> Child
> > and Compressed Status.
> > + elif rootTree.type == SECTION_TREE:
> > + # Not compressed section
> > + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData !=
> > b'' and CompressStatus):
> > + if rootTree.HasChild():
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header) +
> > struct2stream(rootTree.Data.ExtHeader)
> > + else:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header)
> > + else:
> > + Data = rootTree.Data.Data
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header) +
> > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> > + else:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + self.FinalData += ParTree.Data.PadData
> > + # If compressed section
> > + else:
> > + Data = rootTree.Data.OriData
> > + rootTree.Child = []
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header) +
> > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> > + else:
> > + self.FinalData +=
> > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + self.FinalData += ParTree.Data.PadData
> > + for Child in rootTree.Child:
> > + self.Encapsulation(Child, CompressStatus)
> > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > new file mode 100644
> > index 000000000000..f73f1fd65c07
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > @@ -0,0 +1,521 @@
> > +## @file
> > +# This file is used to the implementation of Bios layout handler.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import os
> > +from core.BiosTree import *
> > +from core.GuidTools import GUIDTools
> > +from core.BiosTreeNode import *
> > +from PI.Common import *
> > +
> > +EFI_FVB2_ERASE_POLARITY = 0x00000800
> > +
> > +def ChangeSize(TargetTree, size_delta: int=0) -> None:
> > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or
> > type(TargetTree.Data.Header) ==
> type(EFI_COMMON_SECTION_HEADER2()):
> > + TargetTree.Data.Size -= size_delta
> > + TargetTree.Data.Header.ExtendedSize -= size_delta
> > + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
> > + OriSize = TargetTree.Data.Header.SECTION_SIZE
> > + OriSize -= size_delta
> > + TargetTree.Data.Header.Size[0] = OriSize % (16**2)
> > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
> > + TargetTree.Data.Header.Size[2] = OriSize // (16**4)
> > + else:
> > + TargetTree.Data.Size -= size_delta
> > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
> > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4)
> > //(16**2)
> > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
> > +
> > +def ModifyFfsType(TargetFfs) -> None:
> > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and
> > TargetFfs.Data.Size > 0xFFFFFF:
> > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
> > + New_Header = EFI_FFS_FILE_HEADER2()
> > + New_Header.Name = TargetFfs.Data.Header.Name
> > + New_Header.IntegrityCheck =
> > TargetFfs.Data.Header.IntegrityCheck
> > + New_Header.Type = TargetFfs.Data.Header.Type
> > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > + New_Header.Size = 0
> > + New_Header.State = TargetFfs.Data.Header.State
> > + New_Header.ExtendedSize = ExtendSize
> > + TargetFfs.Data.Header = New_Header
> > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > + TargetFfs.Data.HeaderLength =
> > TargetFfs.Data.Header.HeaderLength
> > + TargetFfs.Data.ModCheckSum()
> > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and
> > TargetFfs.Data.Size <= 0xFFFFFF:
> > + New_Header = EFI_FFS_FILE_HEADER()
> > + New_Header.Name = TargetFfs.Data.Header.Name
> > + New_Header.IntegrityCheck =
> > TargetFfs.Data.Header.IntegrityCheck
> > + New_Header.Type = TargetFfs.Data.Header.Type
> > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > + New_Header.Size = TargetFfs.Data.HeaderLength +
> > TargetFfs.Data.Size
> > + New_Header.State = TargetFfs.Data.Header.State
> > + TargetFfs.Data.Header = New_Header
> > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > + TargetFfs.Data.HeaderLength =
> > TargetFfs.Data.Header.HeaderLength
> > + TargetFfs.Data.ModCheckSum()
> > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) ==
> > EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
> > + NeedChange = True
> > + for item in TargetFfs.Parent.Child:
> > + if type(item.Data.Header) ==
> > type(EFI_FFS_FILE_HEADER2()):
> > + NeedChange = False
> > + if NeedChange:
> > + TargetFfs.Parent.Data.Header.FileSystemGuid =
> > ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> > +
> > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> > + TarParent = TargetFfs.Parent
> > + while TarParent:
> > + if TarParent.type == FV_TREE and
> > struct2stream(TarParent.Data.Header.FileSystemGuid) ==
> > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
> > + TarParent.Data.Header.FileSystemGuid =
> > ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> > + TarParent = TarParent.Parent
> > +
> > +class FvHandler:
> > + def __init__(self, NewFfs, TargetFfs) -> None:
> > + self.NewFfs = NewFfs
> > + self.TargetFfs = TargetFfs
> > + self.Status = False
> > + self.Remain_New_Free_Space = 0
> > +
> > + ## Use for Compress the Section Data
> > + def CompressData(self, TargetTree) -> None:
> > + TreePath = TargetTree.GetTreePath()
> > + pos = len(TreePath)
> > + self.Status = True
> > + while pos:
> > + if self.Status:
> > + if TreePath[pos-1].type == SECTION_TREE and
> > TreePath[pos-1].Data.Type == 0x02:
> > + self.CompressSectionData(TreePath[pos-1], None,
> > TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
> > + else:
> > + if pos == len(TreePath):
> > + self.CompressSectionData(TreePath[pos-1],
> > pos)
> > + else:
> > + self.CompressSectionData(TreePath[pos-1],
> > None)
> > + pos -= 1
> > +
> > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) ->
> > None:
> > + NewData = b''
> > + temp_save_child = TargetTree.Child
> > + if TargetTree.Data:
> > + for item in temp_save_child:
> > + if item.type == SECTION_TREE and not
> > item.Data.OriData and item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> > struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
> > + elif item.type == SECTION_TREE and item.Data.OriData
> > and not item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> > item.Data.OriData + item.Data.PadData
> > + elif item.type == SECTION_TREE and item.Data.OriData
> > and item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> > struct2stream(item.Data.ExtHeader) + item.Data.OriData +
> > item.Data.PadData
> > + elif item.type == FFS_FREE_SPACE:
> > + NewData += item.Data.Data + item.Data.PadData
> > + else:
> > + NewData += struct2stream(item.Data.Header) +
> > item.Data.Data + item.Data.PadData
> > + if TargetTree.type == FFS_TREE:
> > + New_Pad_Size = GetPadSize(len(NewData), 8)
> > + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> > + ChangeSize(TargetTree, -Size_delta)
> > + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> > New_Pad_Size
> > + self.Remain_New_Free_Space += Delta_Pad_Size
> > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size
> > + TargetTree.Data.ModCheckSum()
> > + elif TargetTree.type == FV_TREE or TargetTree.type ==
> > SEC_FV_TREE and not pos:
> > + if self.Remain_New_Free_Space:
> > + if TargetTree.Data.Free_Space:
> > + TargetTree.Data.Free_Space +=
> > self.Remain_New_Free_Space
> > + NewData += self.Remain_New_Free_Space *
> > b'\xff'
> > + TargetTree.Child[-1].Data.Data +=
> > self.Remain_New_Free_Space * b'\xff'
> > + else:
> > + TargetTree.Data.Data +=
> > self.Remain_New_Free_Space * b'\xff'
> > + New_Free_Space = BIOSTREE('FREE_SPACE')
> > + New_Free_Space.type = FFS_FREE_SPACE
> > + New_Free_Space.Data =
> > FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
> > + TargetTree.insertChild(New_Free_Space)
> > + self.Remain_New_Free_Space = 0
> > + if TargetTree.type == SEC_FV_TREE:
> > + Size_delta = len(NewData) +
> > self.Remain_New_Free_Space - len(TargetTree.Data.Data)
> > + TargetTree.Data.Header.FvLength += Size_delta
> > + TargetTree.Data.ModFvExt()
> > + TargetTree.Data.ModFvSize()
> > + TargetTree.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetTree)
> > + TargetTree.Data.ModCheckSum()
> > + elif TargetTree.type == SECTION_TREE and
> > TargetTree.Data.Type != 0x02:
> > + New_Pad_Size = GetPadSize(len(NewData), 4)
> > + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> > New_Pad_Size
> > + self.Remain_New_Free_Space += Delta_Pad_Size
> > + TargetTree.Data.PadData = b'\x00' *
> > New_Pad_Size
> > + TargetTree.Data.Data = NewData
> > + if GuidTool:
> > + ParPath =
> >
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
> ")
> > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > + guidtool =
> > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > + CompressedData = guidtool.pack(TargetTree.Data.Data)
> > + if len(CompressedData) < len(TargetTree.Data.OriData):
> > + New_Pad_Size = GetPadSize(len(CompressedData), 4)
> > + Size_delta = len(CompressedData) -
> > len(TargetTree.Data.OriData)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + TargetTree.Data.PadData = b'\x00' *
> > New_Pad_Size
> > + self.Remain_New_Free_Space =
> > len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) -
> > len(CompressedData) - New_Pad_Size
> > + else:
> > + TargetTree.Data.PadData = b''
> > + self.Remain_New_Free_Space =
> > len(TargetTree.Data.OriData) - len(CompressedData)
> > + TargetTree.Data.OriData = CompressedData
> > + elif len(CompressedData) == len(TargetTree.Data.OriData):
> > + TargetTree.Data.OriData = CompressedData
> > + elif len(CompressedData) > len(TargetTree.Data.OriData):
> > + New_Pad_Size = GetPadSize(CompressedData, 4)
> > + self.Remain_New_Free_Space = len(CompressedData) +
> > New_Pad_Size - len(TargetTree.Data.OriData) -
> len(TargetTree.Data.PadData)
> > + Size_delta = len(TargetTree.Data.OriData) -
> > len(CompressedData)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + TargetTree.Data.PadData = b'\x00' *
> > New_Pad_Size
> > + TargetTree.Data.OriData = CompressedData
> > + self.ModifyTest(TargetTree,
> > self.Remain_New_Free_Space)
> > + self.Status = False
> > +
> > + def ModifyFvExtData(self, TreeNode) -> None:
> > + FvExtData = b''
> > + if TreeNode.Data.Header.ExtHeaderOffset:
> > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
> > + FvExtData += FvExtHeader
> > + if TreeNode.Data.Header.ExtHeaderOffset and
> > TreeNode.Data.ExtEntryExist:
> > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
> > + FvExtData += FvExtEntry
> > + if FvExtData:
> > + InfoNode = TreeNode.Child[0]
> > + InfoNode.Data.Data = FvExtData +
> > InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
> > + InfoNode.Data.ModCheckSum()
> > +
> > + def ModifyTest(self, ParTree, Needed_Space: int) -> None:
> > + if Needed_Space > 0:
> > + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
> > + ParTree.Data.Data = b''
> > + Needed_Space = Needed_Space -
> > ParTree.Data.Free_Space
> > + if Needed_Space < 0:
> > + ParTree.Child[-1].Data.Data = b'\xff' *
> > (-Needed_Space)
> > + ParTree.Data.Free_Space = (-Needed_Space)
> > + self.Status = True
> > + else:
> > + if ParTree.type == FV_TREE:
> > + self.Status = False
> > + else:
> > + BlockSize =
> > ParTree.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize -
> > Needed_Space%BlockSize
> > + if New_Add_Len % BlockSize:
> > + ParTree.Child[-1].Data.Data = b'\xff' *
> > New_Add_Len
> > + ParTree.Data.Free_Space =
> > New_Add_Len
> > + Needed_Space += New_Add_Len
> > + else:
> > + ParTree.Child.remove(ParTree.Child[-1])
> > + ParTree.Data.Free_Space = 0
> > + ParTree.Data.Size += Needed_Space
> > + ParTree.Data.Header.Fvlength =
> > ParTree.Data.Size
> > + for item in ParTree.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + ParTree.Data.Data += item.Data.Data +
> > item.Data.PadData
> > + else:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > + ParTree.Data.ModFvExt()
> > + ParTree.Data.ModFvSize()
> > + ParTree.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(ParTree)
> > + ParTree.Data.ModCheckSum()
> > + elif ParTree.type == FFS_TREE:
> > + ParTree.Data.Data = b''
> > + for item in ParTree.Child:
> > + if item.Data.OriData:
> > + if item.Data.ExtHeader:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> > item.Data.OriData + item.Data.PadData
> > + else:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData
> > + else:
> > + if item.Data.ExtHeader:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> > item.Data.Data + item.Data.PadData
> > + else:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > + ChangeSize(ParTree, -Needed_Space)
> > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
> > + Delta_Pad_Size = New_Pad_Size -
> > len(ParTree.Data.PadData)
> > + Needed_Space += Delta_Pad_Size
> > + ParTree.Data.PadData = b'\xff' *
> > GetPadSize(ParTree.Data.Size, 8)
> > + ParTree.Data.ModCheckSum()
> > + elif ParTree.type == SECTION_TREE:
> > + OriData = ParTree.Data.Data
> > + ParTree.Data.Data = b''
> > + for item in ParTree.Child:
> > + if item.type == SECTION_TREE and
> > item.Data.ExtHeader and item.Data.Type != 0x02:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> > item.Data.Data + item.Data.PadData
> > + elif item.type == SECTION_TREE and
> > item.Data.ExtHeader and item.Data.Type == 0x02:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> > item.Data.OriData + item.Data.PadData
> > + else:
> > + ParTree.Data.Data +=
> > struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
> > + if ParTree.Data.Type == 0x02:
> > + ParTree.Data.Size += Needed_Space
> > + ParPath =
> > os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
> > + ToolPath = os.path.join(os.path.dirname(ParPath),
> > r'FMMTConfig.ini')
> > + guidtool =
> >
> GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Se
> c
> > tionDefinitionGuid))
> > + CompressedData =
> > guidtool.pack(ParTree.Data.Data)
> > + Needed_Space = len(CompressedData) -
> > len(ParTree.Data.OriData)
> > + ParTree.Data.OriData = CompressedData
> > + New_Size = ParTree.Data.HeaderLength +
> > len(CompressedData)
> > + ParTree.Data.Header.Size[0] = New_Size % (16**2)
> > + ParTree.Data.Header.Size[1] = New_Size % (16**4)
> > //(16**2)
> > + ParTree.Data.Header.Size[2] = New_Size // (16**4)
> > + if ParTree.NextRel:
> > + New_Pad_Size = GetPadSize(New_Size, 4)
> > + Delta_Pad_Size = New_Pad_Size -
> > len(ParTree.Data.PadData)
> > + ParTree.Data.PadData = b'\x00' *
> > New_Pad_Size
> > + Needed_Space += Delta_Pad_Size
> > + else:
> > + ParTree.Data.PadData = b''
> > + elif Needed_Space:
> > + ChangeSize(ParTree, -Needed_Space)
> > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
> > + Delta_Pad_Size = New_Pad_Size -
> > len(ParTree.Data.PadData)
> > + Needed_Space += Delta_Pad_Size
> > + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> > + NewParTree = ParTree.Parent
> > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE,
> > ROOT_SECTION_TREE, ROOT_TREE]
> > + if NewParTree and NewParTree.type not in ROOT_TYPE:
> > + self.ModifyTest(NewParTree, Needed_Space)
> > + else:
> > + self.Status = True
> > +
> > + def ReplaceFfs(self) -> bool:
> > + TargetFv = self.TargetFfs.Parent
> > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child
> > Ffs Header State need be reversed.
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + # NewFfs parsing will not calculate the PadSize, thus
> recalculate.
> > + self.NewFfs.Data.PadData = b'\xff' *
> > GetPadSize(self.NewFfs.Data.Size, 8)
> > + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size:
> > + Needed_Space = self.NewFfs.Data.Size +
> > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> > len(self.TargetFfs.Data.PadData)
> > + # If TargetFv have enough free space, just move part of the
> > free space to NewFfs.
> > + if TargetFv.Data.Free_Space >= Needed_Space:
> > + # Modify TargetFv Child info and BiosTree.
> > + TargetFv.Child[-1].Data.Data = b'\xff' *
> > (TargetFv.Data.Free_Space - Needed_Space)
> > + TargetFv.Data.Free_Space -= Needed_Space
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + # Modify TargetFv Header and ExtHeader info.
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # return the Status
> > + self.Status = True
> > + # If TargetFv do not have enough free space, need move part
> > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > + else:
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + else:
> > + # Recalculate TargetFv needed space to keep it
> > match the BlockSize setting.
> > + Needed_Space -= TargetFv.Data.Free_Space
> > + BlockSize =
> > TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize -
> > Needed_Space%BlockSize
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + if New_Add_Len % BlockSize:
> > + TargetFv.Child[-1].Data.Data = b'\xff' *
> > New_Add_Len
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + Needed_Space += New_Add_Len
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + else:
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.Data.Free_Space = 0
> > + TargetFv.insertChild(self.NewFfs)
> > + # Encapsulate the Fv Data for update.
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data +
> > item.Data.PadData
> > + else:
> > + TargetFv.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > + TargetFv.Data.Size += Needed_Space
> > + # Modify TargetFv Data Header and ExtHeader info.
> > + TargetFv.Data.Header.FvLength =
> > TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # Start free space calculating and moving process.
> > + self.ModifyTest(TargetFv.Parent, Needed_Space)
> > + else:
> > + New_Free_Space = self.TargetFfs.Data.Size -
> > self.NewFfs.Data.Size
> > + # If TargetFv already have free space, move the new free
> > space into it.
> > + if TargetFv.Data.Free_Space:
> > + TargetFv.Child[-1].Data.Data += b'\xff' *
> > New_Free_Space
> > + TargetFv.Data.Free_Space += New_Free_Space
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + self.Status = True
> > + # If TargetFv do not have free space, create free space for
> Fv.
> > + else:
> > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
> > + New_Free_Space_Tree.type = FFS_FREE_SPACE
> > + New_Free_Space_Tree.Data = FfsNode(b'\xff' *
> > New_Free_Space)
> > + TargetFv.Data.Free_Space = New_Free_Space
> > + TargetFv.insertChild(New_Free_Space)
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + self.Status = True
> > + # Modify TargetFv Header and ExtHeader info.
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + return self.Status
> > +
> > + def AddFfs(self) -> bool:
> > + # NewFfs parsing will not calculate the PadSize, thus
> recalculate.
> > + self.NewFfs.Data.PadData = b'\xff' *
> > GetPadSize(self.NewFfs.Data.Size, 8)
> > + if self.TargetFfs.type == FFS_FREE_SPACE:
> > + TargetLen = self.NewFfs.Data.Size +
> > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> > len(self.TargetFfs.Data.PadData)
> > + TargetFv = self.TargetFfs.Parent
> > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY,
> > Child Ffs Header State need be reversed.
> > + if TargetFv.Data.Header.Attributes &
> > EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + # If TargetFv have enough free space, just move part of the
> > free space to NewFfs, split free space to NewFfs and new free space.
> > + if TargetLen < 0:
> > + self.Status = True
> > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
> > + TargetFv.Data.Free_Space = (-TargetLen)
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + TargetFv.insertChild(self.NewFfs, -1)
> > + ModifyFfsType(self.NewFfs)
> > + elif TargetLen == 0:
> > + self.Status = True
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs)
> > + ModifyFfsType(self.NewFfs)
> > + # If TargetFv do not have enough free space, need move part
> > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > + else:
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + elif TargetFv.type == SEC_FV_TREE:
> > + # Recalculate TargetFv needed space to keep it
> > match the BlockSize setting.
> > + BlockSize =
> > TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - TargetLen%BlockSize
> > + if New_Add_Len % BlockSize:
> > + self.TargetFfs.Data.Data = b'\xff' *
> > New_Add_Len
> > + self.TargetFfs.Data.Size = New_Add_Len
> > + TargetLen += New_Add_Len
> > + TargetFv.insertChild(self.NewFfs, -1)
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + else:
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs)
> > + TargetFv.Data.Free_Space = 0
> > + ModifyFfsType(self.NewFfs)
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data +
> > item.Data.PadData
> > + else:
> > + TargetFv.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > + # Encapsulate the Fv Data for update.
> > + TargetFv.Data.Size += TargetLen
> > + TargetFv.Data.Header.FvLength =
> > TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # Start free space calculating and moving process.
> > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > + else:
> > + # If TargetFv do not have free space, need directly move part
> > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > + TargetLen = self.NewFfs.Data.Size +
> > len(self.NewFfs.Data.PadData)
> > + TargetFv = self.TargetFfs.Parent
> > + if TargetFv.Data.Header.Attributes &
> > EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + elif TargetFv.type == SEC_FV_TREE:
> > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - TargetLen%BlockSize
> > + if New_Add_Len % BlockSize:
> > + New_Free_Space = BIOSTREE('FREE_SPACE')
> > + New_Free_Space.type = FFS_FREE_SPACE
> > + New_Free_Space.Data = FreeSpaceNode(b'\xff' *
> > New_Add_Len)
> > + TargetLen += New_Add_Len
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + TargetFv.insertChild(self.NewFfs)
> > + TargetFv.insertChild(New_Free_Space)
> > + else:
> > + TargetFv.insertChild(self.NewFfs)
> > + ModifyFfsType(self.NewFfs)
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data +
> > item.Data.PadData
> > + else:
> > + TargetFv.Data.Data +=
> > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > + TargetFv.Data.Size += TargetLen
> > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > + return self.Status
> > +
> > + def DeleteFfs(self) -> bool:
> > + Delete_Ffs = self.TargetFfs
> > + Delete_Fv = Delete_Ffs.Parent
> > + Add_Free_Space = Delete_Ffs.Data.Size +
> > len(Delete_Ffs.Data.PadData)
> > + if Delete_Fv.Data.Free_Space:
> > + if Delete_Fv.type == SEC_FV_TREE:
> > + Used_Size = Delete_Fv.Data.Size -
> > Delete_Fv.Data.Free_Space - Add_Free_Space
> > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> > + New_Free_Space = BlockSize - Used_Size % BlockSize
> > + self.Remain_New_Free_Space +=
> > Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
> > + Delete_Fv.Child[-1].Data.Data = New_Free_Space *
> > b'\xff'
> > + Delete_Fv.Data.Free_Space = New_Free_Space
> > + else:
> > + Used_Size = Delete_Fv.Data.Size -
> > Delete_Fv.Data.Free_Space - Add_Free_Space
> > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space *
> > b'\xff'
> > + Delete_Fv.Data.Free_Space += Add_Free_Space
> > + New_Free_Space = Delete_Fv.Data.Free_Space +
> > Add_Free_Space
> > + else:
> > + if Delete_Fv.type == SEC_FV_TREE:
> > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> > + New_Free_Space = BlockSize - Used_Size % BlockSize
> > + self.Remain_New_Free_Space += Add_Free_Space -
> > New_Free_Space
> > + Add_Free_Space = New_Free_Space
> > + else:
> > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > + New_Free_Space = Add_Free_Space
> > + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
> > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
> > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
> > + New_Ffs_Tree.type = FFS_FREE_SPACE
> > + New_Ffs_Tree.Data = New_Free_Space_Info
> > + Delete_Fv.insertChild(New_Ffs_Tree)
> > + Delete_Fv.Data.Free_Space = Add_Free_Space
> > + Delete_Fv.Child.remove(Delete_Ffs)
> > + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
> > + Delete_Fv.Data.ModFvExt()
> > + Delete_Fv.Data.ModFvSize()
> > + Delete_Fv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(Delete_Fv)
> > + Delete_Fv.Data.ModCheckSum()
> > + self.CompressData(Delete_Fv)
> > + self.Status = True
> > + return self.Status
> > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > new file mode 100644
> > index 000000000000..e21d8e0406ae
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > @@ -0,0 +1,152 @@
> > +## @file
> > +# This file is used to define the FMMT dependent external tool
> management
> > class.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import glob
> > +import logging
> > +import os
> > +import shutil
> > +import sys
> > +import tempfile
> > +import uuid
> > +from PI.Common import *
> > +from utils.FmmtLogger import FmmtLogger as logger
> > +import subprocess
> > +
> > +def ExecuteCommand(cmd: list) -> None:
> > + subprocess.run(cmd,stdout=subprocess.DEVNULL)
> > +
> > +class GUIDTool:
> > + def __init__(self, guid: str, short_name: str, command: str) -> None:
> > + self.guid: str = guid
> > + self.short_name: str = short_name
> > + self.command: str = command
> > +
> > + def pack(self, buffer: bytes) -> bytes:
> > + """
> > + compress file.
> > + """
> > + tool = self.command
> > + if tool:
> > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > + ToolInputFile = os.path.join(tmp,
> > "pack_uncompress_sec_file")
> > + ToolOuputFile = os.path.join(tmp, "pack_sec_file")
> > + try:
> > + file = open(ToolInputFile, "wb")
> > + file.write(buffer)
> > + file.close()
> > + command = [tool, '-e', '-o', ToolOuputFile,
> > + ToolInputFile]
> > + ExecuteCommand(command)
> > + buf = open(ToolOuputFile, "rb")
> > + res_buffer = buf.read()
> > + except Exception as msg:
> > + logger.error(msg)
> > + return ""
> > + else:
> > + buf.close()
> > + if os.path.exists(tmp):
> > + shutil.rmtree(tmp)
> > + return res_buffer
> > + else:
> > + logger.error(
> > + "Error parsing section: EFI_SECTION_GUID_DEFINED
> > cannot be parsed at this time.")
> > + logger.info("Its GUID is: %s" % self.guid)
> > + return ""
> > +
> > +
> > + def unpack(self, buffer: bytes) -> bytes:
> > + """
> > + buffer: remove common header
> > + uncompress file
> > + """
> > + tool = self.command
> > + if tool:
> > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > + ToolInputFile = os.path.join(tmp, "unpack_sec_file")
> > + ToolOuputFile = os.path.join(tmp,
> > "unpack_uncompress_sec_file")
> > + try:
> > + file = open(ToolInputFile, "wb")
> > + file.write(buffer)
> > + file.close()
> > + command = [tool, '-d', '-o', ToolOuputFile,
> ToolInputFile]
> > + ExecuteCommand(command)
> > + buf = open(ToolOuputFile, "rb")
> > + res_buffer = buf.read()
> > + except Exception as msg:
> > + logger.error(msg)
> > + return ""
> > + else:
> > + buf.close()
> > + if os.path.exists(tmp):
> > + shutil.rmtree(tmp)
> > + return res_buffer
> > + else:
> > + logger.error("Error parsing section:
> > EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
> > + logger.info("Its GUID is: %s" % self.guid)
> > + return ""
> > +
> > +class GUIDTools:
> > + '''
> > + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools
> > and provide interfaces to access those tools.
> > + '''
> > + default_tools = {
> > +
> > struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-
> 127f4c984779
> > ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO",
> > "TianoCompress"),
> > +
> > struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-
> dc7bd79403cf
> > ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA",
> > "LzmaCompress"),
> > +
> > struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-
> a4600d9dd083
> > ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32",
> > "GenCrc32"),
> > +
> > struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-
> ca72a6eae889
> > ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86",
> > "LzmaF86Compress"),
> > +
> > struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-
> 0f7f630d5afb")
> > ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI",
> > "BrotliCompress"),
> > + }
> > +
> > + def __init__(self, tooldef_file: str=None) -> None:
> > + self.dir = os.path.dirname(__file__)
> > + self.tooldef_file = tooldef_file if tooldef_file else
> os.path.join(
> > + self.dir, "FMMTConfig.ini")
> > + self.tooldef = dict()
> > + self.load()
> > +
> > + def VerifyTools(self) -> None:
> > + """
> > + Verify Tools and Update Tools path.
> > + """
> > + path_env = os.environ.get("PATH")
> > + path_env_list = path_env.split(os.pathsep)
> > + path_env_list.append(os.path.dirname(__file__))
> > + path_env_list = list(set(path_env_list))
> > + for tool in self.tooldef.values():
> > + cmd = tool.command
> > + if os.path.isabs(cmd):
> > + if not os.path.exists(cmd):
> > + print("Tool Not found %s" % cmd)
> > + else:
> > + for syspath in path_env_list:
> > + if glob.glob(os.path.join(syspath, cmd+"*")):
> > + break
> > + else:
> > + print("Tool Not found %s" % cmd)
> > +
> > + def load(self) -> None:
> > + if os.path.exists(self.tooldef_file):
> > + with open(self.tooldef_file, "r") as fd:
> > + config_data = fd.readlines()
> > + for line in config_data:
> > + try:
> > + guid, short_name, command = line.split()
> > + new_format_guid =
> > struct2stream(ModifyGuidFormat(guid.strip()))
> > + self.tooldef[new_format_guid] = GUIDTool(
> > + guid.strip(), short_name.strip(),
> > command.strip())
> > + except:
> > + print("GuidTool load error!")
> > + continue
> > + else:
> > + self.tooldef.update(self.default_tools)
> > +
> > + self.VerifyTools()
> > +
> > + def __getitem__(self, guid) -> None:
> > + return self.tooldef.get(guid)
> > +
> > +
> > +guidtools = GUIDTools()
> > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > new file mode 100644
> > index 000000000000..18f0cff96e4b
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > @@ -0,0 +1,18 @@
> > +## @file
> > +# This file is used to define the Fmmt Logger.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +##
> > +
> > +import logging
> > +import sys
> > +
> > +FmmtLogger = logging.getLogger('FMMT')
> > +FmmtLogger.setLevel(logging.INFO)
> > +
> > +lh=logging.StreamHandler(sys.stdout)
> > +lf=logging.Formatter("%(levelname)-8s: %(message)s")
> > +lh.setFormatter(lf)
> > +FmmtLogger.addHandler(lh)
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > new file mode 100644
> > index 000000000000..1a6c67056266
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > @@ -0,0 +1,54 @@
> > +## @file
> > +# This file is used to define the printer for Bios layout.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +
> > +def GetFormatter(layout_format: str):
> > + if layout_format == 'json':
> > + return JsonFormatter()
> > + elif layout_format == 'yaml':
> > + return YamlFormatter()
> > + elif layout_format == 'html':
> > + return HtmlFormatter()
> > + else:
> > + return TxtFormatter()
> > +
> > +class Formatter(object):
> > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
> > + raise NotImplemented
> > +
> > +class JsonFormatter(Formatter):
> > + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
> str=None) ->
> > None:
> > + try:
> > + import json
> > + except:
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > + return
> > + print(outputfile)
> > + if outputfile:
> > + with open(outputfile,"w") as fw:
> > + json.dump(layoutdict, fw, indent=2)
> > + else:
> > + print(json.dumps(layoutdict,indent=2))
> > +
> > +class TxtFormatter(Formatter):
> > + def LogPrint(self,layoutlist: list) -> None:
> > + for item in layoutlist:
> > + print(item)
> > + print('\n')
> > +
> > + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
> str=None) ->
> > None:
> > + print(outputfile)
> > + with open(outputfile, "w") as f:
> > + for item in layoutlist:
> > + f.writelines(item + '\n')
> > +
> > +class YamlFormatter(Formatter):
> > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > +
> > +class HtmlFormatter(Formatter):
> > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > \ No newline at end of file
> > --
> > 2.27.0.windows.1
> >
> >
> >
> >
> >
>
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
2021-12-06 8:34 ` Yuwei Chen
@ 2021-12-06 9:44 ` gaoliming
0 siblings, 0 replies; 6+ messages in thread
From: gaoliming @ 2021-12-06 9:44 UTC (permalink / raw)
To: 'Chen, Christine', devel; +Cc: 'Feng, Bob C'
Christine:
I add my comments below.
> -----邮件原件-----
> 发件人: Chen, Christine <yuwei.chen@intel.com>
> 发送时间: 2021年12月6日 16:34
> 收件人: devel@edk2.groups.io; gaoliming@byosoft.com.cn
> 抄送: Feng, Bob C <bob.c.feng@intel.com>
> 主题: RE: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
>
> Hi Liming,
>
> Need your helps on the first and third issues:
>
> 1. As the PI spec defined, for Fv Header "The first 16 bytes are reserved to
> allow for the reset vector of processors whose reset vector is at address 0."
> The FVSEC.Fv generated did not follow the Spec definition, is this the issue of
> GenFv or FMMT, are there any references for this issue?
This is the expected behavior. Edk2 implementation places AP reset vector into the first 16 bytes in SEC FV.
>
> 3. The PEIM rebase way follows which rules?
>
GenFv tool has the logic to rebase PEIM on its flash address. Rebase means to relocate PE image at its flash address.
So, you need to calculate PE image base address in the updated FV image, then rebase PE image on this address.
Thanks
Liming
> Thanks,
> Christine (Yuwei)
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> > gaoliming
> > Sent: Friday, December 3, 2021 11:19 AM
> > To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>
> > Cc: Feng, Bob C <bob.c.feng@intel.com>
> > Subject: 回复: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
> >
> > Yuwei:
> > I did some test and meet three problems. I submit BZ
> > https://bugzilla.tianocore.org/show_bug.cgi?id=3762. Please help check.
> >
> > Thanks
> > Liming
> > > -----邮件原件-----
> > > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei
> Chen
> > > 发送时间: 2021年12月1日 9:29
> > > 收件人: devel@edk2.groups.io
> > > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao
> > > <gaoliming@byosoft.com.cn>
> > > 主题: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
> > >
> > > The FMMT python tool is used for firmware files operation, which has
> > > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function:
> > >
> > > 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware
> Files)
> > > 2.Add a new FFS into a FV file (both included in a FD file or not)
> > > 3.Replace an FFS in a FV file with a new FFS file
> > > 4.Delete an FFS in a FV file (both included in a FD file or not)
> > > 5.Extract the FFS from a FV file (both included in a FD file or not)
> > >
> > > Currently the FMMT C tool is saved in edk2-staging repo, but its
> > > quality and coding style can't meet the Edk2 quality, which is hard to
> > > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
> > >
> > > The new Python version keeps same functions with origin C version. It
> > > has higher quality and better coding style, and it is much easier to
> > > extend new functions and to maintain.
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847
> > > PR Link: https://github.com/tianocore/edk2-basetools/pull/12
> > > RFC Link: https://edk2.groups.io/g/devel/message/82877
> > > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
> > >
> > > Cc: Bob Feng <bob.c.feng@intel.com>
> > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
> > > ---
> > > V4 fixed the Linux file format issue and known bugs.
> > > BaseTools/BinWrappers/PosixLike/FMMT | 14 +
> > > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
> > > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
> > > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 11 +
> > > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515
> bytes
> > > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906
> bytes
> > > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
> > > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++
> > > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++
> > > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++
> > > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
> > > BaseTools/Source/Python/FMMT/README.md | 180 ++++++
> > > BaseTools/Source/Python/FMMT/__init__.py | 0
> > > .../Python/FMMT/core/BinaryFactoryProduct.py | 371
> +++++++++++++
> > > BaseTools/Source/Python/FMMT/core/BiosTree.py | 198 +++++++
> > > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
> > > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
> > > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++
> > > .../Source/Python/FMMT/core/FvHandler.py | 521
> > > ++++++++++++++++++
> > > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++
> > > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
> > > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
> > > 22 files changed, 2432 insertions(+)
> > > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
> > > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
> > > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
> > > create mode 100644
> BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > > create mode 100644
> > BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
> > > create mode 100644 BaseTools/Source/Python/FMMT/README.md
> > > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > > create mode 100644
> > BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > > create mode 100644
> BaseTools/Source/Python/FMMT/core/FvHandler.py
> > > create mode 100644
> BaseTools/Source/Python/FMMT/core/GuidTools.py
> > > create mode 100644
> > BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > > create mode 100644
> > > BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > >
> > > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT
> > > b/BaseTools/BinWrappers/PosixLike/FMMT
> > > new file mode 100644
> > > index 000000000000..5f5519e1e1b6
> > > --- /dev/null
> > > +++ b/BaseTools/BinWrappers/PosixLike/FMMT
> > > @@ -0,0 +1,14 @@
> > > +#!/usr/bin/env bash
> > > +#python `dirname $0`/RunToolFromSource.py `basename $0` $*
> > > +
> > > +# If a ${PYTHON_COMMAND} command is available, use it in preference
> > to
> > > python
> > > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
> > > + python_exe=${PYTHON_COMMAND}
> > > +fi
> > > +
> > > +full_cmd=${BASH_SOURCE:-$0} # see
> > > http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is
> not
> > a
> > > good choice here
> > > +dir=$(dirname "$full_cmd")
> > > +cmd=${full_cmd##*/}
> > > +
> > > +export
> > >
> >
> PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PY
> > > THONPATH:+:"$PYTHONPATH"}"
> > > +exec "${python_exe:-python}" -m $cmd.$cmd "$@"
> > > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > > b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > > new file mode 100644
> > > index 000000000000..f0551c4ac54a
> > > --- /dev/null
> > > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > > @@ -0,0 +1,4 @@
> > > +@setlocal
> > > +@set ToolName=%~n0%
> > > +@set
> > >
> >
> PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BA
> > > SE_TOOLS_PATH%\Source\Python\FMMT
> > > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
> > > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py
> > > b/BaseTools/Source/Python/FMMT/FMMT.py
> > > new file mode 100644
> > > index 000000000000..5028d8446ee0
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/FMMT.py
> > > @@ -0,0 +1,117 @@
> > > +# @file
> > > +# Firmware Module Management Tool.
> > > +#
> > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> > > +#
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +#
> > > +##
> > > +
> > > +# Import Modules
> > > +#
> > > +import argparse
> > > +import sys
> > > +from core.FMMTOperation import *
> > > +
> > > +parser = argparse.ArgumentParser(description='''
> > > +View the Binary Structure of FD/FV/Ffs/Section, and
> > > Delete/Extract/Add/Replace a Ffs from/into a FV.
> > > +''')
> > > +parser.add_argument("--version", action="version", version='%(prog)s
> > > Version 1.0',
> > > + help="Print debug information.")
> > > +parser.add_argument("-v", "--View", dest="View", nargs='+',
> > > + help="View each FV and the named files within
> > > each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
> > > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
> > > + help="Delete a Ffs from FV: '-d inputfile
> > > TargetFfsName outputfile TargetFvName(Optional,\
> > > + If not given, wil delete all the existed target
> > Ffs)'")
> > > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
> > > + help="Extract a Ffs Info: '-e inputfile
> TargetFfsName
> > > outputfile'")
> > > +parser.add_argument("-a", "--Add", dest="Add", nargs='+',
> > > + help="Add a Ffs into a FV:'-a inputfile
> > > TargetFvName newffsfile outputfile'")
> > > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
> > > + help="Replace a Ffs in a FV: '-r inputfile
> > > TargetFfsName newffsfile outputfile TargetFvName(Optional,\
> > > + If not given, wil replace all the existed
> target
> > > Ffs with new Ffs file)'")
> > > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
> > > + help="The format of log file which saves Binary
> > > layout. Currently supports: json, txt. More formats will be added in the
> > > future")
> > > +
> > > +def print_banner():
> > > + print("")
> > > +
> > > +class FMMT():
> > > + def __init__(self) -> None:
> > > + self.firmware_packet = {}
> > > +
> > > + def CheckFfsName(self, FfsName:str) -> str:
> > > + try:
> > > + return uuid.UUID(FfsName)
> > > + except:
> > > + return FfsName
> > > +
> > > + def View(self, inputfile: str, logfiletype: str=None, outputfile:
> > str=None) ->
> > > None:
> > > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
> > > + filetype = os.path.splitext(inputfile)[1].lower()
> > > + if filetype == '.fd':
> > > + ROOT_TYPE = ROOT_TREE
> > > + elif filetype == '.fv':
> > > + ROOT_TYPE = ROOT_FV_TREE
> > > + elif filetype == '.ffs':
> > > + ROOT_TYPE = ROOT_FFS_TREE
> > > + elif filetype == '.sec':
> > > + ROOT_TYPE = ROOT_SECTION_TREE
> > > + else:
> > > + ROOT_TYPE = ROOT_TREE
> > > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
> > > +
> > > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile:
> > str,
> > > Fv_name: str=None) -> None:
> > > + if Fv_name:
> > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> > > outputfile, uuid.UUID(Fv_name))
> > > + else:
> > > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> > > outputfile)
> > > +
> > > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) ->
> > None:
> > > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
> > > +
> > > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str,
> > outputfile: str) ->
> > > None:
> > > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile,
> > > outputfile)
> > > +
> > > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str,
> > outputfile:
> > > str, Fv_name: str=None) -> None:
> > > + if Fv_name:
> > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
> > newffsfile,
> > > outputfile, uuid.UUID(Fv_name))
> > > + else:
> > > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name),
> > newffsfile,
> > > outputfile)
> > > +
> > > +
> > > +def main():
> > > + args=parser.parse_args()
> > > + status=0
> > > +
> > > + try:
> > > + fmmt=FMMT()
> > > + if args.View:
> > > + if args.LogFileType:
> > > + fmmt.View(args.View[0], args.LogFileType[0])
> > > + else:
> > > + fmmt.View(args.View[0])
> > > + if args.Delete:
> > > + if len(args.Delete) == 4:
> > > +
> > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
> > > + else:
> > > +
> > > fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
> > > + if args.Extract:
> > > +
> fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
> > > + if args.Add:
> > > +
> fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
> > > + if args.Replace:
> > > + if len(args.Replace) == 5:
> > > +
> > >
> >
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> > > 3],args.Replace[4])
> > > + else:
> > > +
> > >
> >
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> > > 3])
> > > + # TODO:
> > > + '''Do the main work'''
> > > + except Exception as e:
> > > + print(e)
> > > +
> > > + return status
> > > +
> > > +
> > > +if __name__ == "__main__":
> > > + exit(main())
> > > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > > b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > > new file mode 100644
> > > index 000000000000..aa2444f11b38
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > > @@ -0,0 +1,11 @@
> > > +## @file
> > > +# This file is used to define the FMMT dependent external tool guid.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
> > > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
> > > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
> > > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
> > > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
> > > diff --git
> > a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > > new file mode 100644
> > > index
> > >
> 0000000000000000000000000000000000000000..7cc806a0133413a4aa037
> > > f1d43d80000546a5246
> > > GIT binary patch
> > > literal 29515
> > > zcmcG$bySpZzxIs{h;*kQ-
> > QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+
> > > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@-
> > mueX!oILX!ky#
> > > KL)-b
> > >
> >
> z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331Tx
> > > mKL
> > >
> z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-*01vG}q*T?cd3(SjgooeVt#2I(K
> > > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A-
> > ~0
> > > Os
> > > zomQa`7xm?Vn1W*P-%s-
> > jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTK
> > > u0
> > >
> zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{)
> > > abe
> > >
> z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-@J?eZ>M^7i~SOv=Z7|He
> > > 5*9B
> > > z*-Jfk;((ApOh<DBpW00KVT-
> > d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_
> > > e
> > > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU-
> > u*mWM
> > > w)
> > >
> >
> zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1OK
> > > !@Kal=
> > >
> >
> zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB04
> > > 1
> > >
> >
> z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7^
> > > W
> > > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy-
> > 4#Vx^C$n*R(S2#<fkNRn8K6C!26<
> > > O
> > > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<-
> > BdBP<AmFX)1
> > > _0^
> > > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt-
> > C5{L_
> > >
> >
> zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~@
> > > YoAv$
> > >
> zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o%
> > >
> >
> z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+OT
> > > oZlL
> > >
> z&3gKW-6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk`
> > > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@-
> > nrRU
> > >
> >
> zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtKr
> > > k
> > > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX-
> > Sd(_WJqP_|B0b^CxF|AoL+M;CA
> > > Vm
> > >
> >
> zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rxT
> > +
> > > 5
> > >
> >
> z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu
> > > D}JIY
> > >
> >
> zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fyY
> > > y
> > >
> z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk
> > >
> znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-=J0m0eEDjs15%NH+H9h
> > > W653
> > >
> zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz
> > >
> z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-d|`jvIbK+si;&!T2_F_&_HNh<w9^L8
> > > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B-
> > 8MDTh)0*RC#EN#u!^
> > > nVH$m
> > >
> zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxd
> > > m$
> > >
> >
> zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^|
> > > 1l
> > > zs#*3J+AHPINX8;)QiLwy6-Z2S$&-
> > jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep
> > >
> >
> z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81l
> > > As
> > > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$-
> > *{a=n
> > > ?K!V
> > >
> zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-918Sb}
> > > rWM
> > > zKu}~4YZm`$e$42-
> > HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4k
> > > sy
> > >
> >
> z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=WdU
> > > CN$
> > >
> >
> z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgKG
> > > |Lx3X6
> > >
> >
> zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhkt
> > > P
> > > z4}!3MY9t1~*EvD4lR~M)=-
> > uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P!
> > >
> >
> zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8b
> > > 3+@WmhX
> > > z>ZGUkb+ts3Tk&n$W-
> > n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2C
> > > Qkvs@
> > > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)-
> > !o_k?1CJInjgyPOhp1A%MDgUMftCS$J~
> > > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA-
> > 1pvp;SGObla#%wB7pN+^fnJc#a?jT)B
> > > 8
> > > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&-
> > l~CT@#e0@&
> > > vmX7
> > > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*-
> > 7<1UbT|>O|@l;?iY=`N4
> > >
> z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*%
> > > zg_$H!-
> > &YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW
> > >
> >
> z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi^(
> > > F<T-(}
> > >
> >
> zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy`
> > > TJt!CY
> > > zZezN}4wz=94~>e){&{8Z-
> > !pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=c
> > > PC
> > >
> >
> z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@4|
> > > bv
> > >
> >
> zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb
> > > HJ6Kn
> > > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78-
> > 3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq
> > > ;E
> > >
> zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9
> > > uN5=1
> > >
> >
> z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?Fu
> > > S
> > >
> >
> zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D
> > > p?;
> > >
> zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)%
> > >
> >
> zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;hw
> > > Z%2
> > >
> z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl;
> > > utt
> > >
> z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-9w%D+WylIItDc+R{L*5
> > > W0`!
> > >
> >
> z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59
> > > {es93C0D
> > >
> zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@>
> > > 3g{x5
> > > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^-
> > 1kaKB+d7T
> > > Drx2
> > >
> >
> ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7UB
> > > (wX
> > >
> zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_u?
> > > 3XkOqt
> > >
> >
> zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_yX
> > > DU
> > >
> z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy
> > > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y-
> > oCVYo9xaw1S?6YWT`9V^=h<QFr
> > > Q}
> > > zHAIHMg-
> > ^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0
> > > NyW
> > > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t-
> > !imMfLU8CUGd)w
> > > ^
> > >
> >
> zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5WJ
> > > L
> > >
> zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18j}
> > > *
> > > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r-
> > rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb
> > > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ-
> > ?%k;$V^R5XclbB
> > > !ZjD
> > > zt=UY&?7-X9<AFk^dEO%~_#P&-
> > r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(=
> > > tOwMb
> > >
> >
> z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK0
> > > lL_
> > >
> >
> z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J+
> > > YC
> > >
> >
> zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{Tc
> > > OCnX
> > >
> za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-PWV~o9k)+h9?sds1ss
> > > @v
> > > zSgaMn{Kb=7It4nMlG8iA*-
> > tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHH
> > > Y<UT
> > >
> >
> zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8M
> > > y7^
> > >
> >
> zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#uf
> > > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS-
> > w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoR
> > > A2ii
> > >
> >
> z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^NB
> > > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V-
> > {XCZzitML(}hGq&W
> > >
> >
> zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q
> > > zeC@D`Bk`qD-
> > *FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VS
> > > bRs
> > >
> >
> zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw
> > >
> >
> z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_Mb0
> > >
> >
> zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9<
> > > 3
> > >
> >
> zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPnO
> > > 7{FtVq
> > > zO<`-
> > jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT
> > > -Ie5
> > >
> >
> z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{jg
> > > u
> > >
> >
> zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;wV
> > > aGRj!
> > >
> >
> z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D
> > > h
> > >
> z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o
> > > M(_fvkH
> > >
> zj+J$59%!#I24A*hWHJ-4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY
> > > $
> > >
> z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H
> > > @@5TTQn
> > > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|-
> > *^dW
> > > 5
> > > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG-
> > =t3xx
> > > w9x1s>
> > > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)-
> > ^X=?*fdvD
> > > OD
> > > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ-
> > h^Vc`*v)kGJbP?dUI5
> > > #x
> > >
> >
> z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o
> > > S
> > >
> >
> zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5
> > > sA
> > >
> >
> zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?A
> > > -H_
> > >
> >
> zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq
> > > Cg}S
> > > zLrkk-
> > #H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB
> > > $or-
> > >
> >
> z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz{
> > > }W
> > >
> >
> zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qjo
> > > wW$
> > > znAFU~_wY4f2q?dP-
> > TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D
> > > &U93
> > > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>-
> > &vpdCAooZEI#
> > > wk{a
> > > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T)
> > >
> >
> z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c#
> > > ~d
> > >
> >
> zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWBt
> > > z0zq
> > > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5-
> > iu6O
> > > P@(+
> > > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p-
> > UTYHHHGHJ
> > > a^R
> > > z4e9LSAJ3h-
> > L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR
> > >
> >
> zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jOO<
> > > C
> > > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B-
> > aGV<R9j?#M^F4HzUbtwklL`dfBclo_Ad
> > > u
> > > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<-
> > CE_@x)deTU#?kEtpbb>pf
> > > JQ
> > > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#-
> > <B(*%Baj
> > > w8bG
> > >
> >
> z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO4
> > > pUp
> > >
> z-SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<j
> > > kUEqfGQeE
> > > zsxs)ys+*k-
> > a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j
> > >
> >
> zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G*
> > > Aw_D
> > > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb-
> > 9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1
> > > D
> > >
> >
> z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb7
> > > X^
> > >
> >
> zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe
> > > pj>)
> > >
> >
> z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4ID<
> > > <
> > >
> >
> z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF(`
> > > 3v
> > >
> >
> zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z@
> > > Y8EQ
> > > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>-
> > &_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar
> > > }<t
> > >
> >
> zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd+
> > > -Xd
> > > zF@iS2N;c?&GGNFv1f-
> > nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zF
> > > lqL!
> > >
> >
> z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)$
> > >
> >
> zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1M
> > > TTEJ1
> > > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+-
> > iRa;O_hx8v1
> > > pM
> > >
> >
> zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#VJ
> > > i-E
> > > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{-
> > <qQVg#k>78
> > > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#-
> > fvwHu8795}6
> > > W
> > >
> >
> z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-`
> > > X2@$m4(
> > >
> >
> zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9r
> > > A*%
> > > zYs#3InBRHdV-
> > hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L
> > >
> >
> zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>09
> > > 9|n
> > >
> >
> zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&@
> > > u
> > >
> zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6%
> > > Ib
> > >
> zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU
> > > *R)a;LqQ
> > >
> >
> zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&w
> > > vUtt
> > >
> zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c
> > > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE-
> > {)&!(C4TBm|f@H
> > > Qxf
> > >
> >
> zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTzx
> > > &
> > >
> zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%=
> > > WmbM0
> > >
> z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl-
> > q3
> > > 6
> > > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6-
> > LubB
> > > c
> > >
> z={sgH-$it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha
> > >
> >
> zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrNDh
> > > g
> > > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$
> > >
> >
> z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB
> > > k2bs
> > >
> >
> zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#(
> > > t_TQ<~
> > > zPpkWLsyFv=kpB8wMCMJ461d6-
> > pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guB
> > > WqSJV
> > >
> zr~@V68iN_D)Gs;XkCz0TsX-UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@u
> > > w9Z
> > > zIQm^k)g4d<<I-`XDjPImuOoV3k-
> > fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@
> > > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ-
> > q&>D;Lu4Y*65q
> > > 0=*^{N
> > >
> >
> zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5FtT
> > > bF
> > >
> >
> ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv<
> > >
> >
> z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>Xv
> > > L
> > >
> >
> zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?Y5
> > > g^7sU
> > >
> zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*>
> > > 4
> > >
> >
> zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t`
> > > !
> > > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$-
> > 5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%In
> > > Z;K
> > >
> z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-1#f$3B_;fh#D$u=
> > > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H-
> > JdOHA$qRsqPN|9aQ#M)bXn83O8fh4V
> > > J)p
> > >
> zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3#
> > > MZ@o
> > > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G-
> > ;I<V5t?h0H4ZJmY{X!kNZmp3
> > > lj
> > >
> zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo#
> > > 0G7mqVU
> > >
> >
> zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9ANx|
> > > C^
> > > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os-
> > Y*<Arj
> > > @T
> > >
> >
> zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!U
> > > zv&u^91`JfQ*$6*pQVC-
> > u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`Z
> > > T
> > > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB-
> > Dh>thr$2oA7josXpNOr1+
> > > 57
> > >
> >
> z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~
> > > zUK--
> > r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@Yd
> > > V-z
> > >
> >
> zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY
> > > VB&
> > >
> zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w*
> > > oz
> > > z@o`0!-
> > ;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe`
> > > m
> > >
> zSCR8?6JGt;@q->Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B-
> > {
> > > Y
> > >
> z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-|Ni}Ud%P6T
> > > nb329
> > > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY-
> > w@fzc7$VQ4tNhm5V8N(S
> > > dPS
> > > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8-
> > C&&+<Zy65#V5
> > >
> >
> z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uSw
> > > hf!j
> > > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j-
> > W2=miHT
> > > no
> > > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1-
> > qeL<q;^=2F}
> > > T|
> > >
> >
> zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC
> > > pwM(WO
> > > z`0>B1JR`+)ZDiuFC!F7Fv-
> > o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF
> > > =-
> > >
> >
> zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP
> > > (nm$
> > > zgn7NXKD%P4(&M*qR-
> > (Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c
> > > <p
> > > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av-
> > 4<bCdT@wTC>GBy~|DLthW;7TX
> > > boX
> > > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C-
> > ixZ#a}(P
> > > %71
> > > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg-
> > Xm`x2Xg
> > >
> z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA
> > > qe
> > >
> >
> z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps4
> > >
> z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8
> > >
> z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-7UEtjFzgP5w#}NelsZ%yH
> > > T-
> > > zH|7YArh@+FLkg-
> > WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3
> > > UO`cs
> > >
> >
> zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxLB)
> > > 0
> > >
> >
> zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl25
> > > zwYj@;E^4?Qbs%M^x|g>zUX-
> > moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A!
> > > IRJo
> > >
> zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-u$+G_O!aRmQ{dO`@hXL
> > > wpm5C
> > > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd-
> > 6Ob;XHAbX$!ujWY~NcR
> > > 9fz?
> > > zA{m&^E5y==&`JNCtrsVh*i&iF-
> > ?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&Gzzdj
> > > mI
> > >
> zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r
> > > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi-
> > 6N<6qBRAbW>R|5Yvc<6M7$K
> > > w`6V
> > >
> zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-KqAl?$!d7>ZZeK;OxmNkYMvFp2
> > > q4`
> > >
> >
> z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO^
> > > |E7=&
> > > zinFr&rqO5i{Cmn-
> > mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*U
> > > ab
> > >
> zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO
> > >
> >
> zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@Aw
> > > n>R7
> > >
> zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc#
> > > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)-
> > %FkT
> > > XOBB
> > >
> >
> zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`&
> > > uLj
> > >
> >
> zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({|
> > > *p
> > > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X-
> > Z#BGRQr2o
> > > aKQ
> > >
> >
> zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt(
> > > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q-
> > =mGP;tP2mL@wi(xnoq6<%Cb76W9}f
> > > Ny@K
> > >
> >
> zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0O
> > > pL)Fq>4
> > >
> >
> zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!yf
> > > Mt
> > >
> z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@
> > > @Yi
> > >
> >
> zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v
> > > E`
> > >
> zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-MbjCYgyG44iG*#u
> > > Q@)u
> > >
> >
> zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi4
> > > PQQA
> > >
> z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4
> > > ~<o<8e
> > >
> >
> zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`D
> > > <J
> > >
> >
> z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~F`
> > > F4&
> > >
> >
> zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb
> > > E5
> > >
> >
> z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%z
> > > #~g=O
> > >
> zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-k
> > > e1
> > > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi-
> > O@I~^x{;?=(JqlKKAP)z9
> > >
> zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF%
> > > *F9!4P^
> > >
> zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-LMnpxxcdeCt4<N)
> > > x`
> > >
> >
> zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82#
> > > hx6wR
> > >
> z28k-jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp%
> > > FUzQ
> > >
> >
> zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb
> > > 4G2Su$
> > > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&-
> > TpdZ4Sm%Z^!(mu%Q
> > > -d6
> > > z8CSq{iA^TAM+Sba`K-
> > HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFd
> > > qw
> > >
> z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci
> > >
> zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-YD!;>
> > > m
> > >
> >
> zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW
> > > DlU4VKO$Q7#
> > >
> >
> zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJF
> > > m!6A
> > >
> z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s
> > > 2
> > >
> >
> zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQtq
> > > uX
> > >
> >
> zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=b
> > > URoM
> > >
> z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-Si5+SU@T;
> > > dh
> > > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b-
> > +I~rxJ^NTX^hUZQ_xQHPN@RYRbv=
> > > OAaP0<
> > >
> >
> z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzIv
> > > Yry
> > >
> zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-lW*C|d@!U{tJ?&fR|s{4iO^7Ls>
> > > &a*
> > >
> z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8-
> > K
> > >
> z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m
> > >
> zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j
> > > >
> > >
> >
> zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vqW
> > > d@XHe
> > > zvn*f~#Zp|_nC%d-
> > |J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`<
> > > x-t
> > >
> >
> zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}Vc
> > > ny<
> > > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d-
> > chHgloB
> > > Wr|bA
> > >
> zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-(ytQE}L~vl8pUl{XkJ#~v
> > >
> >
> z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQH
> > > y
> > >
> >
> z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+edJ
> > > u7Dn
> > > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_-
> > YI>c&n(Yp>Lyir
> > > ~@
> > >
> zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-<
> > > h!%=
> > > z*&>EVOnq&ad$05T2-
> > 6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7
> > > Tcf_kK
> > >
> zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-V)~VYWQrve
> > > HMi
> > > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?-
> > }0}e(EkUQx{gt5Qv2GI}9K
> > > s
> > >
> >
> z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN~
> > > |
> > >
> zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y
> > > *YvY
> > > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW-
> > `VxgtihK5w!+4bR%e5W4fcRUBu
> > > t}=3
> > > z-
> > )H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*&
> > > MCZ
> > >
> zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&-
> > >
> zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}#
> > > (sm;
> > >
> >
> zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzc
> > E
> > > -_;{w
> > >
> >
> zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^0
> > > R!C
> > >
> >
> z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!h
> > > o5lF
> > >
> >
> z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!+
> > > &#`
> > >
> >
> zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD-
> > > m$*V
> > >
> >
> zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(jpt
> > > a
> > >
> >
> zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+&
> > > `~cD
> > >
> zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-K0fBZT$@>
> > > U5(
> > >
> zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-}{HlC+M?0#F#>
> > > i8(
> > >
> zj(X%<dp4jcBZN}QPI=}G-w-x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV
> > > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ
> > >
> >
> zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(uw
> > > JY7J-w
> > >
> >
> zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^
> > > NQcQ
> > >
> zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~
> > >
> >
> z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9o
> > > m
> > >
> zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y
> > > C
> > > z<!BcWm*#gI)Q;$>P(-
> > ^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$
> > > VQ0FW
> > > zGH;^fyr(a?>xrm&;uh2hKqp>D-
> > AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7
> > > aZ
> > >
> ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-*{A1{Q)=dfP<Z?
> > > !Ajpt
> > >
> >
> z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha
> > > 7z
> > >
> >
> z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ
> > > @Ox
> > >
> >
> zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk0
> > > l
> > > zVjM=Qw37|BK0|)-
> > NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj
> > >
> z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-{92vZFC<}cxt{&w}6A$>f^vt-II
> > > Uz
> > >
> zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-2h|Tdt}
> > > MtL
> > > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr-
> > NH4*=bhL7Tc<AKzmQSP`%KB$^O6d
> > > paf~!
> > >
> zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE-
> > 1A
> > > zv1;CZ!z3UqKTUkaP--
> > mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw*
> > > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO-
> > t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXs
> > > Eg
> > >
> z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$
> > > ^*M}
> > >
> >
> zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}v
> > >
> >
> z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CLr
> > > Z?;v@B
> > >
> zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-fZZ_
> > >
> zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb)
> > > OG
> > >
> >
> z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~JK
> > > n{X
> > >
> >
> z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1
> > > pZ%wkIe6
> > >
> >
> zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY-
> > > pR
> > >
> zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75!
> > > sSCv
> > > zOI0V)+9b%8^ak8NWz6d-
> > k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW&
> > > !*&3(
> > > zh6=X0QmwWX9XHj5l1@tYGXVhG)-
> > Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+
> > > HQzlwT
> > > z8x|ZZV|V(-
> > wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hH
> > > Psf
> > >
> >
> z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs
> > > s8V7
> > >
> z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj
> > > z5_5g=+O$i$k;%-
> > 1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO
> > > 5%a
> > >
> z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-So=W!Xm2z-
> > > qZ)Dr
> > >
> >
> z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;E
> > > NpfA
> > >
> zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0
> > > zd*)2v-
> > xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&k
> > > XtIl50
> > >
> >
> zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F
> > > Um
> > > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}-
> > _g|Ab91$j2ad2jnt
> > > +=M
> > >
> >
> znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|Sg
> > >
> >
> zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>UY
> > > QmA
> > >
> >
> zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2pf
> > > HM#
> > >
> zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-p^Ljf0`_wKX+3QU^wzXrqcJ5
> > > VI=
> > > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL-
> > `KrNzBi@nX
> > > eF
> > >
> >
> z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux=r
> > > ;!F
> > >
> z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t
> > > xQ
> > >
> >
> z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y|
> > > p
> > >
> >
> zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e
> > > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp-
> > =DEZ9aDLwe&emQpH(ng8O8f|
> > > N|b
> > >
> >
> zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGLO
> > > -%SX
> > > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm-
> > Et@op
> > > ^sZ
> > >
> >
> z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmcW
> > > 5K
> > >
> >
> zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGes
> > > )B
> > > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o-
> > 9JRkFbj^Cvi9
> > > l63
> > >
> >
> z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v
> > > +d4T
> > >
> >
> z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8^
> > > `QF}Y
> > > zTI!eAjaQV1M2^`)i<P>gsTGz-
> > UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew<
> > > 3
> > >
> z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V
> > > mt<0
> > >
> >
> zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk^
> > > +
> > > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=-
> > Jy}m
> > > Zu
> > > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^-
> > &~y
> > > sjCF
> > > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC-
> > gE$~l!e
> > > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^-
> > Xvwp0G$Ypd!Rc|ZQdfy
> > > )>q
> > > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d-
> > LF2U(
> > > N;ve
> > > z`|0v08lJhE-
> > 43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK|
> > > T
> > >
> >
> z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`(
> > > m
> > > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<-
> > L*AxFh1pz<SsamItVw$U*
> > > KSpI
> > >
> z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-l>MDyh5Jwv@sO|fU(KJ
> > > G;
> > >
> >
> zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_G
> > > iy|~
> > >
> z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw>
> > > 1jO
> > >
> zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR
> > > ~#6
> > >
> >
> z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>W
> > > ;)#
> > >
> zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb
> > > z$n8i2c(^-
> > EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN
> > > 9%7z
> > > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J-
> > iap7Ma
> > > 7+~R
> > > zr)wN#;gC`Q+R-
> > b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7
> > > sn
> > >
> zx@d9YxZQ9&G%`VB#)^`&cT-iR-irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?Vw
> > > HK
> > >
> >
> zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz
> > > zM
> > >
> zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-1ug!MMyK4jY4r>~c*
> > > wq)=
> > >
> >
> z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bbF
> > > S*
> > >
> >
> z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkpk-
> > > _@X*
> > >
> >
> za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&~
> > > I4
> > > zMe~hi*!yt-
> > e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBW
> > > B@
> > >
> >
> ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%z
> > > aMs11
> > > zN|%vFr}N@XKRz-
> > JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW&
> > > XA7Ak
> > >
> z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-In{tAe0Yfk<0~_114e<1n;vlOL2uY
> > > M
> > > z{((;&-
> > ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB
> > >
> >
> z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)S
> > > KDX
> > > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`-
> > jSejso!@e^uJ
> > > <
> > >
> zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG
> > > HTu
> > >
> >
> znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%ZH
> > > d+
> > > zMY-
> > =jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+
> > > k&+m
> > > z%ZWm1z4nMfO?(4A8G8!-
> > oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+-
> > > ^I
> > >
> z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-7FWTd$s&4
> > > e|4?
> > >
> >
> ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj#
> > > ^0e
> > >
> zhFT#E%_-^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E;
> > > aO
> > >
> zX{e*o%yIv-brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI)
> > > d
> > >
> z_4)OXSo-JfPgfZ(AGe2R-YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B
> > > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA-
> > +T`x7hrGd7
> > > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G-
> > tP(~dNEPPRy<$X2&|cAe5A
> > > }bI
> > >
> >
> z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C
> > >
> >
> zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM#
> > > g8_@a_!
> > >
> z=SdD&-%dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e0
> > > 06
> > >
> >
> zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`q#
> > > N
> > >
> zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@
> > > M4b@Z
> > >
> zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-D#cJI{S4sKPkL746lL@;A
> > > W
> > > zDssgPVVyB-*vr3ad5~B-
> > )<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&f
> > > wo)
> > > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H-
> > BNMSM32B_HnUIx=z%Fof0ntPF#j9W
> > > WX+
> > >
> >
> zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u
> > >
> >
> ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>L
> > > D0
> > >
> z%@OUSu;f1d%Pvpc-E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$
> > > T2!
> > > zdK(Bjx%p|zQnoY<UWi-
> > I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjb
> > > Nki
> > >
> zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nuP>
> > > u{Cu
> > >
> z<sp-+I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA
> > >
> z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a
> > > @W=
> > >
> zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-@yHu=O|^RYZE2p
> > >
> >
> zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4b
> > > aP~U
> > >
> z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS?
> > > dZ
> > > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T-
> > wQgkxi3VLQjxyVy
> > >
> >
> zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%Kod
> > > Up5h
> > > zqp!T4LK?<KJ()xH%)kcP!N1qc-
> > swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4n
> > > rr|
> > >
> z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE->+H?u5?g
> > > $M
> > >
> >
> zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>EgwG
> > > nyO9
> > >
> >
> z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<=
> > > QC
> > >
> >
> z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrOO
> > > 2Oi
> > > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl
> > >
> >
> zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI
> > > +uw!;
> > >
> zsCmp?gl$-++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL
> > >
> >
> z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD2
> > > )p
> > >
> >
> zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B
> > > c;i!
> > > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV-
> > Hkg6e~c%ayO
> > > }6e
> > >
> z-D(9Q7^=TW8tG-`!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf
> > >
> >
> zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlmx
> > > yhi
> > >
> >
> zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE
> > > FSC
> > > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz-
> > *>o*46xhGpS8Y;XQ
> > > *+
> > >
> z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_;
> > > $3Q
> > >
> zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-#KBcq!;rb9
> > > d
> > >
> >
> zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)ePq
> > > b-|
> > > zOx|zYa;20oYTSb^$f*puP6`{=@+R-
> > cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYs
> > > C^
> > >
> >
> zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv
> > > $0gQ
> > > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#-
> > a+SMQ@Tv59b7zfSbF`J@FL3|c(?~
> > > Mw6
> > >
> >
> zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva
> > > Y
> > >
> z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-A4`jXw+Z5jRxVtBV%J&vH+QRLK
> > > J}o!
> > >
> >
> zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y
> > > GYg
> > >
> zi-_{4)CLA*f2_EP#Zn-|tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE
> > >
> >
> z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ
> > > QYoK
> > > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ-
> > ~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M
> > > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{-
> > p3I!HZ(Q(cX|
> > > H6u
> > >
> >
> zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi@
> > > wl
> > > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_-
> > `ds;ZHWg<At
> > > o
> > > z_!d&4;KL)krKVbM_-
> > %V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3
> > >
> zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW?
> > > s&KLw+
> > >
> >
> zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB(
> > > ~6l
> > > z==pSlrsfT~2W{Zj-
> > #*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapU
> > > Xk
> > >
> >
> zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1(
> > > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$-
> > Ow%eFF$z!@
> > > J+-
> > > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R
> > >
> zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-`hOL3Xr@NJ=ToO<irYaR
> > > +Kh}Lr
> > >
> zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2
> > >
> >
> zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{a
> > Q
> > >
> z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?n
> > > C)ZrQ
> > >
> >
> zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$7
> > > 6h
> > >
> zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW
> > >
> >
> z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=C
> > > Wu8yz
> > > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{)
> > > zw7h-
> > b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{
> > > $z*$
> > > z=zlg}>gO`p-
> > 0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7i
> > > B
> > >
> z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-}feE_&!ul
> > > @}
> > >
> z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6
> > > nc`
> > >
> z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-lUuhQjhP>4g#j`eZL{aU
> > >
> z*(6I1SaLpb4L0MXg_IC-N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs7
> > > 2C@
> > >
> zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)->k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JM
> > > e
> > >
> zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2
> > >
> >
> z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oLg
> > > 7
> > >
> >
> z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?FP
> > > Su5
> > >
> z)ab5C!KD#<D`;Z6I{4a^p-05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{
> > > 2
> > >
> >
> z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^
> > > h{bn+
> > >
> zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-@+a<=!C@tI}k;wK*4
> > > uNZt+
> > >
> z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-)p^*Y(4Gdy1chpzMD=e^fghwH
> > > @17p
> > > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@-
> > 1E
> > > 7@!
> > >
> z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv
> > > UZA3
> > >
> ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13
> > >
> z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq
> > >
> z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2
> > >
> zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH
> > >
> zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-8vb&OJY
> > > Ep}s
> > >
> >
> z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox
> > >
> >
> zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|n
> > > z{aj
> > >
> zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT
> > >
> zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-C_W&g}sGsC&
> > > Q*
> > >
> z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@
> > > 1dFnWtdD
> > > zNVk1t_y;mT-
> > k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vr
> > > q=F
> > > zDjf9;-
> > DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLu
> > > WqN
> > >
> zwRjfyIWini{Z{Zc#TL&V-&#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GM
> > > o0
> > >
> >
> zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p
> > > h-@
> > >
> z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-f>WK&)%iK
> > > HW
> > >
> >
> z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3y
> > > nKla
> > >
> zzKcV{HtX!!3WKrl`Ohp-{h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D!
> > > B
> > >
> z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp
> > > Zw$e
> > >
> zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c;
> > >
> za+_9!J)*OdO@3=78DOkJ0B-!5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g%
> > > mO
> > >
> zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_-
> > Hx
> > > _2|
> > >
> zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6
> > > R4Rr
> > >
> >
> zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1N
> > >
> zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-xOd
> > >
> >
> zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6&
> > > u@Wv
> > >
> z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-U2rX9A=^b2@4!NSpZK6
> > > 9Jd_v
> > >
> >
> zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*a
> > > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56-
> > 8|HN!VHDt?X!7%VRV8^)x
> > > U0D
> > > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e-
> > h|F2yMD^>eWe)o2zdCq!a(n?9
> > > >#f
> > >
> >
> z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO}
> > > F
> > >
> >
> z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hDQ
> > #
> > > qTm(t
> > > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;-
> > }$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG(
> > > 6c
> > >
> >
> zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRUr
> > > a
> > >
> zMX}`gm-bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU
> > >
> zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h
> > > <pq
> > >
> zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC
> > > Mb
> > >
> zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn?
> > > G
> > >
> z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm!
> > > &o
> > >
> >
> zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7sem
> > > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e-
> > RM%C;1ods}_Dy6=&aE!DH&yZe}Po
> > > l_s&^
> > > ztt&=Z6-
> > Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D}
> > > 1
> > >
> >
> zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G6
> > > Vm*0jD
> > >
> zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-R4|toS
> > >
> z2pydY%10h4Ql|^g&a~-aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|>
> > > `XAJs
> > >
> >
> z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL&
> > >
> z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A-
> > > Mf
> > > z<-7K<$G6OrXCLF&g-
> > X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN
> > >
> >
> z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il
> > > {Aw9
> > >
> >
> zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87
> > > CC@??
> > > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo-
> > ^_Ot?JdLg|1aj$ifpl{V^
> > > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C-
> > R#Vcu^1XBSkb
> > > =
> > > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o--
> > &31)1TQ|Q%EAhuIXZd?<`#d
> > > Hj
> > > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1-
> > k2y^JQ>&e<>!r+45@!bqRS
> > > D
> > >
> zut3i~-=JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#=
> > > z8@e(3tmNqVWq`wXV!qG<JTY-
> > Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3
> > > e-e`uBA
> > > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq-
> > a`x7HIXwJ=fQf_ro@BbDbjW+5A=13
> > > ?M
> > >
> zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-mrArVjc*XJ0kT0YL$?T^(tr16{tK`A
> > > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71-
> > xIa;QyQ+A+=ch*hu
> > > DSEC
> > > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0&
> > >
> > > literal 0
> > > HcmV?d00001
> > >
> > > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > > b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > > new file mode 100644
> > > index
> > >
> 0000000000000000000000000000000000000000..6335653ece1605cd0c53b
> > > d2cc2bc21d57d213dae
> > > GIT binary patch
> > > literal 79906
> > >
> zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$
> > > C9i
> > >
> >
> zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`c
> > > }
> > >
> >
> zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}I
> > > {
> > >
> z0yaZNTtv-PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7
> > > MH&Y
> > >
> zSBgmL+qc~&-2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM|
> > > NThc
> > > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M-
> > DQkUsiWm_>>F`39z{F@w
> > > QiMSjA
> > >
> >
> zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#^
> > > -oj
> > > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB-
> > Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY
> > >
> zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1>
> > >
> >
> z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0o
> > > OF-(
> > > ze(GY+PNz-|cTO$duNND)-
> > {Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR&
> > > %J
> > >
> zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-dx#OD{OQg(eub>QT==~l6(hlr){Y{
> > > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb-
> > jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD
> > >
> z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-r`IT%N?Xt3UUT~e3sOW
> > > %3^
> > >
> >
> zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&k
> > > vG
> > >
> >
> zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz3
> > d
> > > R&s7P
> > > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq-
> > u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt
> > > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm-
> > &}GK
> > > x(<
> > >
> >
> zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$n
> > > -t?
> > >
> >
> z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9
> > > *
> > >
> z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#V
> > > 4Ni
> > >
> >
> zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3oEu
> > > ^%
> > >
> >
> z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?4
> > > C=
> > > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+-
> > DI^9d~!WoYX0A1$
> > > X%
> > > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=-
> > ;cGp&
> > > 30
> > > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X-
> > )f2nzV!Q^qU_$m?x3Qsm
> > > ex3w
> > > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j-
> > #eg0l|9C)@T=sxzA
> > > k
> > >
> >
> zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&&E
> > > NK9U!c
> > > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4-
> > eKJY=bwrSyQ;ZQBGptmP=XzcCg2Mb
> > > nmP
> > > zDdg?>-
> > mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>a
> > > R`2d(
> > >
> zYnUwZ-9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|<
> > > D<#}
> > >
> >
> zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>o
> > > 8
> > > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e-
> > W7
> > >
> >
> zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_
> > > P
> > > zLL$x|O2|$4_>pUK%4O!a-6#4-
> > alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT
> > > z`*O5L^inXLpWTzaUm%TSE<U`-
> > Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfs
> > > p!
> > >
> z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{
> > > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR-
> > #Ov6((s
> > > C#V
> > >
> >
> zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<T
> > > @9C
> > > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&-
> > x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4
> > > n=
> > >
> >
> z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!mZ
> > > e
> > > zuk|Q9*5!@y$-
> > x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF
> > > 8^
> > > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G-
> > <BptWKsIz=W_P31e
> > >
> >
> zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV2
> > > &++Q{
> > >
> >
> zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>Sv
> > > Y!Bo}
> > >
> >
> z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L8
> > > P<
> > >
> zV85AA*wyD<1C-lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-Z
> > > RAE+
> > >
> z*xt4p*!SU|NhKAQxbwBmrpho5-EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K
> > >
> >
> z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{e
> > > g
> > > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA-
> > UumgF$+yN
> > > ^{w
> > >
> >
> zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjrR
> > > {j
> > > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0-
> > 9#FB%x&<MXb|Gr!H(s~?YlpM1#}9N
> > > XFE
> > >
> zQ<q-BeOLa-^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj
> > >
> zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-NqJL%nZt${4%ha;&H5Z
> > > v^+
> > >
> >
> zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G)#
> > > Yhjbc;
> > >
> >
> z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n_
> > > Rx-k$
> > >
> zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-_R)o%4NaDc$tF4>RNx6<r
> > > !n
> > >
> z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#};
> > > @Voub
> > >
> >
> ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX
> > > #p{~VSr
> > >
> >
> zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L2
> > > 6z*3T
> > > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^-
> > D9Xi=W|_*B95jIA_{cNB_^^LFA&C%d
> > > NUT
> > >
> zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@s
> > >
> zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ
> > >
> >
> znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwpp
> > > utI
> > > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg-
> > y}h%yHH_0H
> > > a8<A
> > >
> >
> zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps
> > > >6Mc?h
> > >
> >
> z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&e
> > > TQ%X
> > >
> zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M-
> > G
> > > 2{M
> > >
> >
> znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u&
> > > Jp
> > > zum8=!r+B_~0&G%_%VRj-TC~2mL-
> > ot07njmvdGDQXScyh?WMt%s_phdFXEx;v
> > > A6W{j
> > >
> z-gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam
> > > `+(0
> > >
> >
> z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29
> > > @
> > >
> z6wP@W%D-XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On
> > > @-tU=bw%s
> > >
> >
> zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{
> > > YugQ}
> > > zM8N()%W_L~2Da%^cIAH-<-
> > an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v*
> > > wES
> > > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H-
> > AhOC|1BQKucrND=U^;)jo
> > > OarT+
> > > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s-
> > 8ymFk^)c%duzJ;nL)3Nu
> > > }
> > > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx-
> > &f`Khm=*XOz
> > > ?S<B}
> > > z%8w-r#pfF@&BNC-
> > fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?2
> > > 2QC!aZ
> > >
> >
> ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP
> > > W
> > >
> z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!%
> > > U)1gME
> > > zXaJ!`N#R-
> > _I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk
> > >
> >
> z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO@
> > > ZQJwxv
> > >
> zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-@!x)8v9!cbq!92IM
> > > |FT
> > >
> >
> z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9M
> > > Re<Cff;
> > >
> >
> z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{
> > > P5
> > >
> zKmX|O;)u-!R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L
> > >
> >
> zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsHg
> > > uoJJp
> > >
> >
> zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^
> > > AC
> > >
> >
> z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n1f
> > >
> z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7-
> > rV
> > > rF
> > > zg3F-R(c*YRq-@%swU!k`8-
> > wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R(
> > > 9R2;h
> > >
> >
> z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqTs
> > > 08Z
> > >
> zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r
> > > wY
> > >
> zNP-2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a
> > > %KM75
> > >
> zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2
> > >
> >
> z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*tW
> > > G
> > >
> >
> zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+K
> > > 9+X
> > >
> >
> zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@S
> > >
> >
> z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&aRJ
> > > pa
> > >
> >
> zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@Ds
> > >
> >
> zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U^
> > > rj9
> > >
> >
> z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI
> > > 7hE2
> > >
> >
> z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U
> > > Qp
> > >
> >
> zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P
> > > u^kAGC
> > >
> >
> zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?p
> > > &qx
> > > zu6PAe_-
> > |zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRce
> > > Wy}o-
> > > zDVg;W`B&bT@-
> > K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~
> > >
> >
> zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{IIV
> > > >9
> > > zsE<cJl8QUANXMMXD!_@-
> > n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{P
> > > q
> > > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC-
> > =%ubEfAZ
> > > @
> > >
> >
> zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^
> > >
> zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA
> > > R5My
> > >
> >
> zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0v
> > > adA
> > >
> z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-L
> > > ~M
> > > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW-
> > e{py@
> > > Z9m
> > >
> zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d
> > >
> >
> zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G
> > > %
> > >
> >
> zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{y
> > > 1
> > >
> zSJSa?&I$~=oQ5B~-fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI>
> > > pGi
> > > z+_V-
> > c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+
> > > X
> > >
> >
> zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQPj
> > > !|*
> > >
> >
> z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU
> > > M9o^q
> > >
> zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-*k
> > >
> z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-=z}?&d5y
> > >
> >
> zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}G
> > > tq
> > >
> z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp%
> > > wS#
> > >
> >
> zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW2
> > > iu$
> > >
> >
> zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z^
> > > Q
> > >
> >
> zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{
> > > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x
> > > z-
> > axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b
> > >
> zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-L1pr!QHNl#CA?N`J_d
> > >
> >
> zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi
> > > GxV
> > > zW+Xgk^iMPoaLhyqRlH?kt-
> > @DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~
> > > z
> > > z?VV;!_jL_mlUw;2nHl-
> > WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4-
> > > %
> > >
> >
> zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+
> > > UJ
> > >
> >
> z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2
> > > >D
> > >
> >
> z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo{(
> > > <dC
> > > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i-
> > 6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2
> > > %
> > >
> >
> z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7
> > > D~m%
> > >
> >
> zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU
> > > wS<o
> > >
> >
> z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT
> > > h8Q
> > > zoJ6nV;1DH2O4gK#e-
> > q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO
> > >
> zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y-
> > ?g
> > > mho5+
> > > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane-
> > R8v5Z3OKYwF7I{995>T{A1a4Im!
> > > )_
> > >
> zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-D4RV>p@CxRzdtr$ww~ijkk?Q
> > > wBco
> > >
> >
> zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8=
> > > %Fv%A
> > >
> >
> zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKFl
> > > ZU<
> > > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0-
> > }=OWCI_3x@
> > > 9
> > >
> >
> zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGiz
> > > hw
> > >
> z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*)
> > >
> >
> z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK_
> > >
> >
> z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaVC
> > > DNWo
> > >
> >
> zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$T
> > > !
> > >
> z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T
> > >
> >
> z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>>s
> > > B
> > >
> zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7
> > >
> zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ>
> > > TQCm
> > > znzg-
> > `v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a
> > > 0J
> > > zIkAk(wATQFU}lxojL8BaMgpS*sZF-
> > `Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y
> > >
> z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-b3uV(fj)ahIFAy;rX!LzT{03ImN8e
> > >
> >
> zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n
> > > >SOcM
> > >
> >
> zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWMZ
> > > %4x)R
> > > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}-
> > 7DJqPTCn{7Nz>p0rZlI4~7mz
> > >
> zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|!
> > > g`?g
> > >
> >
> zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=JO
> > > cr
> > >
> >
> zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440zb
> > > Z!t
> > >
> >
> zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b3
> > > l8e%
> > >
> >
> z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!O
> > > (n
> > >
> >
> zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+O
> > > pc>
> > >
> >
> zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>|
> > > 3uW
> > >
> zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{
> > > UyAaR~g
> > > zku^pl=~dP2`Zfc98X!v015wP-
> > Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMd
> > > r
> > >
> >
> zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=0j
> > > 9
> > >
> >
> zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%so
> > > Gf%c@
> > >
> >
> zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62
> > > 5bew
> > >
> z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG
> > >
> >
> zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFpN
> > > ^
> > > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=-
> > Y=I$JBF{x__)9E*zZEmcCFhV9%@A
> > > |;C;
> > > z0dw89i-
> > PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%-
> > > &
> > > z>Q=`%q>K==&;cust-
> > ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV
> > >
> z{!UtA!mJA!M)R(65XcC`dC$-SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9
> > > XLis
> > >
> zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P
> > > 1}jc
> > > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k-
> > w~FY#E${v
> > > @rK
> > >
> >
> zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lEp
> > > -fr0oM
> > > zeqF9y$w4I3?w-
> > jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrU
> > > Fr1!2
> > >
> z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-Z&+z>GTbGWFZ3~;
> > > mLh?
> > >
> z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-^_g0=lFv<t4trhJ6oDrwj
> > > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1-
> > (p9OWCabzpEq45mFF
> > > oK|H
> > >
> z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+-
> > O
> > > Y}tK
> > >
> zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a
> > >
> zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa
> > > +|BJf
> > > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo-
> > {zTWc%6}gM|{b`5lyb8()nn?Zf
> > >
> >
> zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W9
> > > +T
> > >
> z)0vi*_}W40^G-Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u
> > > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%-
> > (}mcvBi24si~mkArbb_~r3o|KZf^n7Uy
> > > E
> > >
> >
> z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9{
> > > $e
> > > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H-
> > 8)+593lMa!6m;Ey~fbc
> > > ;@zbu
> > > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g-
> > `zSeHh*X@cob
> > > g_J
> > > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H-
> > $azMlS<h3_eAd0+EVB
> > > ViPF*q=w
> > >
> zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7JgmS
> > > Tw
> > >
> zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K`
> > > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;-
> > q=U!pbpr~8VdgFOFb
> > > 5t^9
> > > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9-
> > 6O1aqUt
> > >
> >
> zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9
> > > QDz?mSX5
> > >
> >
> z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsus;l
> > > QHSl
> > >
> z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-(N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!F
> > > C#
> > >
> >
> znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*sI1
> > >
> zW-W-#4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~
> > > H
> > >
> zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--GI~UA3cBywH@_
> > > oz
> > >
> z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K
> > > DGp
> > >
> zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o
> > >
> >
> zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C#
> > > v9
> > >
> zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s`
> > > S
> > > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E-
> > y8jBnk?{Kg<Q(rP
> > > ?aP
> > >
> >
> zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^M
> > > #<y@7X
> > >
> >
> zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P
> > > e
> > >
> >
> z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf}
> > > Dot
> > > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)-
> > tXUE^B;?g$~2}e
> > > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr-
> > h5P};PfpB7o>k|p
> > > #
> > >
> >
> zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>5
> > > tV
> > > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz-
> > o1WNRw7&EKpp!}70%&c^b
> > > 4h<X*
> > >
> z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-d=LwZv12NG{0Z$pcQ<
> > > GAqMM
> > > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q-
> > 5QmskD?C29B1Pr&(c@s&e+uwi>ijiC
> > >
> >
> zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$Gz
> > > 6I
> > >
> >
> zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2
> > > p^z
> > >
> z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3
> > > z<50dfE9+W7#lo(K-
> > r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+
> > > CCm
> > >
> zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7
> > > 2*<<s
> > > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}-
> > rVwE?y%~_n0~M
> > > }
> > >
> >
> zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m
> > > &MC4
> > > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw-
> > XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL
> > > -MC
> > >
> >
> zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY
> > > h39ZZ}0
> > >
> zLt^3vj&#lIv1g544<Yb6-gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb!
> > > L
> > > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v-
> > s0rJQC*k<wIAScDz1q_$t
> > > 67V9
> > >
> z>GYw>U{=-7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M
> > > @O5t
> > >
> >
> zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+X
> > > NW
> > > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3-
> > Je!ymF9!@&)jg5>?2{8NsyKmZu
> > > 0v4vt
> > >
> z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-=VGbTMH6
> > > m~9%
> > >
> >
> zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr$
> > > 4
> > > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls-
> > oKS&kVw270i?>6=6@nEFRC5Es`
> > > ~
> > > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*-
> > LqT
> > > F>U
> > > z^KiUZAYXWSxqM(C(C=Zy<<Qa-
> > QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4r
> > > G
> > > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=-
> > 4|~9MCtID_85v
> > > Yp
> > >
> zfQ~<^;wF=BO&RVk-REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W}
> > > hq
> > > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<-
> > JnxxY)Hg
> > > z?YX0XeW;3-
> > 48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n
> > > >i
> > >
> >
> z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU<
> > > pvY2
> > >
> zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb%
> > > W=j
> > >
> >
> zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_re
> > > %CCQ<r
> > >
> >
> z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1#
> > > &l`5
> > >
> z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2?
> > > |b4
> > >
> >
> zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSIx
> > > E)m#
> > >
> >
> zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV
> > > >xj
> > >
> >
> zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$o
> > > b|>
> > >
> >
> zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB
> > > wX}s$
> > >
> z=mOMGb(OU&;Y-sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiw
> > > m=%XJu
> > >
> >
> zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<Bf
> > > XFK
> > >
> >
> z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn87
> > > omSx
> > >
> >
> z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v
> > > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#-
> > 8~w<KRe>5t8O19tX
> > > VdlKcX
> > >
> zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X|
> > >
> zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-u#2Ll>9)JJeX5yx&Eg+s
> > > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza-
> > 27uAu?{)Oh
> > >
> >
> zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1
> > > u
> > >
> >
> zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZll
> > > Tnbb(?(
> > >
> >
> z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98L
> > > W5JPe
> > >
> zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-xUpjh6K$0<~(#MOVT
> > > G
> > >
> >
> zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x||
> > > &@
> > > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B-
> > qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%y
> > > Sa
> > >
> >
> zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3sw
> > > (
> > > zY^$M(f1CD!4Fn3S@`Lx%c?j-
> > wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac
> > > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7-
> > Yq$
> > > gRd
> > >
> z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-~!IF8K%Oc)c3a6l@P%0*!Tl67fA
> > > z8K_Ar&HHJwu<-S7^&Tz-
> > z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3D
> > > Q{Qdr
> > >
> z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz
> > >
> >
> zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l
> > > h|`
> > >
> zN#4k4j`m)iY!Be9XXffR3T-y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?H
> > > d>
> > >
> >
> zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz+
> > > p8T
> > >
> >
> zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?sAi
> > > Z`#p
> > >
> >
> z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK
> > > G
> > > zO!{{Gr-
> > ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N
> > >
> z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E
> > > QFcnaYc^
> > > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe-
> > {}E&CO6a@=<Y;tXT*n
> > > V6
> > >
> >
> zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC#
> > > 52^
> > >
> >
> zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j(
> > > V7D7
> > > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u-
> > U{
> > > b
> > >
> >
> z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N?t
> > > ^wM9?
> > >
> zpX-W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFs
> > > K25^
> > > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff-
> > KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt
> > > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|-
> > EFP&Y*s>3Yf2)ZCTs)~
> > > gJ+
> > >
> zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-S;?x;Ac{qB5S{
> > > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G-
> > PPJ0
> > > ?Kf3
> > >
> >
> z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$o
> > > Qo<
> > >
> zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o
> > > UA=
> > > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD-
> > X_KaBxie|nwb|o$l{eH#^hvv27<
> > > Qn
> > >
> zV*^8C4nV-)|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUn
> > > D@
> > > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb-
> > jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U(
> > >
> z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-?j0jQ
> > >
> >
> zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$
> > > %Qo3*6
> > >
> >
> zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5m
> > > 9{p
> > >
> >
> z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?DkZ
> > > +Y
> > >
> zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl
> > >
> >
> z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>HE
> > > 9&
> > >
> z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-bY)T4%ZNoPKw)W&U^_JSvDu#$
> > > &>8io
> > > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb-
> > OZgaoXUvS83(PBK8FLxH<rd+PcVL
> > >
> z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr
> > > @>iU79
> > >
> zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ->$^U|&6iNl<
> > > @
> > >
> zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-nth*
> > > NP
> > >
> z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-0o5+h_
> > > <h1r2
> > >
> >
> z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;U
> > > U^
> > >
> >
> zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S
> > > a#=2pN
> > >
> >
> z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T
> > > KI
> > >
> za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp
> > > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh-
> > `^5g98TqP_j#KdfRYD|0YNGFhOt4
> > > #(
> > >
> z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy%
> > > MXI4g
> > >
> >
> zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc
> > > v
> > >
> >
> zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmXA
> > 6
> > > 3
> > >
> z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-&=L
> > > P`
> > > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&-
> > acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*z
> > > G
> > >
> >
> zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJyF
> > > Xihx
> > >
> >
> zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg
> > > ~d{ri!Y
> > >
> >
> zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL{
> > >
> >
> z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q~_
> > > z)
> > >
> >
> ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi
> > > x|!
> > >
> z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G;
> > > *KA
> > > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a-
> > 2i*w9Y1kWggcE
> > > Az
> > > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz-
> > Yc~Qsu2kWQ?O0sIz*2Ug$6lF
> > > 7j$V
> > >
> >
> zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7SN
> > > bAk
> > >
> >
> ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;Hc
> > > @
> > > zi|8mSqO-MoaYaqA_#}w?c-
> > >nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G
> > > 65>`
> > > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog-
> > (Rz@ruT7zBf!)UI
> > > W~
> > >
> >
> z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4T
> > > `E
> > > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^-
> > ^WD
> > > %
> > >
> zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf
> > > zTyu*%V(L_|%5}>KD68-
> > 34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy
> > > 2
> > >
> >
> zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOmr
> > > ^+)zfc4
> > > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#-
> > Uk>=DjJl057_mpgxax|_Z7^eE
> > > *fBXa
> > > z5_DRyRueL^-
> > #{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;(
> > >
> z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFCg
> > > &
> > >
> >
> zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iuB
> > >
> z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&}
> > > h
> > > z32!E$+=MZ91HfdyI-J-
> > l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$
> > >
> zd`8fM-3port=p~3R?cXIgSVn_*SYG3-ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m
> > > @
> > > z7tPMl@iqfxzh@Lj$xc-Z{m@G-
> > GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`P
> > > nn4<
> > >
> zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-|1x}%Ug?w2J9*_~UVX)
> > > q(
> > > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb-
> > qV@_uT2r9>Pn}r5o@L|E
> > > Y*YV
> > > z0`B%7x?w2<&7x>az-
> > wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1
> > > m0yoPLQ
> > >
> zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-Th|V9j=y
> > >
> >
> z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5W
> > > mG
> > >
> >
> zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0=j
> > > sD@ZJ
> > >
> z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8->7#rH>p$^Y|^sG28
> > > 9!|
> > >
> zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-cbbiR*
> > > r7a77
> > >
> >
> zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG-
> > > z-
> > 09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e
> > > WrXO
> > >
> >
> zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{lC
> > > TI
> > > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk-
> > v)o<J5KbA=o=@`(r5hoYx
> > > Mi^
> > >
> z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-6X%T!<A&<1R6
> > > 6N
> > >
> >
> z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrgO
> > > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#-
> > IZ<w4%qoDyYF%VJC8
> > > ue
> > > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n-
> > wj*c)&TK
> > > 0t?
> > > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm-
> > qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~
> > > z!
> > >
> z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-wBgQsaQyi_$56
> > > MWm-
> > >
> z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-Td^1>N*IfU42cc<s92
> > > W=k
> > > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?-
> > nog7X%sk_s<Y+v
> > > *t
> > > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo-
> > `!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F
> > > zbCM2u?}yBTP-|YUP+qtE+N-
> > $^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc8
> > > 3OR
> > >
> >
> zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc|
> > > ej
> > > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{-
> > f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~
> > > Y
> > >
> >
> z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK5
> > > mBp
> > >
> z(Gk3F*A%@zOR1A-{J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K-
> > 6r
> > > 9Of1
> > >
> >
> z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mnaB
> > > H*
> > > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX-
> > uT&S
> > >
> >
> z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0B
> > > Z5=er
> > >
> zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-6zlU+5lkdX0c
> > > sNof`
> > > z=Hs3R{$%c!jWY-
> > L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP
> > > `
> > >
> z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-S;UtJ>e0
> > > bt
> > > zlnR+ZB=thb?WfT~!j<x<0-
> > aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u|
> > > vh
> > >
> >
> zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7;
> > > J|z
> > >
> z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-Y7Z#SLCl|8KUqDi;w?7O0&
> > >
> z_3jO5;_U<B)w-HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&N
> > > YbY!ry
> > >
> zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-UiX
> > > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2-
> > <QnUzm@<!39peL;+M
> > > Bzl|M
> > >
> >
> z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_
> > > EO7gN
> > >
> >
> zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6
> > > $i
> > >
> >
> zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDyX
> > > n{Of
> > >
> z4XP9-f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R
> > > @dv8E
> > >
> >
> zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@
> > > YK
> > > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We-
> > #w4(vmfn?Vr
> > > u
> > > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6-
> > 4f(+RJub`mui!
> > > Dw
> > > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl-
> > }yeK=rbpE2k2X
> > > KXQx
> > >
> zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-3th7&!
> > > 6
> > >
> zbP-Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLj
> > > N
> > > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf-
> > y^iZn3c@baZ{@GX$an^4lQ&IToF+y
> > > zyt
> > >
> >
> z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=Sd
> > >
> z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a?
> > > S
> > > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di-
> > #FqXjnSNMO_Y*e|TkzT6w
> > > L
> > >
> z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N
> > > L
> > > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!-
> > s9+9*KOCp;tUhBW(x32
> > > DqHX
> > >
> >
> z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gxo+
> > > (
> > > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y-
> > Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7w
> > > X
> > >
> z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq%
> > > K
> > >
> zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel
> > >
> >
> z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j#
> > > +q&
> > >
> zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t)
> > > MFP
> > > z2e~I-K~cSXx8EG)lzE+7@73IePhx-
> > ;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL
> > > #F
> > >
> >
> zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|5
> > > ~|o
> > >
> >
> z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd9f
> > >
> zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(xf
> > >
> >
> zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)Af
> > > A<3
> > >
> >
> zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~Hw
> > > FM4a
> > >
> >
> zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD
> > > >YZ7`
> > >
> >
> zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd
> > > W<i*
> > > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q-
> > dnOip*0`sN2T
> > > a~yG
> > > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk-
> > (q@M
> > > TF-Nx
> > >
> >
> zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4{
> > > `
> > >
> >
> zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?Ra
> > > OZX
> > > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW-
> > kGO+`xCf>(h{Mcc
> > > %|2
> > >
> zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE
> > >
> >
> zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpDV
> > > -5^$B
> > > zPbdR=b%2-
> > pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L
> > > ?
> > > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2-
> > pNELfG(uNbq{doFM5MP7xlb)Rgq
> > > <
> > >
> >
> zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2N
> > > DpUF
> > >
> >
> zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q
> > > %wi~ga
> > > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW-
> > 3aN5iiL|
> > > `
> > >
> >
> zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x$
> > > z
> > > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+-
> > lbp!I4w9ZnT_6aMT~=LLkg!$R
> > > l#
> > > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c-
> > lmKVwD
> > > 3GSE9z(
> > >
> z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE
> > >
> >
> zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw
> > > bk
> > >
> >
> z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Amo
> > > a9>Y
> > >
> >
> zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(#
> > > R
> > >
> >
> z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R@
> > > K
> > >
> >
> zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN9
> > > N?
> > >
> >
> z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxiw
> > > K
> > > zdildOB}k13;#BI@N5b9u5s-
> > {=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp
> > >
> z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-G^`3j|E#&2Ze@Uf$#4HX(7!w
> > > 64j
> > >
> >
> znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>|
> > > sB
> > >
> zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r
> > >
> zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL-
> > $T
> > > m>
> > >
> >
> zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1
> > > 3i$
> > >
> >
> z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2k
> > > G5`&V
> > > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng--
> > HdhvEg
> > > EU
> > >
> >
> z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4
> > > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$-
> > Q%t!bC
> > > $cv!
> > >
> z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO)
> > > Br-
> > > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C-
> > 8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ
> > > 9x`@
> > >
> >
> z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGNB
> > > Hp}
> > > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r-
> > 2YOPxyr*
> > > b}>
> > >
> >
> z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{A
> > > DU;X
> > >
> >
> zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v@
> > > bS
> > > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|-
> > W+1H2CZtdm
> > > OT(s
> > >
> >
> zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#J
> > > zwr
> > >
> ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$?
> > > Zisq
> > >
> z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-7nGsJXyLNjo
> > >
> >
> zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp
> > > <
> > >
> >
> z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~
> > > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x-
> > |BgIJfi=ju7@WZg-
> > > yi
> > >
> >
> z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW
> > > N<+%Xc6
> > >
> >
> z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9v
> > > Gh
> > > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep-
> > 0s*6L=4RuZ>k3UeD`pkpd=
> > > K6
> > >
> >
> zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_8
> > > a1HxFs
> > >
> >
> zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY
> > > yJ6
> > >
> >
> z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR*
> > > &
> > > z-
> > =>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLk
> > > f
> > >
> > z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtkJ
> > G
> > > f
> > > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C-
> > m=TI!deWV<@u@B+g9zOd!H<h7
> > > 6
> > > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H-
> > !7w?@Nm!4fF|H&)>RG9@xH#
> > > VA%Kj
> > >
> zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M
> > > 3@
> > >
> zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x
> > >
> zFz6F-O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rL
> > > m2
> > > z`KG6~&Y4#$-
> > >{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eO
> > > KIXO
> > >
> >
> z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L
> > > NUGvT
> > >
> >
> z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr|
> > > %C
> > >
> z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S
> > > $~q
> > > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o-
> > IzYg)#61qGsUJ
> > > @X>V
> > > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY-
> > L2ha3l(|O
> > > P
> > > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=-
> > neefemATL|%SeTj
> > > 7KM
> > >
> >
> zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc
> > > e
> > >
> >
> zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u
> > > L7
> > > z!mV(@!YY)C1EI1tx4-
> > 6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x
> > > $AP
> > > zwpSBL-
> > W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVdu
> > > yMC6_
> > > zOF$m<BQ-
> > 2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI<
> > > T&4!
> > > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~-
> > ^iTXueIx8byvHT>hu$|i_OeooSft
> > > n
> > > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV?
> > >
> zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1
> > > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%-
> > W88*^zKTEx>j2)~V
> > > 9UTQ`*
> > > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V--
> > kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL
> > > 57
> > >
> ze?~SykK7UD-{WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V
> > >
> z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL)
> > > $Zo2
> > >
> za$ipL@2iXRNSZ-$C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9I
> > > e~kMH
> > >
> zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?!
> > > %!FY6
> > > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K-
> > s2WN^ui3C{($wPhZa^$pzWR^Hl
> > > 3F
> > >
> >
> zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pgw
> > > 4<G
> > > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt-
> > M7|}+UXRU7h?~TB=)5(t0^!(
> > > %P
> > > z-
> > F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc
> > > )h3ea
> > > z6-
> > G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;W
> > > Nvtc
> > >
> z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-i9_yFw*O
> > > B-A
> > >
> >
> zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*peV
> > > vU`(H
> > >
> >
> zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_UhW
> > > E37a#
> > > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o-
> > gou2?WYbb69sCMC}^w$$jzUo!Y&
> > > !
> > >
> >
> zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Zm
> > >
> z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z
> > > #
> > > zq-
> > Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYV
> > > L
> > >
> zJP}y5v#0lQ&o)1+{dt-t@Zz-J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;|
> > >
> >
> z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO(
> > > 9zDJE
> > >
> z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p
> > > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p-
> > ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I
> > > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6-
> > fqr2rZ=VYP@rHCOq9pf8B0xw@Y0
> > > Q|UG
> > >
> >
> zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCXY
> > >
> >
> zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#-
> > > G
> > >
> zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-csF2$3|xVaVFSs$oR?)X!
> > > we
> > > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)-
> > H!*m0eZZ!QVFvyXV^=j}!Z?!plq
> > >
> >
> zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6h
> > > 3
> > >
> >
> zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM43
> > > 0oJ
> > > zI(_U{Z0qELvqlo1zMy(-
> > joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOq
> > > I+
> > >
> >
> z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+
> > > VXJD)
> > > z-
> > q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yV
> > > YY0B
> > >
> zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC!
> > > P|
> > > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r-
> > *H*VR4`LaS<<C1W7hg&
> > > ~pO+K-
> > >
> >
> zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM*
> > > ANN
> > > zUz%6;oPCB&&k^}WT*2fbT-
> > rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)(
> > > t{
> > >
> >
> zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6z
> > > 4P
> > > z{MfuNHeOI7d~NQbki>Wa*r?}Ta-
> > }c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMw
> > > nR7
> > > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&-
> > v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0`
> > > %z
> > >
> zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-K&kxx^&?So<C{4I6S7?Y
> > > O|w1&
> > > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih-
> > 2{<n)!I+;AHbRo*RPPJ<gUm%2
> > > u
> > >
> za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP
> > > d~+Gh
> > > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj-
> > > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?-
> > BXUNalABrN}l?3DDjuoNkTNq%YT7
> > > 3F~h
> > > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV-
> > S%|a7B=tS!rdlDQnw_~vR
> > > NG+
> > >
> >
> z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3AWI
> > > TI9~
> > > z80}SbU~>FO|9I4K$=-
> > QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@
> > > JW;6
> > > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=-
> > TSOTON|2ebg0xls`JM}%@O`g
> > > K
> > > zmH+=v*cCg)>)6&*G74T9ntba~IB-
> > 18Gfz;WMB^neWL%=F6kixs3>vAmMHr<#
> > > a{F%5
> > > zSV4%6rVjJ{9oXWh7>e;x_5=7-
> > ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@
> > > Cxn#6
> > >
> zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-ke|AX!c_CIepD4
> > > z!jPQ@A+Wb%GhI-
> > D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*av
> > > QoVl
> > > zpg?U5sxJ^-
> > s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDU
> > > u2u
> > >
> >
> zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRzH
> > > Y16t
> > > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l-
> > Fr_U^mpQywF
> > > 7_%T
> > >
> z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{a
> > > mi%
> > >
> z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-q1jNZ1iQgnD$U>`mLw>B3j#
> > > @z5(
> > > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi-
> > XyKLb
> > > hKa
> > >
> >
> zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3p
> > >
> >
> zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBMt
> > > i-
> > >
> >
> zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*K
> > > 9fOo`p
> > > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs-
> > ui){uM_Y;pwOERO_
> > > ?nhh
> > >
> >
> zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avgp
> > > !5R#S
> > > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q-
> > UO22MYfNY
> > > *&sB
> > >
> >
> zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5O1
> > >
> >
> zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrmsN
> > > 1K
> > >
> zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-D2p;#e8CCpYYhflt
> > >
> zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr
> > > |TU+
> > >
> zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@}
> > > qgr0T7w
> > > z<XUd9YdH`MV%gjTsUwYem-
> > CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2#
> > > 7kIj!)
> > >
> >
> zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*D
> > >
> z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx<
> > > D`^2
> > >
> z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-0h5~^qID()!>0
> > > O
> > >
> >
> zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+w
> > > )9*
> > > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz-
> > xEr*zAK9
> > > <N?Y
> > >
> z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!F
> > > &Xs
> > >
> >
> z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7hx
> > > qkyHve
> > >
> >
> z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3vp
> > > E(bW+
> > >
> >
> zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(II
> > >
> z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-^Z?jgng+Js*a
> > >
> >
> z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K
> > > 127i
> > >
> zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe
> > > WR1yd=
> > > zOy+GS3N+k-
> > ;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X
> > > 8KHw
> > >
> >
> zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZM
> > > wuHG
> > >
> z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#T
> > > NTye@
> > > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+-
> > 8Mp5YQRWhyS@`gIr&htF@U
> > > =BD#r6X7
> > >
> >
> zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp
> > > i=M9v
> > >
> >
> zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP9
> > > f4
> > > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f-
> > C*U
> > > }T
> > >
> >
> z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>2
> > > T=@i
> > >
> >
> zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_
> > > &ip
> > >
> z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED
> > > M
> > >
> >
> zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#F
> > > Ya5e
> > >
> zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-hjIr6^ba%1jIlO{0DzrRDO70A?
> > > N>
> > >
> >
> zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n-
> > > -MxQ
> > > zG1h%OC9O9yC%If5t*4BIdz)$gh>-
> > Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_q
> > > MQ
> > >
> >
> zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV
> > > SbVYbX
> > >
> zpi3#KXDI_-<!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`%
> > > WvX
> > >
> zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS
> > > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d-
> > XA~5}VSN6cplAA%P=_p4Y
> > > qn~a
> > >
> zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q%
> > > 9};T
> > >
> >
> zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w#
> > > X`^h
> > >
> >
> zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_}
> > > Ln=
> > > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw-
> > J{yCA}t$O?2Gbro_S0%@6bE|NUO7
> > > 3JAX4o
> > >
> zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM-
> > 0
> > > <2
> > >
> >
> zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT
> > > D9y$
> > > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4-
> > pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ
> > > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW-
> > 8FRu~9(wk+ock12GT_
> > > Ja
> > > zM^?ezBrqptKLHwLt1X-
> > 1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0
> > > #5
> > >
> >
> zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa82
> > > +`
> > > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF-
> > GVJ3Or!j$S_H;Jw
> > > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!-
> > _c(_oR
> > > c|
> > >
> zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-($0ZmQkxzN+R9ka~NXu
> > > ma=
> > >
> >
> zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4YghW
> > > Kn#~-
> > >
> >
> zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zNO
> > > XKo0`
> > >
> >
> zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f&
> > > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v-
> > Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3;
> > > (
> > > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y-
> > BrsYiU;W<x<Ea;>dpU
> > > @
> > > zmR>$-PfosIWz(r5(5<wxPbjmo;#-
> > XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE
> > > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N-
> > z3e*X4)s#1kO^g=a
> > > {~c
> > >
> zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl
> > >
> z)W<<5N7esulR#)QKLOZ_yMPT)2lP-)(2&}?&!a(E{XC(M^JVebM5P=yNoukF84}
> > > qZ
> > >
> >
> zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1
> > > vI2
> > >
> >
> zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP
> > > |K
> > >
> >
> zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq@
> > > +3pvf
> > >
> >
> zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mfhc
> > > 7
> > >
> zU4=wyP@_L^!ey*x-F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5l
> > > WtAe
> > >
> z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$
> > > w2^;3
> > >
> z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-EU)dialphdi2!2fv#;W#&=*3tizw4<|e7(
> > >
> zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-j|k|gNJZ70eA<}HU#BT%R$jr844
> > >
> >
> z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4VjP
> > > oM
> > >
> >
> zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+
> > >
> zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j>
> > > aq
> > >
> zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-?4X5LIO8OnL6lhYB0`;
> > > L2G
> > > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu-
> > hUH$wa
> > > RbE
> > >
> z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6
> > > mTGS
> > >
> z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ftz
> > > w=
> > >
> >
> z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID;
> > > @
> > > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb-
> > Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix
> > > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F-
> > ?Au{0G5tdd)TPX1hakJ3TvR90rM<^
> > > Y
> > >
> z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa
> > > @~k)f
> > >
> >
> zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*m
> > > L4-Kc
> > > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!-
> > _hOdW0;F-
> > > OTOp
> > >
> >
> zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!=
> > > X+}$
> > > zFuvZ~++1ipISzO)2)RT}D;-
> > aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7
> > > =
> > >
> >
> z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq7
> > > GW
> > >
> >
> zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%nU
> > > ePA~
> > > z_hxdvS8-
> > a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E
> > >
> z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-QgjuQpS8QXz{p&e
> > >
> zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-@Hx#0H|P?NxL@E^iOnte<`wY(-
> > > C#Ha|I
> > > z=C2Ea@CE*LYY3?FwL2-
> > o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dn
> > > be
> > >
> >
> z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A
> > > W=XSe-
> > >
> zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-=Ns
> > > zM-
> > {9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs
> > > 456yTg
> > >
> z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-62S1{LY+8Uo@`U
> > > XC
> > > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_-
> > =gt@_z#8g{&FBl60M
> > > 8q
> > >
> z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl
> > > <
> > >
> >
> z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s+
> > > <`F
> > >
> >
> zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v|
> > > da*
> > >
> zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-!c6wZ64KV4{+qqvrkXa4qYz3afv?
> > > e
> > >
> >
> zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2XrM
> > > P?$BB
> > > zOd-J<xYW8H1RRa|E>kVw-
> > `TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#da
> > > kHuGSr
> > >
> >
> zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7z)
> > > P
> > > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r#
> > >
> >
> z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl
> > > bN}<
> > > zqLB8`-
> > ^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrX
> > > u{1
> > >
> >
> zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwmZ
> > > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq
> > >
> >
> zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwoX
> > > )z(Tp
> > > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD-
> > jHBwcr%2
> > > 0bUM~
> > >
> >
> zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm
> > > n
> > > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f-
> > bCjEDTbbkioa3
> > > AvU
> > > zTgs{woXY3O-
> > Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*tw
> > > FPeX
> > >
> zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-Z~vbV*7~RKAZfiSoxryi||<$Peh;
> > >
> z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G
> > > 86v
> > >
> >
> zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHmeu
> > > JvQk4
> > >
> >
> zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+An
> > > t>wSc
> > > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af-
> > Xuf0lKfuTpKFA04
> > > 1
> > >
> >
> zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8I;
> > > hr
> > >
> z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+
> > > wHXl
> > > zz&1Drp|7~EN?!zH5pKw!JvbXK-
> > ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(B
> > > C!KO
> > >
> >
> z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{Ug
> > > B$R
> > > zx6k>}-
> > ^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg
> > >
> >
> zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsYD
> > > ;>-$c
> > >
> zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM}
> > >
> >
> zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO
> > > P{<K
> > >
> zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB
> > > G7
> > >
> zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln
> > > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7-
> > kO_`Up!D&o+Zeo37N~wiT
> > > 81j
> > > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e-
> > +C(B!Y<Aj46`65i%71cYGD{
> > > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;-
> > TI~;
> > > EW
> > >
> zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-n}
> > > xK
> > >
> >
> z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I
> > >
> >
> z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQd
> > > nlbj
> > >
> >
> zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j05
> > >
> >
> z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>j-
> > > Y
> > >
> >
> zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$^
> > > 7
> > > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0-
> > O=A5+6B7bE
> > > #7
> > >
> >
> zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ
> > > !$pK^xF
> > > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn>
> > >
> > z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf
> > > ma;W
> > >
> >
> zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d?i
> > > xTr
> > >
> zx}-xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X}
> > > ms
> > > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D-
> > ^e94<`cGBaYaA!4zd=KEsJn
> > > eJ
> > > zd%}Zl026m#*+6#l9yFz!8d8<-
> > XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i
> > > }
> > >
> >
> zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q+
> > > zD#6R=4Z52d(S5iva$jQAz=xFyN-
> > q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~
> > > (
> > > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe
> > > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG-
> > UmfNcjAaL
> > > Epl$S
> > >
> >
> z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7
> > > m#Z
> > > z1f>)aDLDPf#(_xvLI-
> > F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#g
> > > XhRr
> > >
> >
> zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f
> > >
> zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-d{&70ArUQjSu>%=MWtVgeZ=P_
> > > <Ne~e
> > >
> zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S
> > >
> >
> znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)p
> > > 2%fV|*A
> > >
> >
> zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{F
> > > +?=
> > >
> >
> zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}D
> > > 0
> > > zIugZZoN&hDJvgzTn^^1-
> > d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_X
> > > uR
> > >
> zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y
> > > wh4&L
> > >
> zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-+5W5EJWN40wt&=oX#4jZ$9
> > > v
> > >
> z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-APOr43BM{y?
> > > @d>R
> > > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO-
> > x&lC0KfJO|C8kgnlMCC`W~^izTp?
> > > z
> > >
> >
> zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr$
> > > )4
> > >
> >
> z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZYZj
> > > NU_
> > >
> >
> zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?L
> > > wJy
> > > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o-
> > D+M
> > > C?
> > >
> >
> zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#R
> > > @B3p
> > >
> zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-dpiIGuQZ&)3%pWP8|}U%p;
> > > pe#
> > >
> >
> z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^cg
> > > Gu
> > > z<x;1&YdE7!dLGg3LR#-
> > vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4H
> > > xN>
> > >
> z?aBHQe~(b-l2-_R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45%
> > >
> zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh}
> > > R
> > >
> zv0N8>X&n57s}J8$=?=l<bk$t68l-p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!;
> > > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`-
> > <Skpc
> > >
> >
> zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI(
> > >
> zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck>
> > >
> >
> zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1=
> > > O7
> > >
> >
> zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ
> > > Q
> > >
> z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$
> > > &S(O@
> > > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{-
> > gM3Y^a
> > > D&p
> > >
> >
> zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C
> > > 9
> > >
> >
> zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhPw
> > > R
> > >
> z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA
> > > Ms?
> > >
> zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l;
> > > EF=S
> > > zx7~>-e--
> > gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emi
> > > fo
> > >
> >
> zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d
> > > P
> > >
> z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-P0RWsv57^A{E*(nx
> > > RVQs
> > >
> z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e-
> > eJ
> > > (bu7W
> > >
> >
> z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eYY
> > > jt9
> > >
> >
> zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fyW
> > >
> >
> zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%M
> > > M>h@k1
> > >
> zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-4K}7pe~$d41@G9?JVE=j9^arESLcp^
> > >
> zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7
> > > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2-
> > Z~r3V
> > > 4w4#M}^k
> > > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7-
> > #MPr;?r3h8
> > > kN
> > >
> zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF
> > >
> ze@vBF-ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p
> > > 4&oPZ
> > >
> zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V
> > > W1
> > >
> zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-YBZ0Dx|q=e&coqf={1P?*
> > > 5gM
> > > z-dO<=pUw9Hu!6VH-
> > $5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^
> > > P$
> > >
> zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-Snz)c?Y7D?
> > > W@}5
> > >
> zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-HV!HNe?g<7s!)8&&Xyxc8
> > > _Vr
> > >
> zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&G
> > > Uu
> > >
> zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M%
> > > 7_V&j
> > >
> >
> zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ`
> > >
> >
> z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`UcG
> > > z--mu$ZE#I*Q8<#GJ~-
> > LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts
> > > 5J#$S
> > > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`-
> > h@bk9
> > > O3s
> > > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S-
> > y+h<
> > > ?#Y
> > > zk-Qk=flDo-
> > RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu
> > > z+C9W1IPvuo^Z|-
> > GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJw
> > > VT0
> > > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy-
> > t?t~fVXzqFG>P(y1EoKn
> > > x2hb
> > >
> >
> z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b|
> > > +mG
> > >
> >
> zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+D
> > > !#34
> > > z-*FDsO~mox-
> > k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93-
> > > 5v$t
> > >
> >
> zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fwO
> > > CE
> > >
> >
> zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z(
> > Y
> > > z)aDR~xD1dzXmhus5Q??fihY8I-
> > ?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1
> > > QMq
> > >
> >
> zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n@
> > > H~~
> > > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT-
> > h%26Z
> > > X#
> > > z7~{-@v;G{8Lxo0@cHdz4T{-
> > P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur
> > > +Z
> > > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6-
> > Xr9n
> > > R6
> > >
> zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-X7nvR?6z`88tI1O>qbo+nQS%&Mf
> > > w^
> > > zZ3$IK{RGVZe9g9-
> > KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ul
> > > qu_{W
> > > zTj#6IYv<7-
> > Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7
> > > AD
> > > z{ZzN7#^JAPYu-X7Y-
> > 03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{
> > > uPf9
> > >
> >
> zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#f
> > > 4A>iW
> > >
> zmneu(RC2$=*qOP%l({AU1d-R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d
> > > &(
> > >
> >
> zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA?l
> > > #
> > >
> >
> zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ_
> > > _~%;
> > >
> zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2Ki
> > > M#a
> > >
> >
> zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7D
> > > vAn@
> > > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0
> > >
> zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l
> > >
> zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~
> > > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_-
> > EP9=wZkWSqwPf`a`R&_k
> > > |@1@
> > >
> zXh8B2JK;2|sv=_0{$G4L@&UK3!-U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj((
> > > |{)
> > > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$-
> > (zx$a
> > > ^1S
> > > zX!<JR+joeIbZEYtIBvgBnl#LV4-
> > NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g
> > > |
> > >
> >
> z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7Fp
> > >
> zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b
> > >
> z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg%
> > > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz-
> > khs!4b#@5QjP>U9%zLiUFG
> > > ~av?
> > > zeUJ9-Dv~3N$B!appHtL@3-
> > IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q
> > > 46kGa
> > >
> >
> zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*y
> > > E
> > >
> zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm
> > > ppAB<
> > >
> zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-SQU=O?+)
> > > 7
> > >
> >
> z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44v
> > > bV
> > > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT-
> > 57V;K;+syy?R+C30w{q70#TZ1
> > > (Ev
> > >
> zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-9=V
> > > @y@+N~R
> > >
> zS%{uzSs`rlZWV8Sjor|@$P;6|-CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I
> > >
> >
> zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k<
> > > >s
> > >
> z504mry9n!$&LXL_h-aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJ
> > > G+U
> > >
> zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U
> > > S
> > >
> >
> zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>Q
> > > HH0-&U
> > >
> zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn
> > >
> znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt
> > >
> >
> zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9
> > > _?krc
> > >
> zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF%
> > >
> zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(|
> > >
> >
> z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW
> > > p_`g?
> > >
> zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^
> > > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof}
> > >
> z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^--
> > >
> >
> zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%`x
> > > `m
> > > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA-
> > cq+Wq%`jv
> > > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i-
> > +%|*Ny&
> > > A
> > >
> z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA
> > > &6k{Fd
> > > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5-
> > JAQI7W$
> > > CZ<;`
> > >
> zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S
> > > OsN
> > >
> >
> zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kkj
> > > mz-w
> > >
> z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=XR
> > > 7~
> > >
> >
> z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx3
> > > D{
> > >
> >
> zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3S
> > > UN
> > >
> zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-XXcn}h4PYWxnsEmq(kHs
> > > mu
> > >
> zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m;
> > > Nu2W
> > >
> >
> z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk
> > > V!}}
> > > zz+g-
> > u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y
> > > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC-
> > xL=Y(
> > > GRx
> > >
> zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q
> > >
> zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii
> > >
> >
> zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfzM
> > > XGy
> > >
> >
> zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBTc
> > >
> zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q
> > > VM
> > >
> >
> z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4ykU
> > >
> >
> zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E;
> > > iUxRR
> > >
> zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v
> > >
> >
> zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!s
> > > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<-
> > rUD)H9&S
> > > f@E
> > >
> zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn
> > > >#iM
> > >
> zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5
> > > wX%
> > >
> zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@
> > >
> >
> zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP
> > >
> z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298}
> > > 0gs
> > >
> >
> zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM-
> > > rJhB%
> > >
> z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-q63k
> > > zPBTLqcmk>G0PwmJ^W#xC-
> > O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm6
> > > 7AvC
> > >
> >
> zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=;
> > > ?!
> > >
> zUa^-~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*%
> > > J?t7L
> > >
> >
> zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#D
> > > K(~
> > >
> zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL
> > >
> zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-^3T9`SOY49BS`8}=Iajk54^6<oD
> > > z*w1fD++$^@e$D7^UGJgf-
> > rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3
> > > <D
> > > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p-
> > @)*^
> > > N(5Ei!
> > > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$-
> > P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu
> > > ~
> > > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP-
> > wj@j!4#6iMbDW)MruAkHCb1Nqxw
> > > NM{
> > >
> >
> z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7pb;
> > > P_l#tb4g
> > >
> z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P
> > > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57-
> > ^*tCzH+>d*z@3AV|%h%!1NOg+zH
> > > >^N55
> > >
> >
> zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1h
> > > E5}(1<
> > >
> >
> zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t
> > > @BwZ
> > >
> >
> zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*#t
> > > ag
> > > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ
> > > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA-
> > S)#DE
> > > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe-
> > +OTZJW>x%V
> > > y
> > >
> z;m4A?M)+c0g~Jf!fSmq$ocsW`-^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz!
> > > Q?
> > >
> >
> zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1cW
> > > VJ
> > >
> zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-OhuXF&2LmRT
> > > @L_3c
> > >
> >
> zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq
> > > w?L
> > >
> zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw-
> > G<
> > > ~n&
> > >
> >
> zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniUC
> > > {22
> > > zX-
> > I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4
> > > dD%
> > > z<YEj;4*V+0;|M-
> > rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes
> > > #~
> > > zqZrF<mFWvzkmFGC{3-
> > LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?d
> > > G1&
> > >
> z^^|5kQSr|rezHIRAXcF-BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v;
> > >
> ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA
> > >
> z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+
> > >
> >
> z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd
> > > ppY;|*f
> > > zdVc@~A9~wr5$E1you*)8n4i?F--
> > }{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l&
> > > wBh
> > >
> >
> zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o
> > > wnE
> > >
> >
> zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54
> > > +~m
> > >
> >
> ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!R
> > > Z>
> > > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z-
> > WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B&
> > > MMf
> > >
> >
> z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)|
> > 2
> > > aiA
> > >
> >
> zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF8
> > > ~=75zos
> > > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g-
> > QOrn
> > > %{
> > >
> >
> zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$
> > > Wvx
> > >
> zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-QLcYX=3P
> > > Q5^
> > >
> zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q
> > > AJ(0a~#
> > >
> >
> zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6D
> > > O*
> > >
> z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN
> > > #0-*
> > >
> z`8m8qy(o3QuX@2Qin7Ls-*V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCD
> > > NuPv
> > > z8A&gM+yWoI3+p-
> > Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqm
> > > Rd
> > >
> z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki
> > > No!Ys
> > >
> >
> zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<S(
> > > B7X}h
> > > zVR;Et%eD@V5-
> > g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3
> > > #N
> > >
> zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx
> > > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}-
> > 8k0{FELICbyZM7w
> > > lN
> > > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{-
> > JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktb
> > > iKo8
> > >
> z-^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKV
> > > hw$
> > >
> >
> z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6tz
> > > =
> > >
> zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-dcR2oe
> > > Mux8;
> > >
> z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*;
> > > =YK
> > > zjl$=}dcQ-
> > TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr
> > >
> >
> zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|Lj
> > > c
> > >
> >
> z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY
> > > 3VqP
> > >
> ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^
> > > b4_
> > >
> >
> zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}k
> > >
> >
> ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC
> > > 6Q_?
> > >
> >
> zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil{
> > > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;-
> > zV}=Ffb;y0
> > >
> z9ZLyNP?CoW5I?@cS8JHm?Pnue-5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV
> > > 9?w%
> > >
> >
> zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g$
> > > `2Z9
> > >
> z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK
> > > MQo
> > >
> >
> zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$
> > > #|)V;RX
> > >
> zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@
> > > Ox5H
> > > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD-
> > VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{
> > > #
> > >
> ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv
> > > <E={9
> > >
> >
> zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUua
> > > {h
> > > z1c&pk*C&s-u!f*^mD<d?d91-
> > {0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{
> > > 71|@f
> > > zqyCdPYA>=Yf_ZfXdKIQ7K-
> > BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS=
> > > *8
> > > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz--
> > =+yEpn0V;dyO#f3
> > > quY*
> > >
> >
> z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycMN
> > > n#x
> > >
> zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7)
> > > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp-
> > >DBbJFmh
> > > ~
> > >
> >
> zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsEc
> > > 359
> > >
> z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-bd#|(RxFrP
> > >
> >
> z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^42
> > > R
> > >
> >
> z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR-
> > > }t
> > >
> zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc
> > > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E-
> > c!f2kMR<>)RwV=hmWjbJxmB
> > > OGSp>
> > > z=zoS%q90`C_3r-1I|(vxy$L|<-
> > ~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53#
> > > E3
> > >
> zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o
> > > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm-
> > eR5re6n!d6@_6hyx(
> > > I78k
> > >
> zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-wWe6|P1iF^JJFS9F<Cn>F4afY
> > > Wssf9!
> > >
> zN2zMr)_yOt7`nX)8)P8--tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ
> > >
> >
> zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P-
> > > %+f<
> > >
> zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-zUL5ct(LASN#vjIQSj<E%G5&G`
> > >
> >
> zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PCd
> > > j+el
> > >
> zEkxc;8(2Oj-Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G%
> > > >t
> > >
> zFZe1N(-Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@%
> > > Il^r=
> > >
> zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-P(9ByC7p(0M!&woUWlg
> > > 6d?0S
> > >
> zZ!o>QVuB%Dbd=tj&-_T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c>
> > > }u
> > >
> >
> zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXmlh
> > > +5
> > >
> >
> ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V
> > > bfpO
> > > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W-
> > !~C&zci
> > > |?
> > >
> >
> z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT
> > > h?j
> > >
> >
> zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4
> > > 8K^U
> > >
> >
> z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+
> > > 9a
> > >
> zdd~d6ooc=sHa<y|-u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM-
> > > Wn
> > > z9YL6MHz1*R`Ebg>i(85{!WP-
> > zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M
> > > $<
> > >
> z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<?
> > >
> >
> zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk
> > > zjcnO0FC<-
> > zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaP
> > > c8Q1
> > > z>8<aHYtJ``M!kq=@76^J=2^>e*+-
> > ?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS
> > >
> z9O!gMa<;zpIPCD!-j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb-
> > > KY
> > >
> zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@)
> > > {}ye
> > >
> zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H
> > > X$b5|#j
> > > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee-
> > d!ko~1?$I;0XQ0Lcy}V_T
> > > M9HH
> > > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M-
> > xe{E>sl9(>CA<_JNmMi
> > > xd
> > > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP-
> > t~(*7E<kqy26Hww<ma171sv
> > > !t#Q
> > > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X-
> > XGl*%Q0ElH2aXP)|ASi9~aI8
> > > )Vn
> > >
> >
> zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s
> > > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;-
> > *c4|rL<x*=v#r8
> > >
> >
> zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^$
> > > AaI
> > >
> >
> zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`M
> > > -hX
> > >
> z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x
> > > B
> > >
> >
> zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+x
> > > kdv8
> > >
> >
> zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)kuH
> > > Z
> > > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm
> > >
> z>>-{a--W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv
> > > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g-
> > dTo#iWkSVwCW1XNNk>DTg
> > > aD;g
> > >
> >
> zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF
> > > WS_L$5
> > > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk-
> > &zLAxDgQMl#h~
> > > l)AM;
> > >
> z-%Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK
> > > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm-
> > $hEIpj?<LiYD}ov|o=<+m77@%`dhAH~
> > > ua
> > >
> >
> zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is5
> > >
> >
> zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%Nf
> > > }$y^xf
> > >
> z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|y
> > > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk-
> > N;TT
> > > N~tt
> > >
> zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-o
> > > zQ-15yS^!}n-
> > @U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)M
> > > Y69Y
> > > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A-
> > Rih9xWf6KdR0%$1u!qOps1C2Q#
> > > ANP
> > >
> z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u!
> > > Dqgb3Ca
> > > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86-
> > gbBvpzX
> > > R
> > >
> >
> z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}5
> > > T
> > > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj-
> > hIrr3a)n*V>r6m=eJo=M3#L3_
> > > &Y
> > >
> >
> zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7
> > >
> z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-9)^
> > > =n
> > >
> >
> zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;FzZ
> > > IJm
> > >
> z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-`znzlp+K6)3`*U@k9
> > >
> z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5sz
> > > g5f7(M
> > > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG-
> > kU
> > > G*
> > >
> >
> zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1no
> > > Oj
> > > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)-
> > 2TC_XY^XyU+7`Q)it$=yI_HeO$|
> > > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}-
> > n<&rw6V{rKB|$Og
> > > GoBpL
> > > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf-
> > ;e_A#;c07yl@emICdlfx6?S
> > >
> zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9-
> > W
> > > Pr4Do
> > > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x-
> > OHJh=>^
> > > %$z
> > >
> zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf
> > > R=j_i)
> > >
> zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb->
> > > N#*
> > >
> zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_
> > > zLs>gSMg&%IxgXVsk+G<1aLQyI;+-
> > (x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p
> > > 4d
> > >
> >
> z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a
> > > O?%3UXP
> > > zmxkemLOe-bD%O81OOdPv56yFNIJswr)-
> > r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tR
> > > n
> > >
> zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-bjd3)EC1i~W
> > > 5H`Q
> > >
> zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=)
> > > @EPJJ
> > > z!!F00iIqj9<FImx<-
> > TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwu
> > > Z
> > > zA@6GBn_*`<fZu;fKyYcdsVz-
> > LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrb
> > > JP
> > >
> >
> zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@SD
> > >
> >
> z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%o
> > > &q
> > > zxj*LqEY-ZnACrceN-
> > ~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573
> > > zN&n5k9DfdGDn-n*utQW4V{X-
> > IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIP
> > > Mq2Z
> > > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4-
> > Y(zEt0m3<zZQzZOBUz
> > > lhe
> > >
> >
> z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i
> > > !
> > >
> >
> zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v=
> > > 5E
> > >
> zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2
> > > U3cy
> > >
> zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-}p4>2#(NT7_EYJdblL%
> > > @Pb
> > >
> >
> zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*W
> > > T~0Y
> > >
> >
> zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk&f
> > > 3EE
> > >
> >
> z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt<
> > > {8Z-8
> > >
> zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-jr~cF^8<VGoE
> > > m16
> > >
> >
> z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD4
> > > LVb1o
> > >
> >
> z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae@
> > > x0z
> > >
> >
> z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDunn
> > > ~4&d
> > >
> >
> zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moAu
> > > G$}Tz
> > > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ-
> > Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@
> > > =?WW
> > > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I-
> > )fwRt3qD8qt(
> > > {
> > > z<P<KF=}PJ1#r#`jS-C-
> > BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a
> > > (X
> > > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB-
> > $@AJqDd(YoB@ZYfK6vP54O
> > > =^o2
> > >
> >
> z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*uaN
> > > g
> > >
> zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(;
> > > P
> > >
> zV+-mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjD
> > > mu
> > >
> >
> z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF
> > > {3
> > > zwPHdUsL_Emi-
> > |sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtx
> > > tn
> > > zbrc)1<0dX~X#twYtTp`&I-
> > K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZ
> > > n
> > >
> >
> zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5
> > > +#Xc
> > > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%-
> > xVei
> > > qO1Hf
> > >
> >
> z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}FcU
> > > <cW
> > >
> zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c-
> > > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?-
> > up`F97
> > > _
> > >
> >
> zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A)e
> > > PVQj
> > >
> z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>jT
> > > z4)s@IGNTe?4-@J{iz-J0sXQl-
> > t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(P
> > > U}
> > >
> >
> zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}&
> > > jB
> > >
> >
> zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F9
> > > XPvK
> > >
> z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ck
> > > N
> > > zH}9#C6|qJ(-
> > ~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb
> > > 5c
> > >
> zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyx
> > > C
> > > z(-
> > KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr
> > > |
> > >
> >
> zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcUS
> > > n)edp
> > >
> >
> zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh
> > > 94r
> > >
> >
> z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qGk
> > > Q;
> > >
> >
> zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}ZS
> > >
> z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B!
> > > zLKgK@^uHSZLNEF1>n3-
> > )R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wP
> > > T*O
> > >
> z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL?
> > >
> zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB>
> > > 4f|!
> > > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF-
> > f1_RXCi@Ib*0
> > >
> z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-fDferp0V!X9B0;Fs85@B4
> > > 8XtM
> > >
> >
> z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fHSi
> > > Vn
> > > zP5ZAFYbCS1g7-
> > `&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9G
> > > uEt
> > >
> >
> zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4N
> > > Vpdll
> > > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a-
> > 3`@t)z}?8R=?u@$Rw&yc>*^x
> > >
> >
> zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{
> > > %xn
> > > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0
> > >
> zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-^FvPyUB5
> > > B
> > >
> >
> zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm
> > > 5jhv7qJ6
> > >
> zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs
> > > G&n
> > >
> zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc
> > > X7Yw
> > >
> zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*-
> > s7
> > > b^
> > >
> zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm
> > > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR-
> > qjhh
> > > O
> > >
> >
> zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)|
> > > CS
> > > z^GD&-H%jsm7i~c(IDGo_-
> > ?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*y
> > > w
> > > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h-
> > %XTOuIK%jeRlC4YOaKdYsipAm+
> > > WrxJ
> > >
> >
> z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%_
> > > emtz|
> > >
> >
> zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alV
> > q
> > > N6
> > >
> >
> zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3wQ
> > > 9VH
> > >
> >
> zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39Td
> > > R
> > > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm-
> > z5jm=aFjj$na3>$mvN|33HD3iFuOn0
> > > va3
> > >
> >
> z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{k
> > >
> >
> zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgic
> > > ;
> > > zO)ScHYd^W4>p1IZF-
> > rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9I
> > > nuw
> > >
> >
> zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Spq
> > > ~p!H
> > >
> >
> zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaBR
> > >
> z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH
> > > @xAy1o
> > > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;-
> > FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq
> > > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb-
> > d5Kj>373=4;|gla3^9<xGWqY!YN
> > >
> zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF
> > > ^
> > >
> >
> z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdVe
> > >
> z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-zaH)%
> > > 6TeU
> > > zDai3Q)sDP}fd8!F4@GgYGt3O#w-
> > T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=&
> > > !#
> > > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ
> > >
> zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A>
> > > JLS
> > >
> >
> zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^B
> > > ^2@xF
> > >
> zjonUY-5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo-
> > 1(
> > > TU>k
> > > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q-
> > I>Wsn^_=%oN0?9m<2++S;$}<NQ
> > > !2w
> > >
> z?D}Sa^U&-{Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y
> > > @4wr+
> > >
> >
> z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW
> > > igCND
> > >
> >
> zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9G
> > > f
> > >
> >
> zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7WnM
> > > +HRe
> > >
> zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7>
> > >
> za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!-
> > N|
> > > -
> > > z;QcJ-
> > _4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2
> > > Vq6r2
> > >
> zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-g!hJtN?o_BdRpcbbxsh0DZ+c_Y(
> > >
> >
> z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^X
> > > ^
> > >
> zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL
> > >
> z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-@2p`Q1mt6FY&K(r;IDDBlIE3o
> > > @ew
> > >
> zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij%
> > > 2fn_q4
> > >
> zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-r13r%jU`>
> > > =!
> > >
> z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-uaNP1Hw%
> > > <b
> > >
> >
> zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!d
> > > {;+cG)
> > > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z-
> > 9KqzX4ywpKgSlL&Lplu
> > > #f5K
> > >
> >
> zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhuN
> > > Be
> > >
> >
> zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%qb
> > > `1J
> > >
> >
> zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n6
> > > h9#
> > >
> >
> z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW
> > > Ts
> > > z@juu7-
> > 1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HS
> > > pa}
> > > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;-
> > DANP
> > > e-
> > > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O-
> > 5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV5
> > > 6
> > > z4%Obc4bQ}m#H`ZWui1dCf-
> > 8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2q
> > > a
> > >
> zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-4`oYb>K>
> > > Mz
> > > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4-
> > gIH0R$|yhL0%iyEWP)
> > > -dMFq
> > >
> zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-g*YKLtRiZRx3P1h$De+)0Slkv%n4;
> > >
> zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(-
> > #
> > > w5
> > > zSQe21-
> > iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH
> > >
> >
> zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=-
> > > h3
> > > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#-
> > u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6
> > >
> >
> zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*V
> > > B
> > >
> >
> z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii
> > > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C-
> > NcZPpT3FT+YGkGFM
> > > 6L6
> > >
> zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-*5bib>R|Lb3>
> > > 49;t
> > >
> >
> z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@
> > > ZoU
> > > z1o^bK^-
> > i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e
> > > <06
> > >
> >
> zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23
> > > |;
> > > zI-
> > 8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0
> > > p%hX
> > > z-z&;-
> > 5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{
> > > O2
> > >
> zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(*
> > >
> >
> znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf
> > >
> >
> zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL
> > > mu
> > > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt-
> > )j9cW`J=^32#Q
> > > _0v=
> > > zYuS>-
> > !$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4
> > > T3
> > > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d-
> > y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%(
> > > U
> > > z6;SpLK}$lNH+Qlh-cKR-
> > YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>&
> > > oV-UQQh
> > >
> >
> zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0U(
> > > c{
> > > zfIZlR!@-
> > s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld*
> > >
> >
> zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e<
> > > WpJJ
> > > z-
> > `$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ
> > > N;@<uUxT
> > > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@-
> > auQ<`tj
> > > RFOs
> > >
> >
> z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^A
> > > m
> > >
> >
> zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}A
> > > G
> > >
> >
> zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB
> > > e+D$Sx
> > >
> zjN(RqZ>bYB5w+-;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-|
> > >
> z2UiCg{->;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7<
> > > K
> > > zTOHkDcgdOyfsEiOu%WtEi(>#Z-
> > ~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pY
> > > u|
> > > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG-
> > KacrZ
> > > _
> > >
> zb9^@-j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG>
> > > N9F
> > > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U-
> > w88FH|Vp0NA28vf|sjS
> > > i!
> > > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt-
> > fK$0VNHs&Mk>^C1D
> > >
> >
> zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Ce
> > > z$GM4
> > >
> zROF{;hFBi-eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV?
> > > ?+@e
> > > zg`wK!-l8aDa_m35OpOA{bq~|+%F-
> > ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ
> > > {
> > >
> zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY
> > >
> >
> zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2GE
> > > f!T<
> > > z2ci!iV-wM?Bu7s^Huqb-
> > 4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#C
> > > Ct6d4
> > >
> >
> z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p;
> > > %j)
> > >
> > z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu
> > > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%-
> > (2Z`Wl
> > > @e
> > >
> >
> zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L1
> > > Smv
> > >
> z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-7j{eN?7xE
> > > TIA
> > >
> zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH-
> > #T
> > > #5p
> > >
> z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV
> > > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS-
> > W4+WUsh43&>4RG*{QQ#GI!w
> > > phN<ut
> > >
> >
> z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O!
> > > 8
> > >
> >
> z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sIPC
> > > li
> > >
> zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-pCM+y02CSF
> > > no2|(R
> > >
> >
> zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS
> > > 4D;
> > > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R-
> > Jpx~r9!pm?4kz;k|ao%zB@5Hbe
> > > <
> > >
> >
> z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV
> > > $~Mw0
> > > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM-
> > j_UaA
> > > x<g;
> > > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu-
> > o$d)MnXpluW?a_({zl
> > > g
> > >
> >
> zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^
> > > Nsh
> > >
> zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^
> > > H>
> > > z@#^-
> > Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5#
> > > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd-
> > Ge_d>@
> > > =&
> > >
> >
> zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK<
> > > zN_8RoATaW}d{5!m3i1gyT+$O()xZN-
> > q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n
> > >
> z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-5<hd8`
> > > AC$53
> > >
> >
> zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d
> > > 7^x3lQL
> > >
> >
> zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t
> > > ^
> > > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n-
> > ;m<n!p%lxe5r|
> > >
> zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--O%ZaQ5exOt&$Uj1Z*HD)
> > > S*
> > > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8-
> > 9ip&dZ
> > > 5@B
> > >
> z-&*JW0-3YW2Pq-<fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja
> > >
> >
> zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D
> > > @Lj
> > >
> zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_`
> > > ?(Q=eq
> > >
> >
> zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^su
> > > !
> > >
> >
> zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n`
> > > lly-i
> > >
> z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77-
> > ?_
> > > D
> > > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=-
> > #ZF|U1if%4r0!Fqa4AKSYGr=Bp4
> > > wS;j
> > >
> >
> zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$f
> > > B
> > >
> zeFN6df-a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<w
> > > SvXa
> > >
> >
> zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~Vg
> > > @KJ
> > >
> zylHB<K26UdQ2ABqe^F8fV<cmx2rW-)4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL`
> > > =`
> > > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q-
> > |Gt8<U$^Rmw`&o%H;FN+S+(N
> > > H@-}E
> > >
> z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-Otc}jM55$Vtv405ZD8XyXx
> > > qT
> > >
> >
> z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ&
> > >
> z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7
> > > v#qf
> > >
> z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp*
> > > M&
> > >
> >
> z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXjf
> > >
> zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!%
> > > R0i
> > >
> >
> z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C
> > > m*DkC
> > > zHs9kcukmSQnY-`;FsIMBQNgVP-
> > Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd
> > > 6
> > >
> zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU
> > > 7F@}
> > > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI-
> > W354EXdcSk^K;5aK
> > > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)-
> > a48PghrZ+3AO}YN
> > > &bdTo
> > >
> >
> ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8zk
> > > ce
> > >
> zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-MgiMENG=ijNg0)d+}c;
> > > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO-
> > KB7MVoi
> > > X`~8>
> > >
> >
> z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+>E
> > > h
> > > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe-
> > jybQSioRnO
> > > 6
> > > zpm;JeMEQciVCPbow+)K59-
> > z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSs
> > > X$9
> > >
> >
> zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJfps
> > > 19
> > > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM-
> > V3W7dJ0WrB4
> > > !!+0k
> > > z;zYZk1x)Y5=+Q4I`1dZe_-
> > J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~
> > > h
> > >
> >
> zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1KY
> > > ^|^o
> > >
> >
> zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY
> > > w
> > > z8&-
> > yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_
> > > Pl}l
> > > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn-
> > cjsU7u?E8Rr%=Go&yh&47sj4
> > > @fk~gw
> > >
> >
> zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))oz;
> > > Vn
> > > z-
> > 7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH-
> > > #bB
> > > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W-
> > 7Me#XrQ^Tzt>kfFu8R(s
> > > Yw
> > >
> zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-HozIURZx??rFE2R1&lHytBUXnb8s0Ooi
> > > G
> > >
> >
> z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=|
> > > B
> > > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU-
> > `l%kXo|H)KHVD6KW
> > > h*Rz
> > >
> zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx=
> > > &<
> > >
> >
> zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^gT
> > >
> >
> zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3ACr
> > > 1>
> > > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx-
> > gL}d<c_Mn^@%_FE+g
> > > ?M
> > >
> zOu>-D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BB
> > > m<8{
> > >
> >
> zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hXB
> > > rHu
> > > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB-
> > gw(`|azE*a<_S1weMZAOo%w(L
> > > )Kl
> > > z-
> > dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_
> > > 3&$$E$
> > >
> z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3-
> > B{
> > > GV
> > >
> zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-ii1s
> > >
> >
> z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d
> > > N
> > >
> >
> zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>f
> > > E#
> > >
> ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l
> > > 27AMD
> > >
> >
> z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LYql
> > > amYM
> > >
> zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-nmZ}%^`N$?z`4}RqF82uB)V>)}QE?
> > >
> zrWiuym1^BE%d4kuv-dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7
> > > W<MJ
> > > z%-
> > SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lH
> > > R8=T
> > > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo-
> > @a)b+Ml`1F<g{$T*e1di)$*fQ5m
> > > |)PQDO
> > >
> ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-69N^MI1)$EFwkLm8>
> > > ;g4
> > >
> zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5NF
> > > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA-
> > k%PLdC*dz
> > > w1?
> > >
> z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c<
> > > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G-
> > H!u*oMbA8
> > > 4$
> > >
> zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q|
> > >
> >
> z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<dd
> > > WSp
> > >
> >
> z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMCK
> > > !+9
> > >
> zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ->LB_tbbsj!WAr(Gsq%
> > > zw_MRqd{G)1`B`l*-
> > mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg
> > > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~
> > >
> >
> zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1GhtA
> > > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6-
> > 9?bOShFo2W$of{J{
> > > gHl
> > >
> zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y
> > > $TzS4WWp
> > >
> z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_}
> > >
> >
> zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7#
> > > T9bz
> > >
> >
> zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r;
> > > 7VlOw;
> > >
> z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-s9fgjkjr739K6W}g;
> > >
> >
> zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p@
> > > ~Q`G
> > > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s-
> > 2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v
> > > z8QwfoitD*@-
> > 5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j
> > > ~x
> > >
> >
> zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&o
> > > }${B{GLO@
> > >
> z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-3_YO
> > > >
> > >
> zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-jlPsK67!Q>`7U~k~@(
> > > W
> > >
> z{H{Q{1-K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r#
> > > JmFX
> > >
> >
> zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0
> > > TYK
> > > z-`2+H1Yr#7j9>-
> > Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M
> > > $i
> > >
> zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@}
> > > 8Q-
> > >
> >
> zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVzVB
> > > {d;Z$
> > > z>%q~GMLth%$)7kc<>-
> > ;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX
> > > =3xm
> > >
> >
> zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW2
> > > eba=c
> > >
> >
> zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUTn
> > > vLvp4*
> > >
> >
> zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~mM
> > J
> > > XCoBHnW
> > > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1
> > > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f
> > >
> zSOT@Xr1Bh-bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO-
> > 2
> > > |a}K?r
> > > zFo(mo@$6w!RCO;!k{m2{z-
> > _`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C
> > > _9
> > >
> >
> ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#u
> > > G8
> > >
> >
> z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o|
> > > p
> > >
> >
> z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|hrK
> > > pU
> > >
> zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G
> > > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`-
> > GBdrly&WQ1*?kDL@
> > > pG<V!
> > > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3-
> > JyC<keh(WCoDi(@n0xqm`@&*0R>;
> > > SVa
> > >
> zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?-
> > i$S
> > > )
> > >
> z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-ABGpf_{Tj
> > > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#-
> > 5>lJ2jXZ|?d~C=
> > > n*V
> > >
> >
> zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRCR
> > > 6na4
> > > zw-
> > T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+L
> > > i
> > > zajQH#9E-
> > re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L
> > > 675^
> > > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T-
> > 5)vkqIFntDZMA1VMOHjx#|#
> > > gp
> > > z<=jzFhYH`U9&O8-fDan`-
> > Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQ
> > > s9
> > >
> z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-U+iW$vXVhjdwb1+
> > > B<
> > >
> zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(-
> > AS
> > > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W-
> > JCA@y|<k2?s=otq
> > > kXs
> > >
> zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-n$&cdT0?4AaJ{y8Haf%
> > > 6
> > >
> ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLcg
> > > V>
> > >
> z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}-
> > >
> >
> zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7OP
> > > e+{
> > > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b-
> > LbUdRv*H4Cj>iO=b6AU_W
> > > kt_g
> > >
> zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><}
> > > &(L
> > >
> ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-dFS5is`M~bDz>$vvzPgi#c=y}m?56~
> > >
> >
> zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqCA
> > I
> > > uWDE
> > >
> >
> z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy
> > > WSRlcK
> > >
> zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-@Y*KD|29REbj1RxL
> > > =h8r
> > >
> >
> z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L
> > > M^W
> > >
> z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7?
> > > _YY
> > > zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf(
> > >
> >
> zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@W
> > > u$Jn
> > >
> >
> zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`j
> > > Uyi#
> > > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1-
> > 7wk8y&7D+XUbG
> > > qc
> > >
> >
> zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{
> > > B?
> > > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR-
> > `ynB}GDY7)z8WdiaOz1?
> > > $
> > >
> >
> z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2
> > > w_fKH^bO
> > >
> >
> zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C>
> > > r
> > >
> >
> z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_Y
> > b
> > > }g
> > >
> zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-{XinIi7VVr+Ml&Uk80i^?uHs^eFi
> > > zXl`9?-
> > $MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29
> > > @(BH
> > > zQPs%IT;9S({?mP*=Qnc|D5J-
> > |w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf=
> > > c
> > > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4-
> > F^%90(P&<beWqvDXsg0?i
> > > WV^Yr
> > >
> zBw90n4C4q-<Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxz
> > > m*iO
> > > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv-
> > 0T#hDV!d
> > > ^^pp
> > >
> >
> zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X{
> > >
> zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I;
> > >
> >
> zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJu
> > > G
> > > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da-
> > R)wUYvP#%R8D{%W4M3=p@E&YpC5Y
> > > <^3Ym
> > > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%-
> > wXl_NyC`0qB
> > > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr-
> > wIc*7P
> > > U)!KE
> > > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek-
> > a?2dg6PVM6GVX~3`oj
> > > %%M;
> > >
> >
> z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S%je
> > > zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i
> > >
> z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`>
> > > g
> > > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T-
> > 2DeQ#fI
> > > 0ra
> > >
> zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90%
> > > U2ISK
> > > z7k~rD4m&7xFAX&{$U-
> > )37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPA
> > > m&$g3
> > >
> >
> z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n
> > > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;-
> > d#*zW#Tye9hV)P&G*REZ2he+xK461i
> > > S
> > > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+-
> > @izT8*fdO5W<a
> > > <>h=
> > > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O-
> > U`a;Yy~M(7
> > > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0-
> > *)&Q!XszxM?Zk
> > > c
> > > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>-
> > Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s
> > >
> >
> z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB
> > > ^
> > >
> z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9Y
> > > mQ9
> > > z7-54~(UFH?f-
> > J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V
> > > zmVbN(^|1#(h+-lD+oK-
> > PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;W
> > > b
> > > zObewKL-
> > P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E
> > > ~AL
> > >
> zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ
> > > mE}
> > >
> >
> zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?FS
> > > Ar
> > >
> >
> zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{
> > > eM#TotF
> > > zf2^1WUw|=jGZ{M_KC6YOEM6I@-
> > R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ>
> > > -!8~
> > >
> zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-G
> > > w
> > >
> >
> z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tupJ
> > > vh0
> > > z2yd+qIez;p={X=o?0-
> > ^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F
> > > 9F
> > > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi-
> > 7AsygbO%g|<oo|
> > > F
> > >
> >
> zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7
> > > mcGpsI
> > >
> >
> zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@z
> > > eLf}n
> > >
> z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_
> > > V58p
> > >
> >
> z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE;
> > > _G
> > > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?-
> > MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zC
> > > uL|
> > >
> >
> zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+Y
> > > 7
> > > z*L9AUT{ijtMS0dcKOCKHpr-
> > +xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDR
> > > p+
> > > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi-
> > eFOmG^@5nqfLK@zsHWvFIpCjl0MVjS
> > > Q!<O&
> > > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r-
> > sKrwU
> > > sCLRyE
> > >
> >
> z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H1
> > > shL
> > >
> zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-PRL>58O!#8GQp{Cl!yQ=7U
> > > e@
> > >
> zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-Xj6S$`8%)2B=C`%#X^UsJk;r
> > >
> >
> za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;qp`
> > >
> zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4
> > > +q
> > > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D-
> > B$kndG=Y6ir}mBr@$2Y+D1hg2`
> > > HSFo?UV4
> > > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs-
> > U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73
> > > t+H6
> > >
> z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-@dCgu?*w68w7U@T2W
> > > 0@Pm_Y
> > >
> zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j)
> > >
> zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-`0?1~a)A*1Aq5ZF=PJX$`K|xwK
> > >
> zy(%Iv1B}78tU<S)-be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3
> > >
> z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P
> > >
> z1nf4JzkGvgr`ceSUg-Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH
> > >
> z3w%^07<cfvxTKF%TLy@HO*}pati@R-^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t
> > > $g7Mc
> > >
> >
> z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*Lw
> > > g4XT
> > > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2-
> > &x>7Mi3KPo##3Vi5A!D
> > > ~zVd
> > >
> >
> zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiHJ
> > > )g}U
> > >
> zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo
> > > aKg
> > > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y-
> > AD^;!g
> > > x|
> > >
> z$J~t&UI|{AvEA-al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3
> > > R
> > > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V-
> > O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0v
> > > OZ
> > >
> >
> z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz-
> > > DH
> > >
> z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy->D4Sb%Y2fkipxK`3NB{Zs52
> > > m?
> > > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET-
> > fIoOZ<f~u
> > > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol-
> > KEmeMx`wo+msu_i=!gCUc5
> > > aAFo
> > > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o-
> > UlMiBIpwFoxSL(w@3J7A9556*;P>na
> > > q(Up`
> > >
> z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-kp8;RCbBEh(6<t|#mnjgI<XQTE7
> > >
> zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr
> > >
> >
> zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei5
> > > k7
> > >
> >
> zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm37i
> > > ?0^U
> > >
> zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-E?}44V&fVSJuUy6C
> > >
> zVZ0QL^9EL}Q+rmi0+hKCO-*YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq
> > > $
> > >
> >
> zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm`
> > > `jz`
> > >
> >
> zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGqr
> > > T%2I
> > > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69-
> > HYb
> > >
> >
> z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9
> > >
> >
> zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh*
> > > !tsx
> > >
> zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C
> > >
> >
> z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWiD
> > > &
> > >
> zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X
> > > @*1fT
> > > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr-
> > G6WS1r9|13yh@
> > > Y{v
> > > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6-
> > {$zk^x|sZJl
> > > O+j
> > >
> zD@^qM5wtrWID6Oyl8t{E-+S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>x
> > > LE}S
> > > zE-
> > yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9`
> > > UBK8
> > > zQ#_-
> > WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2s
> > > HLzP7
> > >
> >
> zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om*
> > > TH
> > >
> zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-5!57<DY112C{RV#CHr&VX%UAd_Wt&=
> > > w*FLg
> > > zsI<EKP=R6SqF-
> > IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6D
> > > k*l
> > >
> z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt
> > > gvZ`h
> > >
> zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-q7*)zY+6;7LJvM>HeW?
> > > MMr
> > >
> zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j%
> > > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u-
> > _fVYHP%QJS6G+)Vr9%12
> > > >J
> > >
> z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw
> > > Mk8(V
> > > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)-
> > ?sMK$L?>Ng)`3v
> > > `R
> > >
> >
> z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl
> > > NJlM
> > > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi-
> > f1#Bw(VP<qeg{%cT1IJ97@nLSx
> > > z_X-
> > ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT4
> > > 5
> > > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4-
> > kyiVyjuy47$
> > > @|
> > >
> z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk
> > > q6<X@
> > > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu-
> > b=1;<A1a(HF7
> > > `i
> > >
> z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y-
> > <
> > > @
> > > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb-
> > %NnQFS!>!e+)H<J7
> > > %
> > >
> >
> z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rzq
> > > )L
> > > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh-
> > @%MC4@d
> > > 0h&s<FN
> > > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V-
> > _M01I|
> > > m8wTMI
> > >
> >
> zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5Ld
> > > (#T`
> > > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK-
> > OFjWJG?jVvSoZ_a6
> > > jbw
> > >
> zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa
> > > qQ
> > > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX-
> > B8hJF!+PDU)2Ng~^@q8b
> > > e+U
> > >
> zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk
> > >
> >
> zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo
> > >
> >
> zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L
> > > cp
> > > zKSVWp#RY$Lhkns{H6-
> > Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0x
> > > d}
> > >
> >
> zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3f
> > >
> zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*-
> > i8
> > > r$$4
> > > zZOqr7#;sW-
> > rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_;
> > > 4Fzt
> > > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob-
> > K5PWDTzJUeq*If}X<4`_2c(`X*0
> > > z6;L!+h$=hX6x?t-
> > Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY
> > > <t#vw;
> > >
> >
> z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ovG
> > > zsy
> > > z&r3>eq@*BKMfN&W*>mt#-
> > zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d
> > > 4t+{
> > >
> >
> zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf
> > > is
> > >
> >
> ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U;
> > > ?2
> > >
> >
> zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUcv
> > > *TAdi
> > >
> zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS
> > >
> zgMq{Gq@-5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I
> > >
> >
> zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)l
> > > hv
> > >
> >
> z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{kK
> > >
> z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{K
> > > B(|Tz
> > >
> z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-WUnk+a@~B7zHP#Z}O$jL{+
> > > XbfG
> > > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^-
> > ;pwarlq8+@E8O5*D1MF
> > > F1&w
> > >
> zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-i<&Go;8D`(=Fz!ud
> > >
> >
> zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)AA
> > > ^H
> > >
> >
> z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<Wv
> > > jX2
> > > RBat2OV|2<CTVmi8`9DHIo&o>>
> > >
> > > literal 0
> > > HcmV?d00001
> > >
> > > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py
> > > b/BaseTools/Source/Python/FMMT/PI/Common.py
> > > new file mode 100644
> > > index 000000000000..efab874ee08b
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py
> > > @@ -0,0 +1,81 @@
> > > +## @file
> > > +# This file is used to define the common C struct and functions.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from ctypes import *
> > > +import uuid
> > > +
> > > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
> > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> > > uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
> > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> > > uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
> > > +# EFI_FFS_VOLUME_TOP_FILE_GUID =
> > > uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
> > > +
> > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID =
> > > uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> > > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> > > EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
> > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID =
> > > uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> > > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> > > b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> > > b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
> > > +EFI_SYSTEM_NVDATA_FV_GUID =
> > > uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
> > > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE =
> > > b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
> > > +EFI_FFS_VOLUME_TOP_FILE_GUID =
> > > uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
> > > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE =
> > > b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
> > > +ZEROVECTOR_BYTE =
> > >
> b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
> > > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
> > > +FVH_SIGNATURE = b'_FVH'
> > > +
> > > +class GUID(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Guid1', c_uint32),
> > > + ('Guid2', c_uint16),
> > > + ('Guid3', c_uint16),
> > > + ('Guid4', ARRAY(c_uint8, 8)),
> > > + ]
> > > +
> > > + def from_list(self, listformat: list) -> None:
> > > + self.Guid1 = listformat[0]
> > > + self.Guid2 = listformat[1]
> > > + self.Guid3 = listformat[2]
> > > + for i in range(8):
> > > + self.Guid4[i] = listformat[i+3]
> > > +
> > > + def __cmp__(self, otherguid) -> bool:
> > > + if not isinstance(otherguid, GUID):
> > > + return 'Input is not the GUID instance!'
> > > + rt = False
> > > + if self.Guid1 == otherguid.Guid1 and self.Guid2 ==
> > otherguid.Guid2
> > > and self.Guid3 == otherguid.Guid3:
> > > + rt = True
> > > + for i in range(8):
> > > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
> > > + return rt
> > > +
> > > +def ModifyGuidFormat(target_guid: str) -> GUID:
> > > + target_guid = target_guid.replace('-', '')
> > > + target_list = []
> > > + start = [0,8,12,16,18,20,22,24,26,28,30]
> > > + end = [8,12,16,18,20,22,24,26,28,30,32]
> > > + num = len(start)
> > > + for pos in range(num):
> > > + new_value = int(target_guid[start[pos]:end[pos]], 16)
> > > + target_list.append(new_value)
> > > + new_format = GUID()
> > > + new_format.from_list(target_list)
> > > + return new_format
> > > +
> > > +
> > > +# Get data from ctypes to bytes.
> > > +def struct2stream(s) -> bytes:
> > > + length = sizeof(s)
> > > + p = cast(pointer(s), POINTER(c_char * length))
> > > + return p.contents.raw
> > > +
> > > +
> > > +
> > > +def GetPadSize(Size: int, alignment: int) -> int:
> > > + if Size % alignment == 0:
> > > + return 0
> > > + Pad_Size = alignment - Size % alignment
> > > + return Pad_Size
> > > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > > b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > > new file mode 100644
> > > index 000000000000..33c49ffb50bc
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > > @@ -0,0 +1,66 @@
> > > +## @file
> > > +# This file is used to define the Ffs Header C Struct.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from struct import *
> > > +from ctypes import *
> > > +from PI.Common import *
> > > +
> > > +EFI_FFS_FILE_HEADER_LEN = 24
> > > +EFI_FFS_FILE_HEADER2_LEN = 32
> > > +
> > > +class CHECK_SUM(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Header', c_uint8),
> > > + ('File', c_uint8),
> > > + ]
> > > +
> > > +class EFI_FFS_INTEGRITY_CHECK(Union):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Checksum', CHECK_SUM),
> > > + ('Checksum16', c_uint16),
> > > + ]
> > > +
> > > +
> > > +class EFI_FFS_FILE_HEADER(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Name', GUID),
> > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > > + ('Type', c_uint8),
> > > + ('Attributes', c_uint8),
> > > + ('Size', ARRAY(c_uint8, 3)),
> > > + ('State', c_uint8),
> > > + ]
> > > +
> > > + @property
> > > + def FFS_FILE_SIZE(self) -> int:
> > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > > +
> > > + @property
> > > + def HeaderLength(self) -> int:
> > > + return 24
> > > +
> > > +class EFI_FFS_FILE_HEADER2(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Name', GUID),
> > > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > > + ('Type', c_uint8),
> > > + ('Attributes', c_uint8),
> > > + ('Size', ARRAY(c_uint8, 3)),
> > > + ('State', c_uint8),
> > > + ('ExtendedSize', c_uint64),
> > > + ]
> > > +
> > > + @property
> > > + def FFS_FILE_SIZE(self) -> int:
> > > + return self.ExtendedSize
> > > +
> > > + @property
> > > + def HeaderLength(self) -> int:
> > > + return 32
> > > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > > b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > > new file mode 100644
> > > index 000000000000..aae2feae844a
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > > @@ -0,0 +1,112 @@
> > > +## @file
> > > +# This file is used to define the FV Header C Struct.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from ast import Str
> > > +from struct import *
> > > +from ctypes import *
> > > +from PI.Common import *
> > > +
> > > +class EFI_FV_BLOCK_MAP_ENTRY(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('NumBlocks', c_uint32),
> > > + ('Length', c_uint32),
> > > + ]
> > > +
> > > +
> > > +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > > + _fields_ = [
> > > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > > + ('FileSystemGuid', GUID),
> > > + ('FvLength', c_uint64),
> > > + ('Signature', c_uint32),
> > > + ('Attributes', c_uint32),
> > > + ('HeaderLength', c_uint16),
> > > + ('Checksum', c_uint16),
> > > + ('ExtHeaderOffset', c_uint16),
> > > + ('Reserved', c_uint8),
> > > + ('Revision', c_uint8),
> > > + ('BlockMap',
> ARRAY(EFI_FV_BLOCK_MAP_ENTRY,
> > > 1)),
> > > + ]
> > > +
> > > +def Refine_FV_Header(nums):
> > > + class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > > + _fields_ = [
> > > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > > + ('FileSystemGuid', GUID),
> > > + ('FvLength', c_uint64),
> > > + ('Signature', c_uint32),
> > > + ('Attributes', c_uint32),
> > > + ('HeaderLength', c_uint16),
> > > + ('Checksum', c_uint16),
> > > + ('ExtHeaderOffset', c_uint16),
> > > + ('Reserved', c_uint8),
> > > + ('Revision', c_uint8),
> > > + ('BlockMap',
> > > ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
> > > + ]
> > > + return EFI_FIRMWARE_VOLUME_HEADER
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
> > > + _fields_ = [
> > > + ('FvName', GUID),
> > > + ('ExtHeaderSize', c_uint32)
> > > + ]
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
> > > + _fields_ = [
> > > + ('ExtEntrySize', c_uint16),
> > > + ('ExtEntryType', c_uint16)
> > > + ]
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('TypeMask', c_uint32)
> > > + ]
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('TypeMask', c_uint32),
> > > + ('Types', ARRAY(GUID, 1))
> > > + ]
> > > +
> > > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) ->
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
> > > + class
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('TypeMask', c_uint32),
> > > + ('Types', ARRAY(GUID, nums))
> > > + ]
> > > + return
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('FormatType', GUID)
> > > + ]
> > > +
> > > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('FormatType', GUID),
> > > + ('Data', ARRAY(c_uint8, 1))
> > > + ]
> > > +
> > > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) ->
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
> > > + class
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('FormatType', GUID),
> > > + ('Data', ARRAY(c_uint8, nums))
> > > + ]
> > > + return
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
> > > +
> > > +class
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
> > > + _fields_ = [
> > > + ('Hdr',
> > > EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > > + ('UsedSize', c_uint32)
> > > + ]
> > > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > > b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > > new file mode 100644
> > > index 000000000000..c2cc8e0172fb
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > > @@ -0,0 +1,110 @@
> > > +## @file
> > > +# This file is used to define the Section Header C Struct.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from struct import *
> > > +from ctypes import *
> > > +from PI.Common import *
> > > +
> > > +EFI_COMMON_SECTION_HEADER_LEN = 4
> > > +EFI_COMMON_SECTION_HEADER2_LEN = 8
> > > +
> > > +class EFI_COMMON_SECTION_HEADER(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Size', ARRAY(c_uint8, 3)),
> > > + ('Type', c_uint8),
> > > + ]
> > > +
> > > + @property
> > > + def SECTION_SIZE(self) -> int:
> > > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > > +
> > > + def Common_Header_Size(self) -> int:
> > > + return 4
> > > +
> > > +class EFI_COMMON_SECTION_HEADER2(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('Size', ARRAY(c_uint8, 3)),
> > > + ('Type', c_uint8),
> > > + ('ExtendedSize', c_uint32),
> > > + ]
> > > +
> > > + @property
> > > + def SECTION_SIZE(self) -> int:
> > > + return self.ExtendedSize
> > > +
> > > + def Common_Header_Size(self) -> int:
> > > + return 8
> > > +
> > > +class EFI_COMPRESSION_SECTION(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('UncompressedLength', c_uint32),
> > > + ('CompressionType', c_uint8),
> > > + ]
> > > +
> > > + def ExtHeaderSize(self) -> int:
> > > + return 5
> > > +
> > > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('SubTypeGuid', GUID),
> > > + ]
> > > +
> > > + def ExtHeaderSize(self) -> int:
> > > + return 16
> > > +
> > > +class EFI_GUID_DEFINED_SECTION(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('SectionDefinitionGuid', GUID),
> > > + ('DataOffset', c_uint16),
> > > + ('Attributes', c_uint16),
> > > + ]
> > > +
> > > + def ExtHeaderSize(self) -> int:
> > > + return 20
> > > +
> > > +def Get_USER_INTERFACE_Header(nums: int):
> > > + class EFI_SECTION_USER_INTERFACE(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('FileNameString', ARRAY(c_uint16, nums)),
> > > + ]
> > > +
> > > + def ExtHeaderSize(self) -> int:
> > > + return 2 * nums
> > > +
> > > + def GetUiString(self) -> str:
> > > + UiString = ''
> > > + for i in range(nums):
> > > + if self.FileNameString[i]:
> > > + UiString += chr(self.FileNameString[i])
> > > + return UiString
> > > +
> > > + return EFI_SECTION_USER_INTERFACE
> > > +
> > > +def Get_VERSION_Header(nums: int):
> > > + class EFI_SECTION_VERSION(Structure):
> > > + _pack_ = 1
> > > + _fields_ = [
> > > + ('BuildNumber', c_uint16),
> > > + ('VersionString', ARRAY(c_uint16, nums)),
> > > + ]
> > > +
> > > + def ExtHeaderSize(self) -> int:
> > > + return 2 * (nums+1)
> > > +
> > > + def GetVersionString(self) -> str:
> > > + VersionString = ''
> > > + for i in range(nums):
> > > + if self.VersionString[i]:
> > > + VersionString += chr(self.VersionString[i])
> > > + return VersionString
> > > +
> > > + return EFI_SECTION_VERSION
> > > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py
> > > b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > > new file mode 100644
> > > index 000000000000..4e8296fad1ba
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > > @@ -0,0 +1,6 @@
> > > +## @file
> > > +# This file is used to define the FMMT dependent external tool
> > management
> > > class.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/README.md
> > > b/BaseTools/Source/Python/FMMT/README.md
> > > new file mode 100644
> > > index 000000000000..e14dfa34ea66
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/README.md
> > > @@ -0,0 +1,180 @@
> > > +# FMMT
> > > +## Overview
> > > +This FMMT tool is the python implementation of the edk2 FMMT tool
> > which
> > > locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
> > > +This implementation has the same usage as the edk2 FMMT, but it's
> more
> > > readable and relaiable.
> > > +
> > > +# FMMT User Guide
> > > +
> > > +#### Last updated October 13, 2021
> > > +
> > > +Important Changes and Updates:
> > > +
> > > +- Oct 13, 2021 Initial Draft of FMMT Python Tool
> > > +
> > > +#### Note:
> > > +
> > > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is
> > > much easier to maintain and extend other functions.
> > > +
> > > +
> > > +
> > > +# 1. Introduction
> > > +
> > > +## 1.1 Overview
> > > +
> > > +The Firmware Device is a persistent physical repository that contains
> > > firmware code and/or data. The firmware code and/or data stored in
> > > Firmware Volumes. Detail layout of Firmware Volumes is described in
> > ?Figure
> > > 1. The Firmware Volume Format?.
> > > +
> > > +![](Img/FirmwareVolumeFormat.png)
> > > +
> > > +<center>Figure 1. The Firmware Volume Format</center>
> > > +
> > > +In firmware development, binary file has its firmware layout following
> > the
> > > Platform-Initialization Specification. Thus, operation on FV file / FFS
> > file
> > > (Firmware File) is an efficient and convenient way for firmware function
> > > testing and developing. FMMT Python tool is used for firmware files
> > > operation.
> > > +
> > > +## 1.2 Tool Capabilities
> > > +
> > > +The FMMT tool is capable of:
> > > +
> > > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware
> > > Files)
> > > +
> > > +- Add a new FFS into a FV file (both included in a FD file or not)
> > > +
> > > +- Replace an FFS in a FV file with a new FFS file
> > > +
> > > +- Delete an FFS in a FV file (both included in a FD file or not)
> > > +
> > > +- Extract the FFS from a FV file (both includ-v < Inputfile > <
> > Outputfile >ed
> > > in a FD file or not)
> > > +
> > > +## 1.3 References
> > > +
> > > +| Document |
> > > +| ------------------------------------------------ |
> > > +| UEFI Platform Initialization (PI) Specification |
> > > +
> > > +
> > > +
> > > +# 2. FMMT Python Tool Usage
> > > +
> > > +## 2.1 Required Files
> > > +
> > > +### 2.1.1 Independent use
> > > +
> > > +When independent use the FMMT Python Tool, the following files and
> > > settings are required:
> > > +
> > > +- GuidTool executable files used for Decompress/Compress Firmware
> data.
> > > +
> > > +- Environment variables path with GuidTool path setting.
> > > +
> > > +### 2.1.2 Use with Build System
> > > +
> > > +When use the FMMT Python Tool with Build System:
> > > +
> > > +- If only use Edk2 based GuidTool, do not need other preparation.
> > > +
> > > +- If use other customized GuidTool, need prepare the config file with
> > GuidTool
> > > info. The syntax for GuidTool definition shown as follow:
> > > +
> > > + ***ToolsGuid ShortName Command***
> > > +
> > > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI
> > > BrotliCompress***
> > > +
> > > +## 2.2 Syntax
> > > +
> > > +### 2.2.1 Syntax for Parse file
> > > +
> > > +***-v < Inputfile > < Outputfile > -l < LogFileType >***
> > > +
> > > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile*
> > is
> > > optional, if inputs, the *Inputfile* will be encapsulated into
> > *Outputfile*
> > > following the parsed firmware layout. *"-l LogFileType"* is optional, it
> > decides
> > > the format of log file which saves Binary layout. Currently supports:
> > json, txt.
> > > More formats will be added in the future.
> > > +
> > > +### 2.2.2 Syntax for Add a new FFS
> > > +
> > > +***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > <
> > > Outputfile >***
> > > +
> > > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid*
> > > (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
> > > +
> > > +### 2.2.3 Syntax for Delete an FFS
> > > +
> > > +***-d < Inputfile > < TargetFfsName > < Outputfile > <
> > > TargetFvName/TargetFvGuid >***
> > > +
> > > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs
> > > which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is
> > the
> > > parent of TargetFfs*.*
> > > +
> > > +### 2.2.4 Syntax for Replace an FFS
> > > +
> > > +***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > <
> > > TargetFvName/TargetFvGuid >***
> > > +
> > > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the
> > TargetFfs
> > > which will be replaced. *TargetFvName/TargetFvGuid* is optional, which
> is
> > > the parent of TargetFfs*.*
> > > +
> > > +### 2.2.5 Syntax for Extract an FFS
> > > +
> > > +***-e < Inputfile > < TargetFfsName > < Outputfile >***
> > > +
> > > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the
> > TargetFfs
> > > which will be extracted.
> > > +
> > > +
> > > +
> > > +# 3. FMMT Python Tool Design
> > > +
> > > +FMMT Python Tool uses the NodeTree saves whole Firmware layout.
> Each
> > > Node have its Data field, which saves the
> > > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the
> > > parse/add/delete/replace/extract operations are based on the NodeTree
> > > (adjusting the layout and data).
> > > +
> > > +## 3.1 NodeTree
> > > +
> > > +A whole NodeTree saves all the Firmware info.
> > > +
> > > +- Parent & Child relationship figured out the Firmware layout.
> > > +
> > > +- Each Node have several fields. ?Data? field saves an FirmwareClass
> > > instance which contains all the data info of the info.
> > > +
> > > +### 3.1.1 NodeTree Format
> > > +
> > > +The NodeTree will be created with parse function. When parse a file, a
> > Root
> > > Node will be initialized firstly. The Data split and Tree construction
> > process is
> > > described with an FD file shown as ?Figure 2. The NodeTree format?:
> > > +
> > > +- A Root Node is initialized.
> > > +
> > > +- Use the ?FV Signature? as FV key to split Whole FD
> > > Data. ?FV0?, ?FV1?, ?FV2?? Node created.
> > > +
> > > +- After FV level Node created, use the ?Ffs Data Size? as FFS key to
> > split each
> > > FV Data. ?Ffs0?...Node created.
> > > +
> > > +- After FFS level Node created, use the ?Section Data Size? as Section
> > key to
> > > split each Ffs Data. ?Section0?...Node created.
> > > +
> > > +- If some of Section includes other Sections, continue use the ?Section
> > Data
> > > Size? as Section key to split each Section Data.
> > > +
> > > +- After all Node created, the whole NodeTree saves all the info. (Can be
> > used
> > > in other functions or print the whole firmware layout into log file)
> > > +
> > > +![](Img/NodeTreeFormat.png)
> > > +
> > > +<center>Figure 2. The NodeTree format</center>
> > > +
> > > +### 3.1.2 Node Factory and Product
> > > +
> > > +As 3.1.1, Each Node is created by data split and recognition. To extend
> > the
> > > NodeTree usage, Factory pattern is used in Node created process.
> > > +
> > > +Each Node have its Factory to create Product and use Product
> ParserData
> > > function to deal with the data.
> > > +
> > > +## 3.2 GuidTool
> > > +
> > > +There are two ways to set the GuidTool. One from Config file, another
> > from
> > > environment variables.
> > > +
> > > +Current GuidTool first check if has Config file.
> > > +
> > > +- If have, load the config GuidTool Information.
> > > +
> > > +- Else get from environment variables.
> > > +
> > > +### 3.2.1 Get from Config file
> > > +
> > > +- Config file should in same folder with FMMT.py or the path in
> > environment
> > > variables.
> > > +
> > > +- Content should follow the format:
> > > +
> > > + ***ToolsGuid ShortName Command***
> > > +
> > > +### 3.2.2 Get from Environment Variables
> > > +
> > > +- The GuidTool Command used must be set in environment variables.
> > > +
> > > +### 3.2.3 Edk2 Based GuidTool
> > > +
> > > +| ***Guid*** |
> ***ShortName***
> > > | ***Command*** |
> > > +| ------------------------------------------ | --------------- |
> > --------------------- |
> > > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO***
> |
> > > ***TianoCompress*** |
> > > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA***
> |
> > > ***LzmaCompress*** |
> > > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32***
> |
> > > ***GenCrc32*** |
> > > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86***
> |
> > > ***LzmaF86Compress*** |
> > > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI***
> |
> > > ***BrotliCompress*** |
> > > diff --git a/BaseTools/Source/Python/FMMT/__init__.py
> > > b/BaseTools/Source/Python/FMMT/__init__.py
> > > new file mode 100644
> > > index 000000000000..e69de29bb2d1
> > > diff --git
> a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > > new file mode 100644
> > > index 000000000000..33ffe73cab27
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > > @@ -0,0 +1,371 @@
> > > +## @file
> > > +# This file is used to implement of the various bianry parser.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from re import T
> > > +import copy
> > > +import os
> > > +from PI.Common import *
> > > +from core.BiosTreeNode import *
> > > +from core.BiosTree import *
> > > +from core.GuidTools import *
> > > +
> > > +ROOT_TREE = 'ROOT'
> > > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > > +
> > > +FV_TREE = 'FV'
> > > +DATA_FV_TREE = 'DATA_FV'
> > > +FFS_TREE = 'FFS'
> > > +FFS_PAD = 'FFS_PAD'
> > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > > +SECTION_TREE = 'SECTION'
> > > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > > +BINARY_DATA = 'BINARY'
> > > +Fv_count = 0
> > > +
> > > +## Abstract factory
> > > +class BinaryFactory():
> > > + type:list = []
> > > +
> > > + def Create_Product():
> > > + pass
> > > +
> > > +class BinaryProduct():
> > > + ## Use GuidTool to decompress data.
> > > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
> > > + ParPath =
> > >
> >
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
> > ")
> > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > > + guidtool =
> > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > > + DecompressedData = guidtool.unpack(Section_Data)
> > > + return DecompressedData
> > > +
> > > + def ParserData():
> > > + pass
> > > +
> > > +class SectionFactory(BinaryFactory):
> > > + type = [SECTION_TREE]
> > > +
> > > + def Create_Product():
> > > + return SectionProduct()
> > > +
> > > +class FfsFactory(BinaryFactory):
> > > + type = [ROOT_SECTION_TREE, FFS_TREE]
> > > +
> > > + def Create_Product():
> > > + return FfsProduct()
> > > +
> > > +class FvFactory(BinaryFactory):
> > > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
> > > +
> > > + def Create_Product():
> > > + return FvProduct()
> > > +
> > > +class FdFactory(BinaryFactory):
> > > + type = [ROOT_FV_TREE, ROOT_TREE]
> > > +
> > > + def Create_Product():
> > > + return FdProduct()
> > > +
> > > +class SectionProduct(BinaryProduct):
> > > + ## Decompress the compressed section.
> > > + def ParserData(self, Section_Tree, whole_Data: bytes,
> > > Rel_Whole_Offset: int=0) -> None:
> > > + if Section_Tree.Data.Type == 0x01:
> > > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > > + self.ParserFfs(Section_Tree, b'')
> > > + # Guided Define Section
> > > + elif Section_Tree.Data.Type == 0x02:
> > > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > > + DeCompressGuidTool =
> > > Section_Tree.Data.ExtHeader.SectionDefinitionGuid
> > > + Section_Tree.Data.Data =
> > > self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
> > > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) +
> > > Section_Tree.Data.HeaderLength
> > > + self.ParserFfs(Section_Tree, b'')
> > > + elif Section_Tree.Data.Type == 0x03:
> > > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > > + self.ParserFfs(Section_Tree, b'')
> > > + # SEC_FV Section
> > > + elif Section_Tree.Data.Type == 0x17:
> > > + global Fv_count
> > > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
> > > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
> > > + Sec_Fv_Tree.type = SEC_FV_TREE
> > > + Sec_Fv_Tree.Data = Sec_Fv_Info
> > > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
> > > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset +
> > > Sec_Fv_Tree.Data.Header.HeaderLength
> > > + Sec_Fv_Tree.Data.Data =
> > > Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
> > > + Section_Tree.insertChild(Sec_Fv_Tree)
> > > + Fv_count += 1
> > > +
> > > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > > int=0) -> None:
> > > + Rel_Offset = 0
> > > + Section_Offset = 0
> > > + # Get the Data from parent tree, if do not have the tree then
> get
> > it
> > > from the whole_data.
> > > + if ParTree.Data != None:
> > > + Data_Size = len(ParTree.Data.Data)
> > > + Section_Offset = ParTree.Data.DOffset
> > > + Whole_Data = ParTree.Data.Data
> > > + else:
> > > + Data_Size = len(Whole_Data)
> > > + # Parser all the data to collect all the Section recorded in its
> > Parent
> > > Section.
> > > + while Rel_Offset < Data_Size:
> > > + # Create a SectionNode and set it as the SectionTree's
> Data
> > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > > + Section_Tree = BIOSTREE(Section_Info.Name)
> > > + Section_Tree.type = SECTION_TREE
> > > + Section_Info.Data =
> > > Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> > > Rel_Offset+Section_Info.Size]
> > > + Section_Info.DOffset = Section_Offset +
> > > Section_Info.HeaderLength + Rel_Whole_Offset
> > > + Section_Info.HOffset = Section_Offset +
> Rel_Whole_Offset
> > > + Section_Info.ROffset = Rel_Offset
> > > + if Section_Info.Header.Type == 0:
> > > + break
> > > + # The final Section in parent Section does not need to add
> > > padding, else must be 4-bytes align with parent Section start offset
> > > + Pad_Size = 0
> > > + if
> > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> > Data_Size):
> > > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > > + Section_Info.PadData = Pad_Size * b'\x00'
> > > + if Section_Info.Header.Type == 0x02:
> > > + Section_Info.DOffset = Section_Offset +
> > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > > + Section_Info.Data =
> > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > > Rel_Offset+Section_Info.Size]
> > > + if Section_Info.Header.Type == 0x14:
> > > + ParTree.Data.Version =
> > > Section_Info.ExtHeader.GetVersionString()
> > > + if Section_Info.Header.Type == 0x15:
> > > + ParTree.Data.UiName =
> > > Section_Info.ExtHeader.GetUiString()
> > > + Section_Offset += Section_Info.Size + Pad_Size
> > > + Rel_Offset += Section_Info.Size + Pad_Size
> > > + Section_Tree.Data = Section_Info
> > > + ParTree.insertChild(Section_Tree)
> > > +
> > > +class FfsProduct(BinaryProduct):
> > > + # ParserFFs / GetSection
> > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > > int=0) -> None:
> > > + Rel_Offset = 0
> > > + Section_Offset = 0
> > > + # Get the Data from parent tree, if do not have the tree then
> get
> > it
> > > from the whole_data.
> > > + if ParTree.Data != None:
> > > + Data_Size = len(ParTree.Data.Data)
> > > + Section_Offset = ParTree.Data.DOffset
> > > + Whole_Data = ParTree.Data.Data
> > > + else:
> > > + Data_Size = len(Whole_Data)
> > > + # Parser all the data to collect all the Section recorded in Ffs.
> > > + while Rel_Offset < Data_Size:
> > > + # Create a SectionNode and set it as the SectionTree's
> Data
> > > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > > + Section_Tree = BIOSTREE(Section_Info.Name)
> > > + Section_Tree.type = SECTION_TREE
> > > + Section_Info.Data =
> > > Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> > > Rel_Offset+Section_Info.Size]
> > > + Section_Info.DOffset = Section_Offset +
> > > Section_Info.HeaderLength + Rel_Whole_Offset
> > > + Section_Info.HOffset = Section_Offset +
> Rel_Whole_Offset
> > > + Section_Info.ROffset = Rel_Offset
> > > + if Section_Info.Header.Type == 0:
> > > + break
> > > + # The final Section in Ffs does not need to add padding,
> else
> > > must be 4-bytes align with Ffs start offset
> > > + Pad_Size = 0
> > > + if
> > > (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> > Data_Size):
> > > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > > + Section_Info.PadData = Pad_Size * b'\x00'
> > > + if Section_Info.Header.Type == 0x02:
> > > + Section_Info.DOffset = Section_Offset +
> > > Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > > + Section_Info.Data =
> > > Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > > Rel_Offset+Section_Info.Size]
> > > + # If Section is Version or UI type, it saves the version and
> > UI
> > > info of its parent Ffs.
> > > + if Section_Info.Header.Type == 0x14:
> > > + ParTree.Data.Version =
> > > Section_Info.ExtHeader.GetVersionString()
> > > + if Section_Info.Header.Type == 0x15:
> > > + ParTree.Data.UiName =
> > > Section_Info.ExtHeader.GetUiString()
> > > + Section_Offset += Section_Info.Size + Pad_Size
> > > + Rel_Offset += Section_Info.Size + Pad_Size
> > > + Section_Tree.Data = Section_Info
> > > + ParTree.insertChild(Section_Tree)
> > > +
> > > +class FvProduct(BinaryProduct):
> > > + ## ParserFv / GetFfs
> > > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> > > int=0) -> None:
> > > + Ffs_Offset = 0
> > > + Rel_Offset = 0
> > > + # Get the Data from parent tree, if do not have the tree then
> get
> > it
> > > from the whole_data.
> > > + if ParTree.Data != None:
> > > + Data_Size = len(ParTree.Data.Data)
> > > + Ffs_Offset = ParTree.Data.DOffset
> > > + Whole_Data = ParTree.Data.Data
> > > + else:
> > > + Data_Size = len(Whole_Data)
> > > + # Parser all the data to collect all the Ffs recorded in Fv.
> > > + while Rel_Offset < Data_Size:
> > > + # Create a FfsNode and set it as the FFsTree's Data
> > > + if Data_Size - Rel_Offset < 24:
> > > + Ffs_Tree = BIOSTREE('Free_Space')
> > > + Ffs_Tree.type = FFS_FREE_SPACE
> > > + Ffs_Tree.Data =
> > > FreeSpaceNode(Whole_Data[Rel_Offset:])
> > > + Ffs_Tree.Data.HOffset = Ffs_Offset +
> Rel_Whole_Offset
> > > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
> > > + ParTree.Data.Free_Space = Data_Size - Rel_Offset
> > > + ParTree.insertChild(Ffs_Tree)
> > > + Rel_Offset = Data_Size
> > > + else:
> > > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
> > > + Ffs_Tree = BIOSTREE(Ffs_Info.Name)
> > > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
> > > + Ffs_Info.DOffset = Ffs_Offset +
> > > Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
> > > + Ffs_Info.ROffset = Rel_Offset
> > > + if Ffs_Info.Name == PADVECTOR:
> > > + Ffs_Tree.type = FFS_PAD
> > > + Ffs_Info.Data =
> > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> > > Rel_Offset+Ffs_Info.Size]
> > > + Ffs_Info.Size = len(Ffs_Info.Data) +
> > > Ffs_Info.Header.HeaderLength
> > > + # if current Ffs is the final ffs of Fv and full of
> > b'\xff',
> > > define it with Free_Space
> > > + if
> struct2stream(Ffs_Info.Header).replace(b'\xff',
> > b'')
> > > == b'':
> > > + Ffs_Tree.type = FFS_FREE_SPACE
> > > + Ffs_Info.Data = Whole_Data[Rel_Offset:]
> > > + Ffs_Info.Size = len(Ffs_Info.Data)
> > > + ParTree.Data.Free_Space = Ffs_Info.Size
> > > + else:
> > > + Ffs_Tree.type = FFS_TREE
> > > + Ffs_Info.Data =
> > > Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> > > Rel_Offset+Ffs_Info.Size]
> > > + # The final Ffs in Fv does not need to add padding,
> else
> > > must be 8-bytes align with Fv start offset
> > > + Pad_Size = 0
> > > + if Ffs_Tree.type != FFS_FREE_SPACE and
> > > (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) !=
> > Data_Size):
> > > + Pad_Size = GetPadSize(Ffs_Info.Size, 8)
> > > + Ffs_Info.PadData = Pad_Size * b'\xff'
> > > + Ffs_Offset += Ffs_Info.Size + Pad_Size
> > > + Rel_Offset += Ffs_Info.Size + Pad_Size
> > > + Ffs_Tree.Data = Ffs_Info
> > > + ParTree.insertChild(Ffs_Tree)
> > > +
> > > +class FdProduct(BinaryProduct):
> > > + type = [ROOT_FV_TREE, ROOT_TREE]
> > > +
> > > + ## Create DataTree with first level /fv Info, then parser each Fv.
> > > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset:
> > int=0) ->
> > > None:
> > > + # Get all Fv image in Fd with offset and length
> > > + Fd_Struct = self.GetFvFromFd(whole_data)
> > > + data_size = len(whole_data)
> > > + Binary_count = 0
> > > + global Fv_count
> > > + # If the first Fv image is the Binary Fv, add it into the tree.
> > > + if Fd_Struct[0][1] != 0:
> > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > > + Binary_node.type = BINARY_DATA
> > > + Binary_node.Data = BinaryNode(str(Binary_count))
> > > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
> > > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > > + Binary_node.Data.HOffset = 0 + offset
> > > + WholeFvTree.insertChild(Binary_node)
> > > + Binary_count += 1
> > > + # Add the first collected Fv image into the tree.
> > > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
> > > + Cur_node.type = Fd_Struct[0][0]
> > > + Cur_node.Data = FvNode(Fv_count,
> > > whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
> > > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
> > > + Cur_node.Data.DOffset =
> > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > > + Cur_node.Data.Data =
> > >
> >
> whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct
> > > [0][1]+Cur_node.Data.Size]
> > > + WholeFvTree.insertChild(Cur_node)
> > > + Fv_count += 1
> > > + Fv_num = len(Fd_Struct)
> > > + # Add all the collected Fv image and the Binary Fv image
> between
> > > them into the tree.
> > > + for i in range(Fv_num-1):
> > > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
> > > + Binary_node = BIOSTREE('BINARY'+
> str(Binary_count))
> > > + Binary_node.type = BINARY_DATA
> > > + Binary_node.Data = BinaryNode(str(Binary_count))
> > > + Binary_node.Data.Data =
> > > whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
> > > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > > + Binary_node.Data.HOffset =
> > > Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
> > > + WholeFvTree.insertChild(Binary_node)
> > > + Binary_count += 1
> > > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
> > > + Cur_node.type = Fd_Struct[i+1][0]
> > > + Cur_node.Data = FvNode(Fv_count,
> > > whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
> > > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
> > > + Cur_node.Data.DOffset =
> > > Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > > + Cur_node.Data.Data =
> > >
> >
> whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Stru
> > > ct[i+1][1]+Cur_node.Data.Size]
> > > + WholeFvTree.insertChild(Cur_node)
> > > + Fv_count += 1
> > > + # If the final Fv image is the Binary Fv, add it into the tree
> > > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
> > > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > > + Binary_node.type = BINARY_DATA
> > > + Binary_node.Data = BinaryNode(str(Binary_count))
> > > + Binary_node.Data.Data =
> > > whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
> > > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > > + Binary_node.Data.HOffset =
> > > Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
> > > + WholeFvTree.insertChild(Binary_node)
> > > + Binary_count += 1
> > > +
> > > + ## Get the first level Fv from Fd file.
> > > + def GetFvFromFd(self, whole_data: bytes=b'') -> list:
> > > + Fd_Struct = []
> > > + data_size = len(whole_data)
> > > + cur_index = 0
> > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV
> > > image offset and length.
> > > + while cur_index < data_size:
> > > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in
> > > whole_data[cur_index:]:
> > > + target_index =
> > >
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE)
> > +
> > > cur_index
> > > + if whole_data[target_index+24:target_index+28] ==
> > > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > > ZEROVECTOR_BYTE:
> > > + Fd_Struct.append([FV_TREE, target_index - 16,
> > > unpack("Q", whole_data[target_index+16:target_index+24])])
> > > + cur_index = Fd_Struct[-1][1] +
> Fd_Struct[-1][2][0]
> > > + else:
> > > + cur_index = target_index + 16
> > > + else:
> > > + cur_index = data_size
> > > + cur_index = 0
> > > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV
> > > image offset and length.
> > > + while cur_index < data_size:
> > > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in
> > > whole_data[cur_index:]:
> > > + target_index =
> > >
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE)
> > +
> > > cur_index
> > > + if whole_data[target_index+24:target_index+28] ==
> > > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > > ZEROVECTOR_BYTE:
> > > + Fd_Struct.append([FV_TREE, target_index - 16,
> > > unpack("Q", whole_data[target_index+16:target_index+24])])
> > > + cur_index = Fd_Struct[-1][1] +
> Fd_Struct[-1][2][0]
> > > + else:
> > > + cur_index = target_index + 16
> > > + else:
> > > + cur_index = data_size
> > > + cur_index = 0
> > > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image
> > > offset and length.
> > > + while cur_index < data_size:
> > > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in
> > > whole_data[cur_index:]:
> > > + target_index =
> > > whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) +
> > > cur_index
> > > + if whole_data[target_index+24:target_index+28] ==
> > > FVH_SIGNATURE and whole_data[target_index-16:target_index] ==
> > > ZEROVECTOR_BYTE:
> > > + Fd_Struct.append([DATA_FV_TREE,
> target_index -
> > > 16, unpack("Q", whole_data[target_index+16:target_index+24])])
> > > + cur_index = Fd_Struct[-1][1] +
> Fd_Struct[-1][2][0]
> > > + else:
> > > + cur_index = target_index + 16
> > > + else:
> > > + cur_index = data_size
> > > + # Sort all the collect Fv image with offset.
> > > + Fd_Struct.sort(key=lambda x:x[1])
> > > + tmp_struct = copy.deepcopy(Fd_Struct)
> > > + tmp_index = 0
> > > + Fv_num = len(Fd_Struct)
> > > + # Remove the Fv image included in another Fv image.
> > > + for i in range(1,Fv_num):
> > > + if tmp_struct[i][1]+tmp_struct[i][2][0] <
> > > tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
> > > + Fd_Struct.remove(Fd_Struct[i-tmp_index])
> > > + tmp_index += 1
> > > + return Fd_Struct
> > > +
> > > +class ParserEntry():
> > > + FactoryTable:dict = {
> > > + SECTION_TREE: SectionFactory,
> > > + ROOT_SECTION_TREE: FfsFactory,
> > > + FFS_TREE: FfsFactory,
> > > + ROOT_FFS_TREE: FvFactory,
> > > + FV_TREE: FvFactory,
> > > + SEC_FV_TREE: FvFactory,
> > > + ROOT_FV_TREE: FdFactory,
> > > + ROOT_TREE: FdFactory,
> > > + }
> > > +
> > > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
> > > + if Tree_type in self.FactoryTable:
> > > + return self.FactoryTable[Tree_type]
> > > +
> > > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data:
> > > bytes, Offset: int) -> None:
> > > + New_Product = TargetFactory.Create_Product()
> > > + New_Product.ParserData(Tree, Data, Offset)
> > > +
> > > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
> > > + TargetFactory = self.GetTargetFactory(Tree.type)
> > > + if TargetFactory:
> > > + self.Generate_Product(TargetFactory, Tree, Data, Offset)
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > > b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > > new file mode 100644
> > > index 000000000000..0b6252ecc1bb
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > > @@ -0,0 +1,198 @@
> > > +## @file
> > > +# This file is used to define the Bios layout tree structure and related
> > > operations.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +import collections
> > > +from PI.Common import *
> > > +
> > > +ROOT_TREE = 'ROOT'
> > > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > > +
> > > +FV_TREE = 'FV'
> > > +DATA_FV_TREE = 'DATA_FV'
> > > +FFS_TREE = 'FFS'
> > > +FFS_PAD = 'FFS_PAD'
> > > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > > +SECTION_TREE = 'SECTION'
> > > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > > +BINARY_DATA = 'BINARY'
> > > +
> > > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE,
> > > ROOT_SECTION_TREE]
> > > +FvType = [FV_TREE, SEC_FV_TREE]
> > > +FfsType = FFS_TREE
> > > +SecType = SECTION_TREE
> > > +
> > > +class BIOSTREE:
> > > + def __init__(self, NodeName: str) -> None:
> > > + self.key = NodeName
> > > + self.type = None
> > > + self.Data = None
> > > + self.Child = []
> > > + self.Findlist = []
> > > + self.Parent = None
> > > + self.NextRel = None
> > > + self.LastRel = None
> > > +
> > > + def HasChild(self) -> bool:
> > > + if self.Child == []:
> > > + return False
> > > + else:
> > > + return True
> > > +
> > > + def isFinalChild(self) -> bool:
> > > + ParTree = self.Parent
> > > + if ParTree:
> > > + if ParTree.Child[-1] == self:
> > > + return True
> > > + return False
> > > +
> > > + # FvTree.insertChild()
> > > + def insertChild(self, newNode, pos: int=None) -> None:
> > > + if len(self.Child) == 0:
> > > + self.Child.append(newNode)
> > > + else:
> > > + if not pos:
> > > + LastTree = self.Child[-1]
> > > + self.Child.append(newNode)
> > > + LastTree.NextRel = newNode
> > > + newNode.LastRel = LastTree
> > > + else:
> > > + newNode.NextRel = self.Child[pos-1].NextRel
> > > + newNode.LastRel = self.Child[pos].LastRel
> > > + self.Child[pos-1].NextRel = newNode
> > > + self.Child[pos].LastRel = newNode
> > > + self.Child.insert(pos, newNode)
> > > + newNode.Parent = self
> > > +
> > > + # lastNode.insertRel(newNode)
> > > + def insertRel(self, newNode) -> None:
> > > + if self.Parent:
> > > + parentTree = self.Parent
> > > + new_index = parentTree.Child.index(self) + 1
> > > + parentTree.Child.insert(new_index, newNode)
> > > + self.NextRel = newNode
> > > + newNode.LastRel = self
> > > +
> > > + def deleteNode(self, deletekey: str) -> None:
> > > + FindStatus, DeleteTree = self.FindNode(deletekey)
> > > + if FindStatus:
> > > + parentTree = DeleteTree.Parent
> > > + lastTree = DeleteTree.LastRel
> > > + nextTree = DeleteTree.NextRel
> > > + if parentTree:
> > > + index = parentTree.Child.index(DeleteTree)
> > > + del parentTree.Child[index]
> > > + if lastTree and nextTree:
> > > + lastTree.NextRel = nextTree
> > > + nextTree.LastRel = lastTree
> > > + elif lastTree:
> > > + lastTree.NextRel = None
> > > + elif nextTree:
> > > + nextTree.LastRel = None
> > > + return DeleteTree
> > > + else:
> > > + print('Could not find the target tree')
> > > + return None
> > > +
> > > + def FindNode(self, key: str, Findlist: list) -> None:
> > > + if self.key == key or (self.Data and self.Data.Name == key) or
> > > (self.type == FFS_TREE and self.Data.UiName == key):
> > > + Findlist.append(self)
> > > + else:
> > > + for item in self.Child:
> > > + item.FindNode(key, Findlist)
> > > +
> > > + def GetTreePath(self):
> > > + BiosTreePath = [self]
> > > + while self.Parent:
> > > + BiosTreePath.insert(0, self.Parent)
> > > + self = self.Parent
> > > + return BiosTreePath
> > > +
> > > + def parserTree(self, TargetDict: dict=None, Info: list=None, space:
> > int=0,
> > > ParFvId="") -> None:
> > > + Key = list(TargetDict.keys())[0]
> > > + if TargetDict[Key]["Type"] in RootType:
> > > + Info.append("Image File: {}".format(Key))
> > > + Info.append("FilesNum:
> > > {}".format(TargetDict.get(Key).get('FilesNum')))
> > > + Info.append("\n")
> > > + elif TargetDict[Key]["Type"] in FvType:
> > > + space += 2
> > > + if TargetDict[Key]["Type"] == SEC_FV_TREE:
> > > + Info.append("{}Child FV named {} of
> {}".format(space*" ",
> > > Key, ParFvId))
> > > + space += 2
> > > + else:
> > > + Info.append("FvId: {}".format(Key))
> > > + ParFvId = Key
> > > + Info.append("{}FvNameGuid: {}".format(space*" ",
> > > TargetDict.get(Key).get('FvNameGuid')))
> > > + Info.append("{}Attributes: {}".format(space*" ",
> > > TargetDict.get(Key).get('Attributes')))
> > > + Info.append("{}Total Volume Size: {}".format(space*" ",
> > > TargetDict.get(Key).get('Size')))
> > > + Info.append("{}Free Volume Size: {}".format(space*" ",
> > > TargetDict.get(Key).get('FreeSize')))
> > > + Info.append("{}Volume Offset: {}".format(space*" ",
> > > TargetDict.get(Key).get('Offset')))
> > > + Info.append("{}FilesNum: {}".format(space*" ",
> > > TargetDict.get(Key).get('FilesNum')))
> > > + elif TargetDict[Key]["Type"] in FfsType:
> > > + space += 2
> > > + if TargetDict.get(Key).get('UiName') != "b''":
> > > + Info.append("{}File: {} / {}".format(space*" ", Key,
> > > TargetDict.get(Key).get('UiName')))
> > > + else:
> > > + Info.append("{}File: {}".format(space*" ", Key))
> > > + if "Files" in list(TargetDict[Key].keys()):
> > > + for item in TargetDict[Key]["Files"]:
> > > + self.parserTree(item, Info, space, ParFvId)
> > > +
> > > + def ExportTree(self,TreeInfo: dict=None) -> dict:
> > > + if TreeInfo is None:
> > > + TreeInfo =collections.OrderedDict()
> > > +
> > > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or
> > > self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
> > > + key = str(self.key)
> > > + TreeInfo[self.key] = collections.OrderedDict()
> > > + TreeInfo[self.key]["Name"] = key
> > > + TreeInfo[self.key]["Type"] = self.type
> > > + TreeInfo[self.key]["FilesNum"] = len(self.Child)
> > > + elif self.type == FV_TREE or self.type == SEC_FV_TREE:
> > > + key = str(self.Data.FvId)
> > > + TreeInfo[key] = collections.OrderedDict()
> > > + TreeInfo[key]["Name"] = key
> > > + if self.Data.FvId != self.Data.Name:
> > > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
> > > + TreeInfo[key]["Type"] = self.type
> > > + TreeInfo[key]["Attributes"] =
> > hex(self.Data.Header.Attributes)
> > > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
> > > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
> > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > > + elif self.type == FFS_TREE:
> > > + key = str(self.Data.Name)
> > > + TreeInfo[key] = collections.OrderedDict()
> > > + TreeInfo[key]["Name"] = key
> > > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
> > > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
> > > + TreeInfo[key]["Type"] = self.type
> > > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > > + elif self.type == SECTION_TREE and self.Data.Type == 0x02:
> > > + key = str(self.Data.Name)
> > > + TreeInfo[key] = collections.OrderedDict()
> > > + TreeInfo[key]["Name"] = key
> > > + TreeInfo[key]["Type"] = self.type
> > > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) +
> > > self.Data.HeaderLength)
> > > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
> > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > > + elif self is not None:
> > > + key = str(self.Data.Name)
> > > + TreeInfo[key] = collections.OrderedDict()
> > > + TreeInfo[key]["Name"] = key
> > > + TreeInfo[key]["Type"] = self.type
> > > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > > +
> > > + for item in self.Child:
> > > + TreeInfo[key].setdefault('Files',[]).append(
> > item.ExportTree())
> > > +
> > > + return TreeInfo
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > > b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > > new file mode 100644
> > > index 000000000000..cfb711eea5a2
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > > @@ -0,0 +1,191 @@
> > > +## @file
> > > +# This file is used to define the BIOS Tree Node.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from PI.FvHeader import *
> > > +from PI.FfsFileHeader import *
> > > +from PI.SectionHeader import *
> > > +from PI.Common import *
> > > +import uuid
> > > +
> > > +SectionHeaderType = {
> > > + 0x01:'EFI_COMPRESSION_SECTION',
> > > + 0x02:'EFI_GUID_DEFINED_SECTION',
> > > + 0x03:'EFI_SECTION_DISPOSABLE',
> > > + 0x10:'EFI_SECTION_PE32',
> > > + 0x11:'EFI_SECTION_PIC',
> > > + 0x12:'EFI_SECTION_TE',
> > > + 0x13:'EFI_SECTION_DXE_DEPEX',
> > > + 0x14:'EFI_SECTION_VERSION',
> > > + 0x15:'EFI_SECTION_USER_INTERFACE',
> > > + 0x16:'EFI_SECTION_COMPATIBILITY16',
> > > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
> > > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
> > > + 0x19:'EFI_SECTION_RAW',
> > > + 0x1B:'EFI_SECTION_PEI_DEPEX',
> > > + 0x1C:'EFI_SECTION_MM_DEPEX'
> > > +}
> > > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
> > > +
> > > +class BinaryNode:
> > > + def __init__(self, name: str) -> None:
> > > + self.Size = 0
> > > + self.Name = "BINARY" + str(name)
> > > + self.HOffset = 0
> > > + self.Data = b''
> > > +
> > > +class FvNode:
> > > + def __init__(self, name, buffer: bytes) -> None:
> > > + self.Header =
> > > EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
> > > + Map_num = (self.Header.HeaderLength - 56)//8
> > > + self.Header =
> > > Refine_FV_Header(Map_num).from_buffer_copy(buffer)
> > > + self.FvId = "FV" + str(name)
> > > + self.Name = "FV" + str(name)
> > > + if self.Header.ExtHeaderOffset:
> > > + self.ExtHeader =
> > >
> >
> EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Heade
> > r
> > > .ExtHeaderOffset:])
> > > + self.Name =
> > > uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
> > > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
> > > + if self.ExtHeader.ExtHeaderSize != 20:
> > > + self.ExtEntryExist = 1
> > > + self.ExtEntry =
> > >
> >
> EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntry
> > > Offset:])
> > > + self.ExtTypeExist = 1
> > > + if self.ExtEntry.ExtEntryType == 0x01:
> > > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16
> > > + self.ExtEntry =
> > >
> >
> Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[
> > s
> > > elf.ExtEntryOffset:])
> > > + elif self.ExtEntry.ExtEntryType == 0x02:
> > > + nums = self.ExtEntry.ExtEntrySize - 20
> > > + self.ExtEntry =
> > >
> >
> Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer
> > [
> > > self.ExtEntryOffset:])
> > > + elif self.ExtEntry.ExtEntryType == 0x03:
> > > + self.ExtEntry =
> > >
> >
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(b
> > > uffer[self.ExtEntryOffset:])
> > > + else:
> > > + self.ExtTypeExist = 0
> > > + else:
> > > + self.ExtEntryExist = 0
> > > + self.Size = self.Header.FvLength
> > > + self.HeaderLength = self.Header.HeaderLength
> > > + self.HOffset = 0
> > > + self.DOffset = 0
> > > + self.ROffset = 0
> > > + self.Data = b''
> > > + if self.Header.Signature != 1213613663:
> > > + print('Invalid! Fv Header Signature {} is not
> > > "_FVH".'.format(self.Header.Signature))
> > > + with open(str(self.Name)+'.fd', "wb") as f:
> > > + f.write(struct2stream(self.Header))
> > > + assert False
> > > + self.PadData = b''
> > > + self.Free_Space = 0
> > > + self.ModCheckSum()
> > > +
> > > + def ModCheckSum(self) -> None:
> > > + # Fv Header Sums to 0.
> > > + Header = struct2stream(self.Header)[::-1]
> > > + Size = self.HeaderLength // 2
> > > + Sum = 0
> > > + for i in range(Size):
> > > + Sum += int(Header[i*2: i*2 + 2].hex(), 16)
> > > + if Sum & 0xffff:
> > > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum -
> > > self.Header.Checksum)[-4:], 16)), 16)
> > > +
> > > + def ModFvExt(self) -> None:
> > > + # If used space changes and self.ExtEntry.UsedSize exists,
> > > self.ExtEntry.UsedSize need to be changed.
> > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and
> > > self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03:
> > > + self.ExtEntry.UsedSize = self.Header.FvLength -
> > > self.Free_Space
> > > +
> > > + def ModFvSize(self) -> None:
> > > + # If Fv Size changed, self.Header.FvLength and
> > > self.Header.BlockMap[i].NumBlocks need to be changed.
> > > + BlockMapNum = len(self.Header.BlockMap)
> > > + for i in range(BlockMapNum):
> > > + if self.Header.BlockMap[i].Length:
> > > + self.Header.BlockMap[i].NumBlocks =
> > > self.Header.FvLength // self.Header.BlockMap[i].Length
> > > +
> > > + def ModExtHeaderData(self) -> None:
> > > + if self.Header.ExtHeaderOffset:
> > > + ExtHeaderData = struct2stream(self.ExtHeader)
> > > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset -
> > > self.HeaderLength
> > > + self.Data = self.Data[:ExtHeaderDataOffset] +
> ExtHeaderData
> > > + self.Data[ExtHeaderDataOffset+20:]
> > > + if self.Header.ExtHeaderOffset and self.ExtEntryExist:
> > > + ExtHeaderEntryData = struct2stream(self.ExtEntry)
> > > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset
> +
> > > 20 - self.HeaderLength
> > > + self.Data = self.Data[:ExtHeaderEntryDataOffset] +
> > > ExtHeaderEntryData +
> > > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
> > > +
> > > +class FfsNode:
> > > + def __init__(self, buffer: bytes) -> None:
> > > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
> > > + # self.Attributes = unpack("<B", buffer[21:22])[0]
> > > + if self.Header.FFS_FILE_SIZE != 0 and self.Header.Attributes !=
> > 0xff
> > > and self.Header.Attributes & 0x01 == 1:
> > > + print('Error Ffs Header! Ffs Header Size and Attributes is
> > not
> > > matched!')
> > > + if self.Header.FFS_FILE_SIZE == 0 and self.Header.Attributes &
> > > 0x01 == 1:
> > > + self.Header =
> > > EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
> > > + self.Name =
> > > uuid.UUID(bytes_le=struct2stream(self.Header.Name))
> > > + self.UiName = b''
> > > + self.Version = b''
> > > + self.Size = self.Header.FFS_FILE_SIZE
> > > + self.HeaderLength = self.Header.HeaderLength
> > > + self.HOffset = 0
> > > + self.DOffset = 0
> > > + self.ROffset = 0
> > > + self.Data = b''
> > > + self.PadData = b''
> > > +
> > > + def ModCheckSum(self) -> None:
> > > + HeaderData = struct2stream(self.Header)
> > > + HeaderSum = 0
> > > + for item in HeaderData:
> > > + HeaderSum += item
> > > + HeaderSum -= self.Header.State
> > > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File
> > > + if HeaderSum & 0xff:
> > > + Header = self.Header.IntegrityCheck.Checksum.Header +
> > > 0x100 - int(hex(HeaderSum)[-2:], 16)
> > > + self.Header.IntegrityCheck.Checksum.Header =
> > > int(hex(Header)[-2:], 16)
> > > +
> > > +class SectionNode:
> > > + def __init__(self, buffer: bytes) -> None:
> > > + if buffer[0:3] != b'\xff\xff\xff':
> > > + self.Header =
> > > EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
> > > + else:
> > > + self.Header =
> > > EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
> > > + if self.Header.Type in SectionHeaderType:
> > > + self.Name = SectionHeaderType[self.Header.Type]
> > > + elif self.Header.Type == 0:
> > > + self.Name = "EFI_SECTION_RAW"
> > > + else:
> > > + self.Name = "SECTION"
> > > + if self.Header.Type in HeaderType:
> > > + self.ExtHeader = self.GetExtHeader(self.Header.Type,
> > > buffer[self.Header.Common_Header_Size():],
> > > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
> > > + self.HeaderLength = self.Header.Common_Header_Size()
> +
> > > self.ExtHeader.ExtHeaderSize()
> > > + else:
> > > + self.ExtHeader = None
> > > + self.HeaderLength = self.Header.Common_Header_Size()
> > > + self.Size = self.Header.SECTION_SIZE
> > > + self.Type = self.Header.Type
> > > + self.HOffset = 0
> > > + self.DOffset = 0
> > > + self.ROffset = 0
> > > + self.Data = b''
> > > + self.OriData = b''
> > > + self.OriHeader = b''
> > > + self.PadData = b''
> > > +
> > > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) ->
> > None:
> > > + if Type == 0x01:
> > > + return
> > > EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
> > > + elif Type == 0x02:
> > > + return
> > > EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
> > > + elif Type == 0x14:
> > > + return Get_VERSION_Header((nums -
> > > 2)//2).from_buffer_copy(buffer)
> > > + elif Type == 0x15:
> > > + return
> > > Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
> > > + elif Type == 0x18:
> > > + return
> > > EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
> > > +
> > > +class FreeSpaceNode:
> > > + def __init__(self, buffer: bytes) -> None:
> > > + self.Name = 'Free_Space'
> > > + self.Data = buffer
> > > + self.Size = len(buffer)
> > > + self.HOffset = 0
> > > + self.DOffset = 0
> > > + self.ROffset = 0
> > > + self.PadData = b''
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > > b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > > new file mode 100644
> > > index 000000000000..a0432c4093cf
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > > @@ -0,0 +1,140 @@
> > > +## @file
> > > +# This file is used to define the functions to operate bios binary file.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from core.FMMTParser import *
> > > +from core.FvHandler import *
> > > +from utils.FvLayoutPrint import *
> > > +
> > > +global Fv_count
> > > +Fv_count = 0
> > > +
> > > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE',
> > 'ROOT_FFS_TREE',
> > > 'ROOT_SECTION_TREE'
> > > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None,
> > outputfile:
> > > str=None) -> None:
> > > + # 1. Data Prepare
> > > + with open(inputfile, "rb") as f:
> > > + whole_data = f.read()
> > > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
> > > + # 2. DataTree Create
> > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree,
> whole_data)
> > > + # 3. Log Output
> > > + InfoDict = FmmtParser.WholeFvTree.ExportTree()
> > > + FmmtParser.WholeFvTree.parserTree(InfoDict,
> FmmtParser.BinaryInfo)
> > > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
> > > + if logfile:
> > > + GetFormatter(logfile.lower()).dump(InfoDict,
> > >
> >
> FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile
> > ),
> > > ".{}".format(logfile.lower())))
> > > + # 4. Data Encapsultion
> > > + if outputfile:
> > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > > + with open(outputfile, "wb") as f:
> > > + f.write(FmmtParser.FinalData)
> > > +
> > > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str,
> > Fv_name:
> > > str=None) -> None:
> > > + # 1. Data Prepare
> > > + with open(inputfile, "rb") as f:
> > > + whole_data = f.read()
> > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > > + # 2. DataTree Create
> > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree,
> whole_data)
> > > + # 3. Data Modify
> > > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name,
> > > FmmtParser.WholeFvTree.Findlist)
> > > + # Choose the Specfic DeleteFfs with Fv info
> > > + if Fv_name:
> > > + for item in FmmtParser.WholeFvTree.Findlist:
> > > + if item.Parent.key != Fv_name and
> > > item.Parent.Data.Name != Fv_name:
> > > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > > + if FmmtParser.WholeFvTree.Findlist != []:
> > > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
> > > + FfsMod = FvHandler(None, Delete_Ffs)
> > > + Status = FfsMod.DeleteFfs()
> > > + else:
> > > + print('Target Ffs not found!!!')
> > > + # 4. Data Encapsultion
> > > + if Status:
> > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > > + with open(outputfile, "wb") as f:
> > > + f.write(FmmtParser.FinalData)
> > > +
> > > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile:
> > str) ->
> > > None:
> > > + # 1. Data Prepare
> > > + with open(inputfile, "rb") as f:
> > > + whole_data = f.read()
> > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > > + # 2. DataTree Create
> > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree,
> whole_data)
> > > + # Get Target Fv and Target Ffs_Pad
> > > + FmmtParser.WholeFvTree.FindNode(Fv_name,
> > > FmmtParser.WholeFvTree.Findlist)
> > > + # Create new ffs Tree
> > > + with open(newffsfile, "rb") as f:
> > > + new_ffs_data = f.read()
> > > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
> > > + Status = False
> > > + # 3. Data Modify
> > > + if FmmtParser.WholeFvTree.Findlist:
> > > + for TargetFv in FmmtParser.WholeFvTree.Findlist:
> > > + TargetFfsPad = TargetFv.Child[-1]
> > > + if TargetFfsPad.type == FFS_FREE_SPACE:
> > > +
> > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> > > new_ffs_data, TargetFfsPad.Data.HOffset)
> > > + else:
> > > +
> > > NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> > > new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
> > > + FfsMod =
> FvHandler(NewFmmtParser.WholeFvTree.Child[0],
> > > TargetFfsPad)
> > > + Status = FfsMod.AddFfs()
> > > + else:
> > > + print('Target Fv not found!!!')
> > > + # 4. Data Encapsultion
> > > + if Status:
> > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > > + with open(outputfile, "wb") as f:
> > > + f.write(FmmtParser.FinalData)
> > > +
> > > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str,
> > outputfile: str,
> > > Fv_name: str=None) -> None:
> > > + # 1. Data Prepare
> > > + with open(inputfile, "rb") as f:
> > > + whole_data = f.read()
> > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > > + # 2. DataTree Create
> > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree,
> whole_data)
> > > + with open(newffsfile, "rb") as f:
> > > + new_ffs_data = f.read()
> > > + newFmmtParser = FMMTParser(newffsfile, FV_TREE)
> > > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree,
> > > new_ffs_data)
> > > + Status = False
> > > + # 3. Data Modify
> > > + new_ffs = newFmmtParser.WholeFvTree.Child[0]
> > > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
> > > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> > > FmmtParser.WholeFvTree.Findlist)
> > > + if Fv_name:
> > > + for item in FmmtParser.WholeFvTree.Findlist:
> > > + if item.Parent.key != Fv_name and
> > > item.Parent.Data.Name != Fv_name:
> > > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > > + if FmmtParser.WholeFvTree.Findlist != []:
> > > + for TargetFfs in FmmtParser.WholeFvTree.Findlist:
> > > + FfsMod =
> FvHandler(newFmmtParser.WholeFvTree.Child[0],
> > > TargetFfs)
> > > + Status = FfsMod.ReplaceFfs()
> > > + else:
> > > + print('Target Ffs not found!!!')
> > > + # 4. Data Encapsultion
> > > + if Status:
> > > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > > + with open(outputfile, "wb") as f:
> > > + f.write(FmmtParser.FinalData)
> > > +
> > > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
> > > + with open(inputfile, "rb") as f:
> > > + whole_data = f.read()
> > > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree,
> whole_data)
> > > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> > > FmmtParser.WholeFvTree.Findlist)
> > > + if FmmtParser.WholeFvTree.Findlist != []:
> > > + TargetNode = FmmtParser.WholeFvTree.Findlist[0]
> > > + TargetFv = TargetNode.Parent
> > > + if TargetFv.Data.Header.Attributes &
> EFI_FVB2_ERASE_POLARITY:
> > > + TargetNode.Data.Header.State = c_uint8(
> > > + ~TargetNode.Data.Header.State)
> > > + FinalData = struct2stream(TargetNode.Data.Header) +
> > > TargetNode.Data.Data
> > > + with open(outputfile, "wb") as f:
> > > + f.write(FinalData)
> > > + else:
> > > + print('Target Ffs not found!!!')
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > > b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > > new file mode 100644
> > > index 000000000000..6e54b860a9c9
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > > @@ -0,0 +1,86 @@
> > > +## @file
> > > +# This file is used to define the interface of Bios Parser.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +from PI.Common import *
> > > +from core.BinaryFactoryProduct import ParserEntry
> > > +from core.BiosTreeNode import *
> > > +from core.BiosTree import *
> > > +from core.GuidTools import *
> > > +
> > > +class FMMTParser:
> > > + def __init__(self, name: str, TYPE: str) -> None:
> > > + self.WholeFvTree = BIOSTREE(name)
> > > + self.WholeFvTree.type = TYPE
> > > + self.FinalData = b''
> > > + self.BinaryInfo = []
> > > +
> > > + ## Parser the nodes in WholeTree.
> > > + def ParserFromRoot(self, WholeFvTree=None, whole_data:
> bytes=b'',
> > > Reloffset: int=0) -> None:
> > > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type ==
> > > ROOT_FV_TREE:
> > > + ParserEntry().DataParser(self.WholeFvTree, whole_data,
> > > Reloffset)
> > > + else:
> > > + ParserEntry().DataParser(WholeFvTree, whole_data,
> > > Reloffset)
> > > + for Child in WholeFvTree.Child:
> > > + self.ParserFromRoot(Child, "")
> > > +
> > > + ## Encapuslation all the data in tree into self.FinalData
> > > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
> > > + # If current node is Root node, skip it.
> > > + if rootTree.type == ROOT_TREE or rootTree.type ==
> > > ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type ==
> > > ROOT_SECTION_TREE:
> > > + print('Start at Root !')
> > > + # If current node do not have Header, just add Data.
> > > + elif rootTree.type == BINARY_DATA or rootTree.type ==
> > > FFS_FREE_SPACE:
> > > + self.FinalData += rootTree.Data.Data
> > > + rootTree.Child = []
> > > + # If current node do not have Child and ExtHeader, just add its
> > > Header and Data.
> > > + elif rootTree.type == DATA_FV_TREE or rootTree.type ==
> FFS_PAD:
> > > + self.FinalData += struct2stream(rootTree.Data.Header) +
> > > rootTree.Data.Data + rootTree.Data.PadData
> > > + if rootTree.isFinalChild():
> > > + ParTree = rootTree.Parent
> > > + if ParTree.type != 'ROOT':
> > > + self.FinalData += ParTree.Data.PadData
> > > + rootTree.Child = []
> > > + # If current node is not Section node and may have Child and
> > > ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data.
> > > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or
> > > rootTree.type == SEC_FV_TREE:
> > > + if rootTree.HasChild():
> > > + self.FinalData +=
> struct2stream(rootTree.Data.Header)
> > > + else:
> > > + self.FinalData +=
> struct2stream(rootTree.Data.Header) +
> > > rootTree.Data.Data + rootTree.Data.PadData
> > > + if rootTree.isFinalChild():
> > > + ParTree = rootTree.Parent
> > > + if ParTree.type != 'ROOT':
> > > + self.FinalData += ParTree.Data.PadData
> > > + # If current node is Section, need to consider its ExtHeader,
> > Child
> > > and Compressed Status.
> > > + elif rootTree.type == SECTION_TREE:
> > > + # Not compressed section
> > > + if rootTree.Data.OriData == b'' or
> (rootTree.Data.OriData !=
> > > b'' and CompressStatus):
> > > + if rootTree.HasChild():
> > > + if rootTree.Data.ExtHeader:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header) +
> > > struct2stream(rootTree.Data.ExtHeader)
> > > + else:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header)
> > > + else:
> > > + Data = rootTree.Data.Data
> > > + if rootTree.Data.ExtHeader:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header) +
> > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> > > + else:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> > > + if rootTree.isFinalChild():
> > > + ParTree = rootTree.Parent
> > > + self.FinalData += ParTree.Data.PadData
> > > + # If compressed section
> > > + else:
> > > + Data = rootTree.Data.OriData
> > > + rootTree.Child = []
> > > + if rootTree.Data.ExtHeader:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header) +
> > > struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
> > > + else:
> > > + self.FinalData +=
> > > struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> > > + if rootTree.isFinalChild():
> > > + ParTree = rootTree.Parent
> > > + self.FinalData += ParTree.Data.PadData
> > > + for Child in rootTree.Child:
> > > + self.Encapsulation(Child, CompressStatus)
> > > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > > b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > > new file mode 100644
> > > index 000000000000..f73f1fd65c07
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > > @@ -0,0 +1,521 @@
> > > +## @file
> > > +# This file is used to the implementation of Bios layout handler.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +import os
> > > +from core.BiosTree import *
> > > +from core.GuidTools import GUIDTools
> > > +from core.BiosTreeNode import *
> > > +from PI.Common import *
> > > +
> > > +EFI_FVB2_ERASE_POLARITY = 0x00000800
> > > +
> > > +def ChangeSize(TargetTree, size_delta: int=0) -> None:
> > > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2())
> or
> > > type(TargetTree.Data.Header) ==
> > type(EFI_COMMON_SECTION_HEADER2()):
> > > + TargetTree.Data.Size -= size_delta
> > > + TargetTree.Data.Header.ExtendedSize -= size_delta
> > > + elif TargetTree.type == SECTION_TREE and
> TargetTree.Data.OriData:
> > > + OriSize = TargetTree.Data.Header.SECTION_SIZE
> > > + OriSize -= size_delta
> > > + TargetTree.Data.Header.Size[0] = OriSize % (16**2)
> > > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
> > > + TargetTree.Data.Header.Size[2] = OriSize // (16**4)
> > > + else:
> > > + TargetTree.Data.Size -= size_delta
> > > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size %
> (16**2)
> > > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size %
> (16**4)
> > > //(16**2)
> > > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size //
> (16**4)
> > > +
> > > +def ModifyFfsType(TargetFfs) -> None:
> > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and
> > > TargetFfs.Data.Size > 0xFFFFFF:
> > > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
> > > + New_Header = EFI_FFS_FILE_HEADER2()
> > > + New_Header.Name = TargetFfs.Data.Header.Name
> > > + New_Header.IntegrityCheck =
> > > TargetFfs.Data.Header.IntegrityCheck
> > > + New_Header.Type = TargetFfs.Data.Header.Type
> > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > > + New_Header.Size = 0
> > > + New_Header.State = TargetFfs.Data.Header.State
> > > + New_Header.ExtendedSize = ExtendSize
> > > + TargetFfs.Data.Header = New_Header
> > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > > + TargetFfs.Data.HeaderLength =
> > > TargetFfs.Data.Header.HeaderLength
> > > + TargetFfs.Data.ModCheckSum()
> > > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2())
> and
> > > TargetFfs.Data.Size <= 0xFFFFFF:
> > > + New_Header = EFI_FFS_FILE_HEADER()
> > > + New_Header.Name = TargetFfs.Data.Header.Name
> > > + New_Header.IntegrityCheck =
> > > TargetFfs.Data.Header.IntegrityCheck
> > > + New_Header.Type = TargetFfs.Data.Header.Type
> > > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > > + New_Header.Size = TargetFfs.Data.HeaderLength +
> > > TargetFfs.Data.Size
> > > + New_Header.State = TargetFfs.Data.Header.State
> > > + TargetFfs.Data.Header = New_Header
> > > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > > + TargetFfs.Data.HeaderLength =
> > > TargetFfs.Data.Header.HeaderLength
> > > + TargetFfs.Data.ModCheckSum()
> > > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid)
> ==
> > > EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
> > > + NeedChange = True
> > > + for item in TargetFfs.Parent.Child:
> > > + if type(item.Data.Header) ==
> > > type(EFI_FFS_FILE_HEADER2()):
> > > + NeedChange = False
> > > + if NeedChange:
> > > + TargetFfs.Parent.Data.Header.FileSystemGuid =
> > > ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> > > +
> > > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> > > + TarParent = TargetFfs.Parent
> > > + while TarParent:
> > > + if TarParent.type == FV_TREE and
> > > struct2stream(TarParent.Data.Header.FileSystemGuid) ==
> > > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
> > > + TarParent.Data.Header.FileSystemGuid =
> > > ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> > > + TarParent = TarParent.Parent
> > > +
> > > +class FvHandler:
> > > + def __init__(self, NewFfs, TargetFfs) -> None:
> > > + self.NewFfs = NewFfs
> > > + self.TargetFfs = TargetFfs
> > > + self.Status = False
> > > + self.Remain_New_Free_Space = 0
> > > +
> > > + ## Use for Compress the Section Data
> > > + def CompressData(self, TargetTree) -> None:
> > > + TreePath = TargetTree.GetTreePath()
> > > + pos = len(TreePath)
> > > + self.Status = True
> > > + while pos:
> > > + if self.Status:
> > > + if TreePath[pos-1].type == SECTION_TREE and
> > > TreePath[pos-1].Data.Type == 0x02:
> > > + self.CompressSectionData(TreePath[pos-1],
> None,
> > > TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
> > > + else:
> > > + if pos == len(TreePath):
> > > +
> self.CompressSectionData(TreePath[pos-1],
> > > pos)
> > > + else:
> > > +
> self.CompressSectionData(TreePath[pos-1],
> > > None)
> > > + pos -= 1
> > > +
> > > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None)
> ->
> > > None:
> > > + NewData = b''
> > > + temp_save_child = TargetTree.Child
> > > + if TargetTree.Data:
> > > + for item in temp_save_child:
> > > + if item.type == SECTION_TREE and not
> > > item.Data.OriData and item.Data.ExtHeader:
> > > + NewData += struct2stream(item.Data.Header)
> +
> > > struct2stream(item.Data.ExtHeader) + item.Data.Data +
> item.Data.PadData
> > > + elif item.type == SECTION_TREE and
> item.Data.OriData
> > > and not item.Data.ExtHeader:
> > > + NewData += struct2stream(item.Data.Header)
> +
> > > item.Data.OriData + item.Data.PadData
> > > + elif item.type == SECTION_TREE and
> item.Data.OriData
> > > and item.Data.ExtHeader:
> > > + NewData += struct2stream(item.Data.Header)
> +
> > > struct2stream(item.Data.ExtHeader) + item.Data.OriData +
> > > item.Data.PadData
> > > + elif item.type == FFS_FREE_SPACE:
> > > + NewData += item.Data.Data +
> item.Data.PadData
> > > + else:
> > > + NewData += struct2stream(item.Data.Header)
> +
> > > item.Data.Data + item.Data.PadData
> > > + if TargetTree.type == FFS_TREE:
> > > + New_Pad_Size = GetPadSize(len(NewData), 8)
> > > + Size_delta = len(NewData) -
> len(TargetTree.Data.Data)
> > > + ChangeSize(TargetTree, -Size_delta)
> > > + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> > > New_Pad_Size
> > > + self.Remain_New_Free_Space += Delta_Pad_Size
> > > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size
> > > + TargetTree.Data.ModCheckSum()
> > > + elif TargetTree.type == FV_TREE or TargetTree.type ==
> > > SEC_FV_TREE and not pos:
> > > + if self.Remain_New_Free_Space:
> > > + if TargetTree.Data.Free_Space:
> > > + TargetTree.Data.Free_Space +=
> > > self.Remain_New_Free_Space
> > > + NewData +=
> self.Remain_New_Free_Space *
> > > b'\xff'
> > > + TargetTree.Child[-1].Data.Data +=
> > > self.Remain_New_Free_Space * b'\xff'
> > > + else:
> > > + TargetTree.Data.Data +=
> > > self.Remain_New_Free_Space * b'\xff'
> > > + New_Free_Space =
> BIOSTREE('FREE_SPACE')
> > > + New_Free_Space.type = FFS_FREE_SPACE
> > > + New_Free_Space.Data =
> > > FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
> > > + TargetTree.insertChild(New_Free_Space)
> > > + self.Remain_New_Free_Space = 0
> > > + if TargetTree.type == SEC_FV_TREE:
> > > + Size_delta = len(NewData) +
> > > self.Remain_New_Free_Space - len(TargetTree.Data.Data)
> > > + TargetTree.Data.Header.FvLength += Size_delta
> > > + TargetTree.Data.ModFvExt()
> > > + TargetTree.Data.ModFvSize()
> > > + TargetTree.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetTree)
> > > + TargetTree.Data.ModCheckSum()
> > > + elif TargetTree.type == SECTION_TREE and
> > > TargetTree.Data.Type != 0x02:
> > > + New_Pad_Size = GetPadSize(len(NewData), 4)
> > > + Size_delta = len(NewData) -
> len(TargetTree.Data.Data)
> > > + ChangeSize(TargetTree, -Size_delta)
> > > + if TargetTree.NextRel:
> > > + Delta_Pad_Size = len(TargetTree.Data.PadData)
> -
> > > New_Pad_Size
> > > + self.Remain_New_Free_Space +=
> Delta_Pad_Size
> > > + TargetTree.Data.PadData = b'\x00' *
> > > New_Pad_Size
> > > + TargetTree.Data.Data = NewData
> > > + if GuidTool:
> > > + ParPath =
> > >
> >
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..
> > ")
> > > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > > + guidtool =
> > > GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > > + CompressedData = guidtool.pack(TargetTree.Data.Data)
> > > + if len(CompressedData) < len(TargetTree.Data.OriData):
> > > + New_Pad_Size = GetPadSize(len(CompressedData),
> 4)
> > > + Size_delta = len(CompressedData) -
> > > len(TargetTree.Data.OriData)
> > > + ChangeSize(TargetTree, -Size_delta)
> > > + if TargetTree.NextRel:
> > > + TargetTree.Data.PadData = b'\x00' *
> > > New_Pad_Size
> > > + self.Remain_New_Free_Space =
> > > len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) -
> > > len(CompressedData) - New_Pad_Size
> > > + else:
> > > + TargetTree.Data.PadData = b''
> > > + self.Remain_New_Free_Space =
> > > len(TargetTree.Data.OriData) - len(CompressedData)
> > > + TargetTree.Data.OriData = CompressedData
> > > + elif len(CompressedData) ==
> len(TargetTree.Data.OriData):
> > > + TargetTree.Data.OriData = CompressedData
> > > + elif len(CompressedData) > len(TargetTree.Data.OriData):
> > > + New_Pad_Size = GetPadSize(CompressedData, 4)
> > > + self.Remain_New_Free_Space =
> len(CompressedData) +
> > > New_Pad_Size - len(TargetTree.Data.OriData) -
> > len(TargetTree.Data.PadData)
> > > + Size_delta = len(TargetTree.Data.OriData) -
> > > len(CompressedData)
> > > + ChangeSize(TargetTree, -Size_delta)
> > > + if TargetTree.NextRel:
> > > + TargetTree.Data.PadData = b'\x00' *
> > > New_Pad_Size
> > > + TargetTree.Data.OriData = CompressedData
> > > + self.ModifyTest(TargetTree,
> > > self.Remain_New_Free_Space)
> > > + self.Status = False
> > > +
> > > + def ModifyFvExtData(self, TreeNode) -> None:
> > > + FvExtData = b''
> > > + if TreeNode.Data.Header.ExtHeaderOffset:
> > > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
> > > + FvExtData += FvExtHeader
> > > + if TreeNode.Data.Header.ExtHeaderOffset and
> > > TreeNode.Data.ExtEntryExist:
> > > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
> > > + FvExtData += FvExtEntry
> > > + if FvExtData:
> > > + InfoNode = TreeNode.Child[0]
> > > + InfoNode.Data.Data = FvExtData +
> > > InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
> > > + InfoNode.Data.ModCheckSum()
> > > +
> > > + def ModifyTest(self, ParTree, Needed_Space: int) -> None:
> > > + if Needed_Space > 0:
> > > + if ParTree.type == FV_TREE or ParTree.type ==
> SEC_FV_TREE:
> > > + ParTree.Data.Data = b''
> > > + Needed_Space = Needed_Space -
> > > ParTree.Data.Free_Space
> > > + if Needed_Space < 0:
> > > + ParTree.Child[-1].Data.Data = b'\xff' *
> > > (-Needed_Space)
> > > + ParTree.Data.Free_Space = (-Needed_Space)
> > > + self.Status = True
> > > + else:
> > > + if ParTree.type == FV_TREE:
> > > + self.Status = False
> > > + else:
> > > + BlockSize =
> > > ParTree.Data.Header.BlockMap[0].Length
> > > + New_Add_Len = BlockSize -
> > > Needed_Space%BlockSize
> > > + if New_Add_Len % BlockSize:
> > > + ParTree.Child[-1].Data.Data = b'\xff' *
> > > New_Add_Len
> > > + ParTree.Data.Free_Space =
> > > New_Add_Len
> > > + Needed_Space += New_Add_Len
> > > + else:
> > > +
> ParTree.Child.remove(ParTree.Child[-1])
> > > + ParTree.Data.Free_Space = 0
> > > + ParTree.Data.Size += Needed_Space
> > > + ParTree.Data.Header.Fvlength =
> > > ParTree.Data.Size
> > > + for item in ParTree.Child:
> > > + if item.type == FFS_FREE_SPACE:
> > > + ParTree.Data.Data += item.Data.Data +
> > > item.Data.PadData
> > > + else:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > > + ParTree.Data.ModFvExt()
> > > + ParTree.Data.ModFvSize()
> > > + ParTree.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(ParTree)
> > > + ParTree.Data.ModCheckSum()
> > > + elif ParTree.type == FFS_TREE:
> > > + ParTree.Data.Data = b''
> > > + for item in ParTree.Child:
> > > + if item.Data.OriData:
> > > + if item.Data.ExtHeader:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader)
> +
> > > item.Data.OriData + item.Data.PadData
> > > + else:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.OriData +
> item.Data.PadData
> > > + else:
> > > + if item.Data.ExtHeader:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader)
> +
> > > item.Data.Data + item.Data.PadData
> > > + else:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > > + ChangeSize(ParTree, -Needed_Space)
> > > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
> > > + Delta_Pad_Size = New_Pad_Size -
> > > len(ParTree.Data.PadData)
> > > + Needed_Space += Delta_Pad_Size
> > > + ParTree.Data.PadData = b'\xff' *
> > > GetPadSize(ParTree.Data.Size, 8)
> > > + ParTree.Data.ModCheckSum()
> > > + elif ParTree.type == SECTION_TREE:
> > > + OriData = ParTree.Data.Data
> > > + ParTree.Data.Data = b''
> > > + for item in ParTree.Child:
> > > + if item.type == SECTION_TREE and
> > > item.Data.ExtHeader and item.Data.Type != 0x02:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader)
> +
> > > item.Data.Data + item.Data.PadData
> > > + elif item.type == SECTION_TREE and
> > > item.Data.ExtHeader and item.Data.Type == 0x02:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader)
> +
> > > item.Data.OriData + item.Data.PadData
> > > + else:
> > > + ParTree.Data.Data +=
> > > struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
> > > + if ParTree.Data.Type == 0x02:
> > > + ParTree.Data.Size += Needed_Space
> > > + ParPath =
> > > os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
> > > + ToolPath =
> os.path.join(os.path.dirname(ParPath),
> > > r'FMMTConfig.ini')
> > > + guidtool =
> > >
> >
> GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.Se
> > c
> > > tionDefinitionGuid))
> > > + CompressedData =
> > > guidtool.pack(ParTree.Data.Data)
> > > + Needed_Space = len(CompressedData) -
> > > len(ParTree.Data.OriData)
> > > + ParTree.Data.OriData = CompressedData
> > > + New_Size = ParTree.Data.HeaderLength +
> > > len(CompressedData)
> > > + ParTree.Data.Header.Size[0] = New_Size %
> (16**2)
> > > + ParTree.Data.Header.Size[1] = New_Size %
> (16**4)
> > > //(16**2)
> > > + ParTree.Data.Header.Size[2] = New_Size //
> (16**4)
> > > + if ParTree.NextRel:
> > > + New_Pad_Size = GetPadSize(New_Size, 4)
> > > + Delta_Pad_Size = New_Pad_Size -
> > > len(ParTree.Data.PadData)
> > > + ParTree.Data.PadData = b'\x00' *
> > > New_Pad_Size
> > > + Needed_Space += Delta_Pad_Size
> > > + else:
> > > + ParTree.Data.PadData = b''
> > > + elif Needed_Space:
> > > + ChangeSize(ParTree, -Needed_Space)
> > > + New_Pad_Size = GetPadSize(ParTree.Data.Size,
> 4)
> > > + Delta_Pad_Size = New_Pad_Size -
> > > len(ParTree.Data.PadData)
> > > + Needed_Space += Delta_Pad_Size
> > > + ParTree.Data.PadData = b'\x00' *
> New_Pad_Size
> > > + NewParTree = ParTree.Parent
> > > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE,
> > > ROOT_SECTION_TREE, ROOT_TREE]
> > > + if NewParTree and NewParTree.type not in ROOT_TYPE:
> > > + self.ModifyTest(NewParTree, Needed_Space)
> > > + else:
> > > + self.Status = True
> > > +
> > > + def ReplaceFfs(self) -> bool:
> > > + TargetFv = self.TargetFfs.Parent
> > > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY,
> Child
> > > Ffs Header State need be reversed.
> > > + if TargetFv.Data.Header.Attributes &
> EFI_FVB2_ERASE_POLARITY:
> > > + self.NewFfs.Data.Header.State = c_uint8(
> > > + ~self.NewFfs.Data.Header.State)
> > > + # NewFfs parsing will not calculate the PadSize, thus
> > recalculate.
> > > + self.NewFfs.Data.PadData = b'\xff' *
> > > GetPadSize(self.NewFfs.Data.Size, 8)
> > > + if self.NewFfs.Data.Size >= self.TargetFfs.Data.Size:
> > > + Needed_Space = self.NewFfs.Data.Size +
> > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> > > len(self.TargetFfs.Data.PadData)
> > > + # If TargetFv have enough free space, just move part of
> the
> > > free space to NewFfs.
> > > + if TargetFv.Data.Free_Space >= Needed_Space:
> > > + # Modify TargetFv Child info and BiosTree.
> > > + TargetFv.Child[-1].Data.Data = b'\xff' *
> > > (TargetFv.Data.Free_Space - Needed_Space)
> > > + TargetFv.Data.Free_Space -= Needed_Space
> > > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.insertChild(self.NewFfs, Target_index)
> > > + # Modify TargetFv Header and ExtHeader info.
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModFvSize()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + # return the Status
> > > + self.Status = True
> > > + # If TargetFv do not have enough free space, need move
> part
> > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > > + else:
> > > + if TargetFv.type == FV_TREE:
> > > + self.Status = False
> > > + else:
> > > + # Recalculate TargetFv needed space to keep it
> > > match the BlockSize setting.
> > > + Needed_Space -= TargetFv.Data.Free_Space
> > > + BlockSize =
> > > TargetFv.Data.Header.BlockMap[0].Length
> > > + New_Add_Len = BlockSize -
> > > Needed_Space%BlockSize
> > > + Target_index =
> TargetFv.Child.index(self.TargetFfs)
> > > + if New_Add_Len % BlockSize:
> > > + TargetFv.Child[-1].Data.Data = b'\xff' *
> > > New_Add_Len
> > > + TargetFv.Data.Free_Space =
> New_Add_Len
> > > + Needed_Space += New_Add_Len
> > > + TargetFv.insertChild(self.NewFfs,
> Target_index)
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + else:
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.Data.Free_Space = 0
> > > + TargetFv.insertChild(self.NewFfs)
> > > + # Encapsulate the Fv Data for update.
> > > + TargetFv.Data.Data = b''
> > > + for item in TargetFv.Child:
> > > + if item.type == FFS_FREE_SPACE:
> > > + TargetFv.Data.Data +=
> item.Data.Data +
> > > item.Data.PadData
> > > + else:
> > > + TargetFv.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > > + TargetFv.Data.Size += Needed_Space
> > > + # Modify TargetFv Data Header and ExtHeader
> info.
> > > + TargetFv.Data.Header.FvLength =
> > > TargetFv.Data.Size
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModFvSize()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + # Start free space calculating and moving
> process.
> > > + self.ModifyTest(TargetFv.Parent,
> Needed_Space)
> > > + else:
> > > + New_Free_Space = self.TargetFfs.Data.Size -
> > > self.NewFfs.Data.Size
> > > + # If TargetFv already have free space, move the new free
> > > space into it.
> > > + if TargetFv.Data.Free_Space:
> > > + TargetFv.Child[-1].Data.Data += b'\xff' *
> > > New_Free_Space
> > > + TargetFv.Data.Free_Space += New_Free_Space
> > > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.insertChild(self.NewFfs, Target_index)
> > > + self.Status = True
> > > + # If TargetFv do not have free space, create free space for
> > Fv.
> > > + else:
> > > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
> > > + New_Free_Space_Tree.type = FFS_FREE_SPACE
> > > + New_Free_Space_Tree.Data = FfsNode(b'\xff' *
> > > New_Free_Space)
> > > + TargetFv.Data.Free_Space = New_Free_Space
> > > + TargetFv.insertChild(New_Free_Space)
> > > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.insertChild(self.NewFfs, Target_index)
> > > + self.Status = True
> > > + # Modify TargetFv Header and ExtHeader info.
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModFvSize()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + return self.Status
> > > +
> > > + def AddFfs(self) -> bool:
> > > + # NewFfs parsing will not calculate the PadSize, thus
> > recalculate.
> > > + self.NewFfs.Data.PadData = b'\xff' *
> > > GetPadSize(self.NewFfs.Data.Size, 8)
> > > + if self.TargetFfs.type == FFS_FREE_SPACE:
> > > + TargetLen = self.NewFfs.Data.Size +
> > > len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> > > len(self.TargetFfs.Data.PadData)
> > > + TargetFv = self.TargetFfs.Parent
> > > + # If the Fv Header Attributes is
> EFI_FVB2_ERASE_POLARITY,
> > > Child Ffs Header State need be reversed.
> > > + if TargetFv.Data.Header.Attributes &
> > > EFI_FVB2_ERASE_POLARITY:
> > > + self.NewFfs.Data.Header.State = c_uint8(
> > > + ~self.NewFfs.Data.Header.State)
> > > + # If TargetFv have enough free space, just move part of
> the
> > > free space to NewFfs, split free space to NewFfs and new free space.
> > > + if TargetLen < 0:
> > > + self.Status = True
> > > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
> > > + TargetFv.Data.Free_Space = (-TargetLen)
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + TargetFv.insertChild(self.NewFfs, -1)
> > > + ModifyFfsType(self.NewFfs)
> > > + elif TargetLen == 0:
> > > + self.Status = True
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.insertChild(self.NewFfs)
> > > + ModifyFfsType(self.NewFfs)
> > > + # If TargetFv do not have enough free space, need move
> part
> > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > > + else:
> > > + if TargetFv.type == FV_TREE:
> > > + self.Status = False
> > > + elif TargetFv.type == SEC_FV_TREE:
> > > + # Recalculate TargetFv needed space to keep it
> > > match the BlockSize setting.
> > > + BlockSize =
> > > TargetFv.Data.Header.BlockMap[0].Length
> > > + New_Add_Len = BlockSize -
> TargetLen%BlockSize
> > > + if New_Add_Len % BlockSize:
> > > + self.TargetFfs.Data.Data = b'\xff' *
> > > New_Add_Len
> > > + self.TargetFfs.Data.Size = New_Add_Len
> > > + TargetLen += New_Add_Len
> > > + TargetFv.insertChild(self.NewFfs, -1)
> > > + TargetFv.Data.Free_Space =
> New_Add_Len
> > > + else:
> > > + TargetFv.Child.remove(self.TargetFfs)
> > > + TargetFv.insertChild(self.NewFfs)
> > > + TargetFv.Data.Free_Space = 0
> > > + ModifyFfsType(self.NewFfs)
> > > + TargetFv.Data.Data = b''
> > > + for item in TargetFv.Child:
> > > + if item.type == FFS_FREE_SPACE:
> > > + TargetFv.Data.Data +=
> item.Data.Data +
> > > item.Data.PadData
> > > + else:
> > > + TargetFv.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > > + # Encapsulate the Fv Data for update.
> > > + TargetFv.Data.Size += TargetLen
> > > + TargetFv.Data.Header.FvLength =
> > > TargetFv.Data.Size
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModFvSize()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + # Start free space calculating and moving
> process.
> > > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > > + else:
> > > + # If TargetFv do not have free space, need directly move
> part
> > > of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
> > > + TargetLen = self.NewFfs.Data.Size +
> > > len(self.NewFfs.Data.PadData)
> > > + TargetFv = self.TargetFfs.Parent
> > > + if TargetFv.Data.Header.Attributes &
> > > EFI_FVB2_ERASE_POLARITY:
> > > + self.NewFfs.Data.Header.State = c_uint8(
> > > + ~self.NewFfs.Data.Header.State)
> > > + if TargetFv.type == FV_TREE:
> > > + self.Status = False
> > > + elif TargetFv.type == SEC_FV_TREE:
> > > + BlockSize =
> TargetFv.Data.Header.BlockMap[0].Length
> > > + New_Add_Len = BlockSize - TargetLen%BlockSize
> > > + if New_Add_Len % BlockSize:
> > > + New_Free_Space = BIOSTREE('FREE_SPACE')
> > > + New_Free_Space.type = FFS_FREE_SPACE
> > > + New_Free_Space.Data = FreeSpaceNode(b'\xff'
> *
> > > New_Add_Len)
> > > + TargetLen += New_Add_Len
> > > + TargetFv.Data.Free_Space = New_Add_Len
> > > + TargetFv.insertChild(self.NewFfs)
> > > + TargetFv.insertChild(New_Free_Space)
> > > + else:
> > > + TargetFv.insertChild(self.NewFfs)
> > > + ModifyFfsType(self.NewFfs)
> > > + TargetFv.Data.Data = b''
> > > + for item in TargetFv.Child:
> > > + if item.type == FFS_FREE_SPACE:
> > > + TargetFv.Data.Data += item.Data.Data +
> > > item.Data.PadData
> > > + else:
> > > + TargetFv.Data.Data +=
> > > struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> > > + TargetFv.Data.Size += TargetLen
> > > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> > > + TargetFv.Data.ModFvExt()
> > > + TargetFv.Data.ModFvSize()
> > > + TargetFv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(TargetFv)
> > > + TargetFv.Data.ModCheckSum()
> > > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > > + return self.Status
> > > +
> > > + def DeleteFfs(self) -> bool:
> > > + Delete_Ffs = self.TargetFfs
> > > + Delete_Fv = Delete_Ffs.Parent
> > > + Add_Free_Space = Delete_Ffs.Data.Size +
> > > len(Delete_Ffs.Data.PadData)
> > > + if Delete_Fv.Data.Free_Space:
> > > + if Delete_Fv.type == SEC_FV_TREE:
> > > + Used_Size = Delete_Fv.Data.Size -
> > > Delete_Fv.Data.Free_Space - Add_Free_Space
> > > + BlockSize =
> Delete_Fv.Data.Header.BlockMap[0].Length
> > > + New_Free_Space = BlockSize - Used_Size %
> BlockSize
> > > + self.Remain_New_Free_Space +=
> > > Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
> > > + Delete_Fv.Child[-1].Data.Data = New_Free_Space *
> > > b'\xff'
> > > + Delete_Fv.Data.Free_Space = New_Free_Space
> > > + else:
> > > + Used_Size = Delete_Fv.Data.Size -
> > > Delete_Fv.Data.Free_Space - Add_Free_Space
> > > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space *
> > > b'\xff'
> > > + Delete_Fv.Data.Free_Space += Add_Free_Space
> > > + New_Free_Space = Delete_Fv.Data.Free_Space +
> > > Add_Free_Space
> > > + else:
> > > + if Delete_Fv.type == SEC_FV_TREE:
> > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > > + BlockSize =
> Delete_Fv.Data.Header.BlockMap[0].Length
> > > + New_Free_Space = BlockSize - Used_Size %
> BlockSize
> > > + self.Remain_New_Free_Space += Add_Free_Space -
> > > New_Free_Space
> > > + Add_Free_Space = New_Free_Space
> > > + else:
> > > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > > + New_Free_Space = Add_Free_Space
> > > + New_Free_Space_Info = FfsNode(Add_Free_Space *
> b'\xff')
> > > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
> > > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
> > > + New_Ffs_Tree.type = FFS_FREE_SPACE
> > > + New_Ffs_Tree.Data = New_Free_Space_Info
> > > + Delete_Fv.insertChild(New_Ffs_Tree)
> > > + Delete_Fv.Data.Free_Space = Add_Free_Space
> > > + Delete_Fv.Child.remove(Delete_Ffs)
> > > + Delete_Fv.Data.Header.FvLength = Used_Size +
> New_Free_Space
> > > + Delete_Fv.Data.ModFvExt()
> > > + Delete_Fv.Data.ModFvSize()
> > > + Delete_Fv.Data.ModExtHeaderData()
> > > + self.ModifyFvExtData(Delete_Fv)
> > > + Delete_Fv.Data.ModCheckSum()
> > > + self.CompressData(Delete_Fv)
> > > + self.Status = True
> > > + return self.Status
> > > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > > b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > > new file mode 100644
> > > index 000000000000..e21d8e0406ae
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > > @@ -0,0 +1,152 @@
> > > +## @file
> > > +# This file is used to define the FMMT dependent external tool
> > management
> > > class.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +import glob
> > > +import logging
> > > +import os
> > > +import shutil
> > > +import sys
> > > +import tempfile
> > > +import uuid
> > > +from PI.Common import *
> > > +from utils.FmmtLogger import FmmtLogger as logger
> > > +import subprocess
> > > +
> > > +def ExecuteCommand(cmd: list) -> None:
> > > + subprocess.run(cmd,stdout=subprocess.DEVNULL)
> > > +
> > > +class GUIDTool:
> > > + def __init__(self, guid: str, short_name: str, command: str) -> None:
> > > + self.guid: str = guid
> > > + self.short_name: str = short_name
> > > + self.command: str = command
> > > +
> > > + def pack(self, buffer: bytes) -> bytes:
> > > + """
> > > + compress file.
> > > + """
> > > + tool = self.command
> > > + if tool:
> > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > > + ToolInputFile = os.path.join(tmp,
> > > "pack_uncompress_sec_file")
> > > + ToolOuputFile = os.path.join(tmp, "pack_sec_file")
> > > + try:
> > > + file = open(ToolInputFile, "wb")
> > > + file.write(buffer)
> > > + file.close()
> > > + command = [tool, '-e', '-o', ToolOuputFile,
> > > + ToolInputFile]
> > > + ExecuteCommand(command)
> > > + buf = open(ToolOuputFile, "rb")
> > > + res_buffer = buf.read()
> > > + except Exception as msg:
> > > + logger.error(msg)
> > > + return ""
> > > + else:
> > > + buf.close()
> > > + if os.path.exists(tmp):
> > > + shutil.rmtree(tmp)
> > > + return res_buffer
> > > + else:
> > > + logger.error(
> > > + "Error parsing section: EFI_SECTION_GUID_DEFINED
> > > cannot be parsed at this time.")
> > > + logger.info("Its GUID is: %s" % self.guid)
> > > + return ""
> > > +
> > > +
> > > + def unpack(self, buffer: bytes) -> bytes:
> > > + """
> > > + buffer: remove common header
> > > + uncompress file
> > > + """
> > > + tool = self.command
> > > + if tool:
> > > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > > + ToolInputFile = os.path.join(tmp, "unpack_sec_file")
> > > + ToolOuputFile = os.path.join(tmp,
> > > "unpack_uncompress_sec_file")
> > > + try:
> > > + file = open(ToolInputFile, "wb")
> > > + file.write(buffer)
> > > + file.close()
> > > + command = [tool, '-d', '-o', ToolOuputFile,
> > ToolInputFile]
> > > + ExecuteCommand(command)
> > > + buf = open(ToolOuputFile, "rb")
> > > + res_buffer = buf.read()
> > > + except Exception as msg:
> > > + logger.error(msg)
> > > + return ""
> > > + else:
> > > + buf.close()
> > > + if os.path.exists(tmp):
> > > + shutil.rmtree(tmp)
> > > + return res_buffer
> > > + else:
> > > + logger.error("Error parsing section:
> > > EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
> > > + logger.info("Its GUID is: %s" % self.guid)
> > > + return ""
> > > +
> > > +class GUIDTools:
> > > + '''
> > > + GUIDTools is responsible for reading FMMTConfig.ini, verify the
> tools
> > > and provide interfaces to access those tools.
> > > + '''
> > > + default_tools = {
> > > +
> > > struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-
> > 127f4c984779
> > > ")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO",
> > > "TianoCompress"),
> > > +
> > > struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-
> > dc7bd79403cf
> > > ")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA",
> > > "LzmaCompress"),
> > > +
> > > struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-
> > a4600d9dd083
> > > ")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32",
> > > "GenCrc32"),
> > > +
> > > struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-
> > ca72a6eae889
> > > ")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86",
> > > "LzmaF86Compress"),
> > > +
> > > struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-
> > 0f7f630d5afb")
> > > ): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI",
> > > "BrotliCompress"),
> > > + }
> > > +
> > > + def __init__(self, tooldef_file: str=None) -> None:
> > > + self.dir = os.path.dirname(__file__)
> > > + self.tooldef_file = tooldef_file if tooldef_file else
> > os.path.join(
> > > + self.dir, "FMMTConfig.ini")
> > > + self.tooldef = dict()
> > > + self.load()
> > > +
> > > + def VerifyTools(self) -> None:
> > > + """
> > > + Verify Tools and Update Tools path.
> > > + """
> > > + path_env = os.environ.get("PATH")
> > > + path_env_list = path_env.split(os.pathsep)
> > > + path_env_list.append(os.path.dirname(__file__))
> > > + path_env_list = list(set(path_env_list))
> > > + for tool in self.tooldef.values():
> > > + cmd = tool.command
> > > + if os.path.isabs(cmd):
> > > + if not os.path.exists(cmd):
> > > + print("Tool Not found %s" % cmd)
> > > + else:
> > > + for syspath in path_env_list:
> > > + if glob.glob(os.path.join(syspath, cmd+"*")):
> > > + break
> > > + else:
> > > + print("Tool Not found %s" % cmd)
> > > +
> > > + def load(self) -> None:
> > > + if os.path.exists(self.tooldef_file):
> > > + with open(self.tooldef_file, "r") as fd:
> > > + config_data = fd.readlines()
> > > + for line in config_data:
> > > + try:
> > > + guid, short_name, command = line.split()
> > > + new_format_guid =
> > > struct2stream(ModifyGuidFormat(guid.strip()))
> > > + self.tooldef[new_format_guid] = GUIDTool(
> > > + guid.strip(), short_name.strip(),
> > > command.strip())
> > > + except:
> > > + print("GuidTool load error!")
> > > + continue
> > > + else:
> > > + self.tooldef.update(self.default_tools)
> > > +
> > > + self.VerifyTools()
> > > +
> > > + def __getitem__(self, guid) -> None:
> > > + return self.tooldef.get(guid)
> > > +
> > > +
> > > +guidtools = GUIDTools()
> > > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > > b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > > new file mode 100644
> > > index 000000000000..18f0cff96e4b
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > > @@ -0,0 +1,18 @@
> > > +## @file
> > > +# This file is used to define the Fmmt Logger.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +##
> > > +
> > > +import logging
> > > +import sys
> > > +
> > > +FmmtLogger = logging.getLogger('FMMT')
> > > +FmmtLogger.setLevel(logging.INFO)
> > > +
> > > +lh=logging.StreamHandler(sys.stdout)
> > > +lf=logging.Formatter("%(levelname)-8s: %(message)s")
> > > +lh.setFormatter(lf)
> > > +FmmtLogger.addHandler(lh)
> > > \ No newline at end of file
> > > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > > b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > > new file mode 100644
> > > index 000000000000..1a6c67056266
> > > --- /dev/null
> > > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > > @@ -0,0 +1,54 @@
> > > +## @file
> > > +# This file is used to define the printer for Bios layout.
> > > +#
> > > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +##
> > > +
> > > +def GetFormatter(layout_format: str):
> > > + if layout_format == 'json':
> > > + return JsonFormatter()
> > > + elif layout_format == 'yaml':
> > > + return YamlFormatter()
> > > + elif layout_format == 'html':
> > > + return HtmlFormatter()
> > > + else:
> > > + return TxtFormatter()
> > > +
> > > +class Formatter(object):
> > > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
> > > + raise NotImplemented
> > > +
> > > +class JsonFormatter(Formatter):
> > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
> > str=None) ->
> > > None:
> > > + try:
> > > + import json
> > > + except:
> > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > > + return
> > > + print(outputfile)
> > > + if outputfile:
> > > + with open(outputfile,"w") as fw:
> > > + json.dump(layoutdict, fw, indent=2)
> > > + else:
> > > + print(json.dumps(layoutdict,indent=2))
> > > +
> > > +class TxtFormatter(Formatter):
> > > + def LogPrint(self,layoutlist: list) -> None:
> > > + for item in layoutlist:
> > > + print(item)
> > > + print('\n')
> > > +
> > > + def dump(self,layoutdict: dict, layoutlist: list, outputfile:
> > str=None) ->
> > > None:
> > > + print(outputfile)
> > > + with open(outputfile, "w") as f:
> > > + for item in layoutlist:
> > > + f.writelines(item + '\n')
> > > +
> > > +class YamlFormatter(Formatter):
> > > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > > +
> > > +class HtmlFormatter(Formatter):
> > > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > > \ No newline at end of file
> > > --
> > > 2.27.0.windows.1
> > >
> > >
> > >
> > >
> > >
> >
> >
> >
> >
> >
> >
> >
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/1] BaseTools: Add FMMT Tool
@ 2021-11-09 0:09 Yuwei Chen
2021-11-09 0:29 ` [edk2-devel] " Michael D Kinney
0 siblings, 1 reply; 6+ messages in thread
From: Yuwei Chen @ 2021-11-09 0:09 UTC (permalink / raw)
To: devel; +Cc: Bob Feng, Liming Gao
From: Bob Feng <bob.c.feng@intel.com>
The FMMT python tool is used for firmware files operation, which has
the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function.
Currently the FMMT C tool is saved in edk2-staging repo, but its
quality and coding style can't meet the Edk2 quality, which is hard to
maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
The new Python version keeps same functions with origin C version. It
has higher quality and better coding style, and it is much easier to
extend new functions and to maintain.
RFC: https://edk2.groups.io/g/devel/message/82877
Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
---
BaseTools/BinWrappers/PosixLike/FMMT | 14 +
BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
BaseTools/Source/Python/FMMT/FMMTConfig.ini | 5 +
.../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
.../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes
BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
| 66 +++
| 112 ++++
| 110 ++++
BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
BaseTools/Source/Python/FMMT/README.md | 180 ++++++
BaseTools/Source/Python/FMMT/__init__.py | 0
.../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
BaseTools/Source/Python/FMMT/core/BiosTree.py | 199 +++++++
.../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
.../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
.../Source/Python/FMMT/core/FMMTParser.py | 86 +++
.../Source/Python/FMMT/core/FvHandler.py | 521 ++++++++++++++++++
.../Source/Python/FMMT/core/GuidTools.py | 152 +++++
.../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
.../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
22 files changed, 2427 insertions(+)
create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
create mode 100644 BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
create mode 100644 BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py
create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
create mode 100644 BaseTools/Source/Python/FMMT/README.md
create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTOperation.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py
create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
create mode 100644 BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
diff --git a/BaseTools/BinWrappers/PosixLike/FMMT b/BaseTools/BinWrappers/PosixLike/FMMT
new file mode 100644
index 000000000000..5f5519e1e1b6
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/FMMT
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#python `dirname $0`/RunToolFromSource.py `basename $0` $*
+
+# If a ${PYTHON_COMMAND} command is available, use it in preference to python
+if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
+ python_exe=${PYTHON_COMMAND}
+fi
+
+full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
+dir=$(dirname "$full_cmd")
+cmd=${full_cmd##*/}
+
+export PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
+exec "${python_exe:-python}" -m $cmd.$cmd "$@"
diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
new file mode 100644
index 000000000000..259d6cd6ddea
--- /dev/null
+++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
@@ -0,0 +1,4 @@
+@setlocal
+@set ToolName=%~n0%
+@set PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BASE_TOOLS_PATH%\Source\Python\FMMT
+@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
diff --git a/BaseTools/Source/Python/FMMT/FMMT.py b/BaseTools/Source/Python/FMMT/FMMT.py
new file mode 100644
index 000000000000..1c41face7308
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/FMMT.py
@@ -0,0 +1,117 @@
+# @file
+# Firmware Module Management Tool.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+# Import Modules
+#
+import argparse
+import sys
+from core.FMMTOperation import *
+
+parser = argparse.ArgumentParser(description='''
+View the Binary Structure of FD/FV/Ffs/Section, and Delete/Extract/Add/Replace a Ffs from/into a FV.
+''')
+parser.add_argument("--version", action="version", version='%(prog)s Version 1.0',
+ help="Print debug information.")
+parser.add_argument("-v", "--View", dest="View", nargs='+',
+ help="View each FV and the named files within each FV: '-v inputfile outputfile, inputfiletype(.Fd/.Fv/.ffs/.sec)'")
+parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
+ help="Delete a Ffs from FV: '-d inputfile TargetFfsName outputfile TargetFvName(Optional,\
+ If not given, wil delete all the existed target Ffs)'")
+parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
+ help="Extract a Ffs Info: '-e inputfile TargetFfsName outputfile'")
+parser.add_argument("-a", "--Add", dest="Add", nargs='+',
+ help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'")
+parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
+ help="Replace a Ffs in a FV: '-r inputfile TargetFfsName newffsfile outputfile TargetFvName(Optional,\
+ If not given, wil replace all the existed target Ffs with new Ffs file)'")
+parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
+ help="The format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future")
+
+def print_banner():
+ print("")
+
+class FMMT():
+ def __init__(self) -> None:
+ self.firmware_packet = {}
+
+ def CheckFfsName(self, FfsName:str) -> str:
+ try:
+ return uuid.UUID(FfsName)
+ except:
+ return FfsName
+
+ def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None) -> None:
+ # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
+ filetype = os.path.splitext(inputfile)[1].lower()
+ if filetype == '.fd':
+ ROOT_TYPE = ROOT_TREE
+ elif filetype == '.fv':
+ ROOT_TYPE = ROOT_FV_TREE
+ elif filetype == '.ffs':
+ ROOT_TYPE = ROOT_FFS_TREE
+ elif filetype == '.sec':
+ ROOT_TYPE = ROOT_SECTION_TREE
+ else:
+ ROOT_TYPE = ROOT_TREE
+ ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
+
+ def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
+ if Fv_name:
+ DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile, uuid.UUID(Fv_name))
+ else:
+ DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile)
+
+ def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None:
+ ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
+
+ def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
+ AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, outputfile)
+
+ def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
+ if Fv_name:
+ ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile, uuid.UUID(Fv_name))
+ else:
+ ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)
+
+
+def main():
+ args=parser.parse_args()
+ status=0
+
+ try:
+ fmmt=FMMT()
+ if args.View:
+ if args.LogFileType:
+ fmmt.View(args.View[0], args.LogFileType[0])
+ else:
+ fmmt.View(args.View[0])
+ if args.Delete:
+ if len(args.Delete) == 4:
+ fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
+ else:
+ fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
+ if args.Extract:
+ fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
+ if args.Add:
+ fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
+ if args.Replace:
+ if len(args.Replace) == 5:
+ fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3],args.Replace[4])
+ else:
+ fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])
+ # TODO:
+ '''Do the main work'''
+ except Exception as e:
+ print(e)
+
+ return status
+
+
+if __name__ == "__main__":
+ exit(main())
diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
new file mode 100644
index 000000000000..e4bf03c41f4e
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
@@ -0,0 +1,5 @@
+a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
+ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
+fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
+d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
+3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
new file mode 100644
index 0000000000000000000000000000000000000000..7cc806a0133413a4aa037f1d43d80000546a5246
GIT binary patch
literal 29515
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
literal 0
HcmV?d00001
diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
new file mode 100644
index 0000000000000000000000000000000000000000..6335653ece1605cd0c53bd2cc2bc21d57d213dae
GIT binary patch
literal 79906
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
RBat2OV|2<CTVmi8`9DHIo&o>>
literal 0
HcmV?d00001
diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py b/BaseTools/Source/Python/FMMT/PI/Common.py
new file mode 100644
index 000000000000..683341094429
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/Common.py
@@ -0,0 +1,81 @@
+## @file
+# This file is used to define the common C struct and functions.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from ctypes import *
+import uuid
+
+# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
+# EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
+# EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
+# EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
+
+EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
+EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
+# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
+EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
+# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
+EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
+EFI_SYSTEM_NVDATA_FV_GUID = uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
+EFI_SYSTEM_NVDATA_FV_GUID_BYTE = b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
+EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
+EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
+ZEROVECTOR_BYTE = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
+FVH_SIGNATURE = b'_FVH'
+
+class GUID(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Guid1', c_uint32),
+ ('Guid2', c_uint16),
+ ('Guid3', c_uint16),
+ ('Guid4', ARRAY(c_uint8, 8)),
+ ]
+
+ def from_list(self, listformat: list) -> None:
+ self.Guid1 = listformat[0]
+ self.Guid2 = listformat[1]
+ self.Guid3 = listformat[2]
+ for i in range(8):
+ self.Guid4[i] = listformat[i+3]
+
+ def __cmp__(self, otherguid) -> bool:
+ if not isinstance(otherguid, GUID):
+ return 'Input is not the GUID instance!'
+ rt = False
+ if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2 and self.Guid3 == otherguid.Guid3:
+ rt = True
+ for i in range(8):
+ rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
+ return rt
+
+def ModifyGuidFormat(target_guid: str) -> GUID:
+ target_guid = target_guid.replace('-', '')
+ target_list = []
+ start = [0,8,12,16,18,20,22,24,26,28,30]
+ end = [8,12,16,18,20,22,24,26,28,30,32]
+ num = len(start)
+ for pos in range(num):
+ new_value = int(target_guid[start[pos]:end[pos]], 16)
+ target_list.append(new_value)
+ new_format = GUID()
+ new_format.from_list(target_list)
+ return new_format
+
+
+# Get data from ctypes to bytes.
+def struct2stream(s) -> bytes:
+ length = sizeof(s)
+ p = cast(pointer(s), POINTER(c_char * length))
+ return p.contents.raw
+
+
+
+def GetPadSize(Size: int, alignment: int) -> int:
+ if Size % alignment == 0:
+ return 0
+ Pad_Size = alignment - Size % alignment
+ return Pad_Size
diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
new file mode 100644
index 000000000000..fb0100420ecc
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
@@ -0,0 +1,66 @@
+## @file
+# This file is used to define the Ffs Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+EFI_FFS_FILE_HEADER_LEN = 24
+EFI_FFS_FILE_HEADER2_LEN = 32
+
+class CHECK_SUM(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Header', c_uint8),
+ ('File', c_uint8),
+ ]
+
+class EFI_FFS_INTEGRITY_CHECK(Union):
+ _pack_ = 1
+ _fields_ = [
+ ('Checksum', CHECK_SUM),
+ ('Checksum16', c_uint16),
+ ]
+
+
+class EFI_FFS_FILE_HEADER(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Name', GUID),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', ARRAY(c_uint8, 3)),
+ ('State', c_uint8),
+ ]
+
+ @property
+ def FFS_FILE_SIZE(self) -> int:
+ return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
+
+ @property
+ def HeaderLength(self) -> int:
+ return 24
+
+class EFI_FFS_FILE_HEADER2(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Name', GUID),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', ARRAY(c_uint8, 3)),
+ ('State', c_uint8),
+ ('ExtendedSize', c_uint64),
+ ]
+
+ @property
+ def FFS_FILE_SIZE(self) -> int:
+ return self.ExtendedSize
+
+ @property
+ def HeaderLength(self) -> int:
+ return 32
--git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
new file mode 100644
index 000000000000..51cb15ddac28
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
@@ -0,0 +1,112 @@
+## @file
+# This file is used to define the FV Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from ast import Str
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+class EFI_FV_BLOCK_MAP_ENTRY(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('NumBlocks', c_uint32),
+ ('Length', c_uint32),
+ ]
+
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', GUID),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8),
+ ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, 1)),
+ ]
+
+def Refine_FV_Header(nums):
+ class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', GUID),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8),
+ ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
+ ]
+ return EFI_FIRMWARE_VOLUME_HEADER
+
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
+ _fields_ = [
+ ('FvName', GUID),
+ ('ExtHeaderSize', c_uint32)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
+ _fields_ = [
+ ('ExtEntrySize', c_uint16),
+ ('ExtEntryType', c_uint16)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32),
+ ('Types', ARRAY(GUID, 1))
+ ]
+
+def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
+ class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('TypeMask', c_uint32),
+ ('Types', ARRAY(GUID, nums))
+ ]
+ return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID),
+ ('Data', ARRAY(c_uint8, 1))
+ ]
+
+def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
+ class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('FormatType', GUID),
+ ('Data', ARRAY(c_uint8, nums))
+ ]
+ return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
+
+class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
+ _fields_ = [
+ ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
+ ('UsedSize', c_uint32)
+ ]
diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
new file mode 100644
index 000000000000..8c6229819a18
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
@@ -0,0 +1,110 @@
+## @file
+# This file is used to define the Section Header C Struct.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from struct import *
+from ctypes import *
+from PI.Common import *
+
+EFI_COMMON_SECTION_HEADER_LEN = 4
+EFI_COMMON_SECTION_HEADER2_LEN = 8
+
+class EFI_COMMON_SECTION_HEADER(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Size', ARRAY(c_uint8, 3)),
+ ('Type', c_uint8),
+ ]
+
+ @property
+ def SECTION_SIZE(self) -> int:
+ return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
+
+ def Common_Header_Size(self) -> int:
+ return 4
+
+class EFI_COMMON_SECTION_HEADER2(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Size', ARRAY(c_uint8, 3)),
+ ('Type', c_uint8),
+ ('ExtendedSize', c_uint32),
+ ]
+
+ @property
+ def SECTION_SIZE(self) -> int:
+ return self.ExtendedSize
+
+ def Common_Header_Size(self) -> int:
+ return 8
+
+class EFI_COMPRESSION_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('UncompressedLength', c_uint32),
+ ('CompressionType', c_uint8),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 5
+
+class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SubTypeGuid', GUID),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 16
+
+class EFI_GUID_DEFINED_SECTION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SectionDefinitionGuid', GUID),
+ ('DataOffset', c_uint16),
+ ('Attributes', c_uint16),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 20
+
+def Get_USER_INTERFACE_Header(nums: int):
+ class EFI_SECTION_USER_INTERFACE(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('FileNameString', ARRAY(c_uint16, nums)),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 2 * nums
+
+ def GetUiString(self) -> str:
+ UiString = ''
+ for i in range(nums):
+ if self.FileNameString[i]:
+ UiString += chr(self.FileNameString[i])
+ return UiString
+
+ return EFI_SECTION_USER_INTERFACE
+
+def Get_VERSION_Header(nums: int):
+ class EFI_SECTION_VERSION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('BuildNumber', c_uint16),
+ ('VersionString', ARRAY(c_uint16, nums)),
+ ]
+
+ def ExtHeaderSize(self) -> int:
+ return 2 * (nums+1)
+
+ def GetVersionString(self) -> str:
+ VersionString = ''
+ for i in range(nums):
+ if self.VersionString[i]:
+ VersionString += chr(self.VersionString[i])
+ return VersionString
+
+ return EFI_SECTION_VERSION
diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py b/BaseTools/Source/Python/FMMT/PI/__init__.py
new file mode 100644
index 000000000000..21cbd82effc5
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
@@ -0,0 +1,6 @@
+## @file
+# This file is used to define the FMMT dependent external tool management class.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/README.md b/BaseTools/Source/Python/FMMT/README.md
new file mode 100644
index 000000000000..cfbc966a6af6
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/README.md
@@ -0,0 +1,180 @@
+# FMMT
+## Overview
+This FMMT tool is the python implementation of the edk2 FMMT tool which locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
+This implementation has the same usage as the edk2 FMMT, but it's more readable and relaiable.
+
+# FMMT User Guide
+
+#### Last updated October 13, 2021
+
+Important Changes and Updates:
+
+- Oct 13, 2021 Initial Draft of FMMT Python Tool
+
+#### Note:
+
+- FMMT Python Tool keeps same function with origin FMMT C Tool. It is much easier to maintain and extend other functions.
+
+
+
+# 1. Introduction
+
+## 1.1 Overview
+
+The Firmware Device is a persistent physical repository that contains firmware code and/or data. The firmware code and/or data stored in Firmware Volumes. Detail layout of Firmware Volumes is described in “Figure 1. The Firmware Volume Format”.
+
+![](Img/FirmwareVolumeFormat.png)
+
+ Figure 1. The Firmware Volume Format
+
+In firmware development, binary file has its firmware layout following the Platform-Initialization Specification. Thus, operation on FV file / FFS file (Firmware File) is an efficient and convenient way for firmware function testing and developing. FMMT Python tool is used for firmware files operation.
+
+## 1.2 Tool Capabilities
+
+The FMMT tool is capable of:
+
+- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware Files)
+
+- Add a new FFS into a FV file (both included in a FD file or not)
+
+- Replace an FFS in a FV file with a new FFS file
+
+- Delete an FFS in a FV file (both included in a FD file or not)
+
+- Extract the FFS from a FV file (both included in a FD file or not)
+
+## 1.3 References
+
+| Document |
+| ------------------------------------------------ |
+| UEFI Platform Initialization (PI) Specification |
+
+
+
+# 2. FMMT Python Tool Usage
+
+## 2.1 Required Files
+
+### 2.1.1 Independent use
+
+When independent use the FMMT Python Tool, the following files and settings are required:
+
+- GuidTool executable files used for Decompress/Compress Firmware data.
+
+- Environment variables path with GuidTool path setting.
+
+### 2.1.2 Use with Build System
+
+When use the FMMT Python Tool with Build System:
+
+- If only use Edk2 based GuidTool, do not need other preparation.
+
+- If use other customized GuidTool, need prepare the config file with GuidTool info. The syntax for GuidTool definition shown as follow:
+
+ ***ToolsGuid ShortName Command***
+
+ -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress***
+
+## 2.2 Syntax
+
+### 2.2.1 Syntax for Parse file
+
+ ***-v < Inputfile > < Outputfile > -l < LogFileType >***
+
+- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is optional, if inputs, the *Inputfile* will be encapsulated into *Outputfile* following the parsed firmware layout. *"-l LogFileType"* is optional, it decides the format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future.
+
+### 2.2.2 Syntax for Add a new FFS
+
+ ***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >***
+
+- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
+
+### 2.2.3 Syntax for Delete an FFS
+
+ ***-d < Inputfile > < TargetFfsName > < Outputfile > < TargetFvName/TargetFvGuid >***
+
+- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
+
+### 2.2.4 Syntax for Replace an FFS
+
+ ***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < TargetFvName/TargetFvGuid >***
+
+- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
+
+### 2.2.5 Syntax for Extract an FFS
+
+ ***-e < Inputfile > < TargetFfsName > < Outputfile >***
+
+- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs which will be extracted.
+
+
+
+# 3. FMMT Python Tool Design
+
+FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each Node have its Data field, which saves the FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the parse/add/delete/replace/extract operations are based on the NodeTree (adjusting the layout and data).
+
+## 3.1 NodeTree
+
+A whole NodeTree saves all the Firmware info.
+
+- Parent & Child relationship figured out the Firmware layout.
+
+- Each Node have several fields. ‘Data’ field saves an FirmwareClass instance which contains all the data info of the info.
+
+### 3.1.1 NodeTree Format
+
+The NodeTree will be created with parse function. When parse a file, a Root Node will be initialized firstly. The Data split and Tree construction process is described with an FD file shown as ‘Figure 2. The NodeTree format’:
+
+- A Root Node is initialized.
+
+- Use the ‘FV Signature’ as FV key to split Whole FD Data. ‘FV0’, ‘FV1’, ‘FV2’… Node created.
+
+- After FV level Node created, use the ‘Ffs Data Size’ as FFS key to split each FV Data. ‘Ffs0’...Node created.
+
+- After FFS level Node created, use the ‘Section Data Size’ as Section key to split each Ffs Data. ‘Section0’...Node created.
+
+- If some of Section includes other Sections, continue use the ‘Section Data Size’ as Section key to split each Section Data.
+
+- After all Node created, the whole NodeTree saves all the info. (Can be used in other functions or print the whole firmware layout into log file)
+
+![](Img/NodeTreeFormat.png)
+
+ Figure 2. The NodeTree format
+
+### 3.1.2 Node Factory and Product
+
+As 3.1.1, Each Node is created by data split and recognition. To extend the NodeTree usage, Factory pattern is used in Node created process.
+
+Each Node have its Factory to create Product and use Product ParserData function to deal with the data.
+
+## 3.2 GuidTool
+
+There are two ways to set the GuidTool. One from Config file, another from environment variables.
+
+Current GuidTool first check if has Config file.
+
+- If have, load the config GuidTool Information.
+
+- Else get from environment variables.
+
+### 3.2.1 Get from Config file
+
+- Config file should in same folder with FMMT.py or the path in environment variables.
+
+- Content should follow the format:
+
+ ***ToolsGuid ShortName Command***
+
+### 3.2.2 Get from Environment Variables
+
+- The GuidTool Command used must be set in environment variables.
+
+### 3.2.3 Edk2 Based GuidTool
+
+| ***Guid*** | ***ShortName*** | ***Command*** |
+| ------------------------------------------ | --------------- | --------------------- |
+| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | ***TianoCompress*** |
+| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | ***LzmaCompress*** |
+| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | ***GenCrc32*** |
+| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | ***LzmaF86Compress*** |
+| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | ***BrotliCompress*** |
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/__init__.py b/BaseTools/Source/Python/FMMT/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
new file mode 100644
index 000000000000..afc0a90bd0cd
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
@@ -0,0 +1,371 @@
+## @file
+# This file is used to implement of the various bianry parser.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from re import T
+import copy
+import os
+from PI.Common import *
+from core.BiosTreeNode import *
+from core.BiosTree import *
+from core.GuidTools import *
+
+ROOT_TREE = 'ROOT'
+ROOT_FV_TREE = 'ROOT_FV_TREE'
+ROOT_FFS_TREE = 'ROOT_FFS_TREE'
+ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+
+FV_TREE = 'FV'
+DATA_FV_TREE = 'DATA_FV'
+FFS_TREE = 'FFS'
+FFS_PAD = 'FFS_PAD'
+FFS_FREE_SPACE = 'FFS_FREE_SPACE'
+SECTION_TREE = 'SECTION'
+SEC_FV_TREE = 'SEC_FV_IMAGE'
+BINARY_DATA = 'BINARY'
+Fv_count = 0
+
+## Abstract factory
+class BinaryFactory():
+ type:list = []
+
+ def Create_Product():
+ pass
+
+class BinaryProduct():
+ ## Use GuidTool to decompress data.
+ def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
+ ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
+ DecompressedData = guidtool.unpack(Section_Data)
+ return DecompressedData
+
+ def ParserData():
+ pass
+
+class SectionFactory(BinaryFactory):
+ type = [SECTION_TREE]
+
+ def Create_Product():
+ return SectionProduct()
+
+class FfsFactory(BinaryFactory):
+ type = [ROOT_SECTION_TREE, FFS_TREE]
+
+ def Create_Product():
+ return FfsProduct()
+
+class FvFactory(BinaryFactory):
+ type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
+
+ def Create_Product():
+ return FvProduct()
+
+class FdFactory(BinaryFactory):
+ type = [ROOT_FV_TREE, ROOT_TREE]
+
+ def Create_Product():
+ return FdProduct()
+
+class SectionProduct(BinaryProduct):
+ ## Decompress the compressed section.
+ def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ if Section_Tree.Data.Type == 0x01:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ self.ParserFfs(Section_Tree, b'')
+ # Guided Define Section
+ elif Section_Tree.Data.Type == 0x02:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ DeCompressGuidTool = Section_Tree.Data.ExtHeader.SectionDefinitionGuid
+ Section_Tree.Data.Data = self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
+ Section_Tree.Data.Size = len(Section_Tree.Data.Data) + Section_Tree.Data.HeaderLength
+ self.ParserFfs(Section_Tree, b'')
+ elif Section_Tree.Data.Type == 0x03:
+ Section_Tree.Data.OriData = Section_Tree.Data.Data
+ self.ParserFfs(Section_Tree, b'')
+ # SEC_FV Section
+ elif Section_Tree.Data.Type == 0x17:
+ global Fv_count
+ Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
+ Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
+ Sec_Fv_Tree.type = SEC_FV_TREE
+ Sec_Fv_Tree.Data = Sec_Fv_Info
+ Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
+ Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + Sec_Fv_Tree.Data.Header.HeaderLength
+ Sec_Fv_Tree.Data.Data = Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
+ Section_Tree.insertChild(Sec_Fv_Tree)
+ Fv_count += 1
+
+ def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Rel_Offset = 0
+ Section_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Section_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Section recorded in its Parent Section.
+ while Rel_Offset < Data_Size:
+ # Create a SectionNode and set it as the SectionTree's Data
+ Section_Info = SectionNode(Whole_Data[Rel_Offset:])
+ Section_Tree = BIOSTREE(Section_Info.Name)
+ Section_Tree.type = SECTION_TREE
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
+ Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
+ Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
+ Section_Info.ROffset = Rel_Offset
+ if Section_Info.Header.Type == 0:
+ break
+ # The final Section in parent Section does not need to add padding, else must be 4-bytes align with parent Section start offset
+ Pad_Size = 0
+ if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Section_Info.Size, 4)
+ Section_Info.PadData = Pad_Size * b'\x00'
+ if Section_Info.Header.Type == 0x02:
+ Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size]
+ if Section_Info.Header.Type == 0x14:
+ ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
+ if Section_Info.Header.Type == 0x15:
+ ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
+ Section_Offset += Section_Info.Size + Pad_Size
+ Rel_Offset += Section_Info.Size + Pad_Size
+ Section_Tree.Data = Section_Info
+ ParTree.insertChild(Section_Tree)
+
+class FfsProduct(BinaryProduct):
+ # ParserFFs / GetSection
+ def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Rel_Offset = 0
+ Section_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Section_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Section recorded in Ffs.
+ while Rel_Offset < Data_Size:
+ # Create a SectionNode and set it as the SectionTree's Data
+ Section_Info = SectionNode(Whole_Data[Rel_Offset:])
+ Section_Tree = BIOSTREE(Section_Info.Name)
+ Section_Tree.type = SECTION_TREE
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
+ Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
+ Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
+ Section_Info.ROffset = Rel_Offset
+ if Section_Info.Header.Type == 0:
+ break
+ # The final Section in Ffs does not need to add padding, else must be 4-bytes align with Ffs start offset
+ Pad_Size = 0
+ if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Section_Info.Size, 4)
+ Section_Info.PadData = Pad_Size * b'\x00'
+ if Section_Info.Header.Type == 0x02:
+ Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
+ Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset: Rel_Offset+Section_Info.Size]
+ # If Section is Version or UI type, it saves the version and UI info of its parent Ffs.
+ if Section_Info.Header.Type == 0x14:
+ ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
+ if Section_Info.Header.Type == 0x15:
+ ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
+ Section_Offset += Section_Info.Size + Pad_Size
+ Rel_Offset += Section_Info.Size + Pad_Size
+ Section_Tree.Data = Section_Info
+ ParTree.insertChild(Section_Tree)
+
+class FvProduct(BinaryProduct):
+ ## ParserFv / GetFfs
+ def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Ffs_Offset = 0
+ Rel_Offset = 0
+ # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
+ if ParTree.Data != None:
+ Data_Size = len(ParTree.Data.Data)
+ Ffs_Offset = ParTree.Data.DOffset
+ Whole_Data = ParTree.Data.Data
+ else:
+ Data_Size = len(Whole_Data)
+ # Parser all the data to collect all the Ffs recorded in Fv.
+ while Rel_Offset < Data_Size:
+ # Create a FfsNode and set it as the FFsTree's Data
+ if Data_Size - Rel_Offset < 24:
+ Ffs_Tree = BIOSTREE('Free_Space')
+ Ffs_Tree.type = FFS_FREE_SPACE
+ Ffs_Tree.Data = FreeSpaceNode(Whole_Data[Rel_Offset:])
+ Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
+ Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
+ ParTree.Data.Free_Space = Data_Size - Rel_Offset
+ ParTree.insertChild(Ffs_Tree)
+ Rel_Offset = Data_Size
+ else:
+ Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
+ Ffs_Tree = BIOSTREE(Ffs_Info.Name)
+ Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
+ Ffs_Info.DOffset = Ffs_Offset + Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
+ Ffs_Info.ROffset = Rel_Offset
+ if Ffs_Info.Name == PADVECTOR:
+ Ffs_Tree.type = FFS_PAD
+ Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
+ Ffs_Info.Size = len(Ffs_Info.Data) + Ffs_Info.Header.HeaderLength
+ # if current Ffs is the final ffs of Fv and full of b'\xff', define it with Free_Space
+ if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') == b'':
+ Ffs_Tree.type = FFS_FREE_SPACE
+ Ffs_Info.Data = Whole_Data[Rel_Offset:]
+ Ffs_Info.Size = len(Ffs_Info.Data)
+ ParTree.Data.Free_Space = Ffs_Info.Size
+ else:
+ Ffs_Tree.type = FFS_TREE
+ Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
+ # The final Ffs in Fv does not need to add padding, else must be 8-bytes align with Fv start offset
+ Pad_Size = 0
+ if Ffs_Tree.type != FFS_FREE_SPACE and (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) != Data_Size):
+ Pad_Size = GetPadSize(Ffs_Info.Size, 8)
+ Ffs_Info.PadData = Pad_Size * b'\xff'
+ Ffs_Offset += Ffs_Info.Size + Pad_Size
+ Rel_Offset += Ffs_Info.Size + Pad_Size
+ Ffs_Tree.Data = Ffs_Info
+ ParTree.insertChild(Ffs_Tree)
+
+class FdProduct(BinaryProduct):
+ type = [ROOT_FV_TREE, ROOT_TREE]
+
+ ## Create DataTree with first level /fv Info, then parser each Fv.
+ def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0) -> None:
+ # Get all Fv image in Fd with offset and length
+ Fd_Struct = self.GetFvFromFd(whole_data)
+ data_size = len(whole_data)
+ Binary_count = 0
+ global Fv_count
+ # If the first Fv image is the Binary Fv, add it into the tree.
+ if Fd_Struct[0][1] != 0:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = 0 + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+ # Add the first collected Fv image into the tree.
+ Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
+ Cur_node.type = Fd_Struct[0][0]
+ Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
+ Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
+ Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
+ Cur_node.Data.Data = whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[0][1]+Cur_node.Data.Size]
+ WholeFvTree.insertChild(Cur_node)
+ Fv_count += 1
+ Fv_num = len(Fd_Struct)
+ # Add all the collected Fv image and the Binary Fv image between them into the tree.
+ for i in range(Fv_num-1):
+ if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+ Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
+ Cur_node.type = Fd_Struct[i+1][0]
+ Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
+ Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
+ Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
+ Cur_node.Data.Data = whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[i+1][1]+Cur_node.Data.Size]
+ WholeFvTree.insertChild(Cur_node)
+ Fv_count += 1
+ # If the final Fv image is the Binary Fv, add it into the tree
+ if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
+ Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
+ Binary_node.type = BINARY_DATA
+ Binary_node.Data = BinaryNode(str(Binary_count))
+ Binary_node.Data.Data = whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
+ Binary_node.Data.Size = len(Binary_node.Data.Data)
+ Binary_node.Data.HOffset = Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
+ WholeFvTree.insertChild(Binary_node)
+ Binary_count += 1
+
+ ## Get the first level Fv from Fd file.
+ def GetFvFromFd(self, whole_data: bytes=b'') -> list:
+ Fd_Struct = []
+ data_size = len(whole_data)
+ cur_index = 0
+ # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ cur_index = 0
+ # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ cur_index = 0
+ # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image offset and length.
+ while cur_index < data_size:
+ if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in whole_data[cur_index:]:
+ target_index = whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + cur_index
+ if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-16:target_index] == ZEROVECTOR_BYTE:
+ Fd_Struct.append([DATA_FV_TREE, target_index - 16, unpack("Q", whole_data[target_index+16:target_index+24])])
+ cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
+ else:
+ cur_index = target_index + 16
+ else:
+ cur_index = data_size
+ # Sort all the collect Fv image with offset.
+ Fd_Struct.sort(key=lambda x:x[1])
+ tmp_struct = copy.deepcopy(Fd_Struct)
+ tmp_index = 0
+ Fv_num = len(Fd_Struct)
+ # Remove the Fv image included in another Fv image.
+ for i in range(1,Fv_num):
+ if tmp_struct[i][1]+tmp_struct[i][2][0] < tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
+ Fd_Struct.remove(Fd_Struct[i-tmp_index])
+ tmp_index += 1
+ return Fd_Struct
+
+class ParserEntry():
+ FactoryTable:dict = {
+ SECTION_TREE: SectionFactory,
+ ROOT_SECTION_TREE: FfsFactory,
+ FFS_TREE: FfsFactory,
+ ROOT_FFS_TREE: FvFactory,
+ FV_TREE: FvFactory,
+ SEC_FV_TREE: FvFactory,
+ ROOT_FV_TREE: FdFactory,
+ ROOT_TREE: FdFactory,
+ }
+
+ def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
+ if Tree_type in self.FactoryTable:
+ return self.FactoryTable[Tree_type]
+
+ def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: bytes, Offset: int) -> None:
+ New_Product = TargetFactory.Create_Product()
+ New_Product.ParserData(Tree, Data, Offset)
+
+ def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
+ TargetFactory = self.GetTargetFactory(Tree.type)
+ if TargetFactory:
+ self.Generate_Product(TargetFactory, Tree, Data, Offset)
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py
new file mode 100644
index 000000000000..b2cdb49f9f3f
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
@@ -0,0 +1,199 @@
+## @file
+# This file is used to define the Bios layout tree structure and related operations.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import collections
+from typing import OrderedDict
+from PI.Common import *
+
+ROOT_TREE = 'ROOT'
+ROOT_FV_TREE = 'ROOT_FV_TREE'
+ROOT_FFS_TREE = 'ROOT_FFS_TREE'
+ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+
+FV_TREE = 'FV'
+DATA_FV_TREE = 'DATA_FV'
+FFS_TREE = 'FFS'
+FFS_PAD = 'FFS_PAD'
+FFS_FREE_SPACE = 'FFS_FREE_SPACE'
+SECTION_TREE = 'SECTION'
+SEC_FV_TREE = 'SEC_FV_IMAGE'
+BINARY_DATA = 'BINARY'
+
+RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE]
+FvType = [FV_TREE, SEC_FV_TREE]
+FfsType = FFS_TREE
+SecType = SECTION_TREE
+
+class BIOSTREE:
+ def __init__(self, NodeName: str) -> None:
+ self.key = NodeName
+ self.type = None
+ self.Data = None
+ self.Child = []
+ self.Findlist = []
+ self.Parent = None
+ self.NextRel = None
+ self.LastRel = None
+
+ def HasChild(self) -> bool:
+ if self.Child == []:
+ return False
+ else:
+ return True
+
+ def isFinalChild(self) -> bool:
+ ParTree = self.Parent
+ if ParTree:
+ if ParTree.Child[-1] == self:
+ return True
+ return False
+
+ # FvTree.insertChild()
+ def insertChild(self, newNode, pos: int=None) -> None:
+ if len(self.Child) == 0:
+ self.Child.append(newNode)
+ else:
+ if not pos:
+ LastTree = self.Child[-1]
+ self.Child.append(newNode)
+ LastTree.NextRel = newNode
+ newNode.LastRel = LastTree
+ else:
+ newNode.NextRel = self.Child[pos-1].NextRel
+ newNode.LastRel = self.Child[pos].LastRel
+ self.Child[pos-1].NextRel = newNode
+ self.Child[pos].LastRel = newNode
+ self.Child.insert(pos, newNode)
+ newNode.Parent = self
+
+ # lastNode.insertRel(newNode)
+ def insertRel(self, newNode) -> None:
+ if self.Parent:
+ parentTree = self.Parent
+ new_index = parentTree.Child.index(self) + 1
+ parentTree.Child.insert(new_index, newNode)
+ self.NextRel = newNode
+ newNode.LastRel = self
+
+ def deleteNode(self, deletekey: str) -> None:
+ FindStatus, DeleteTree = self.FindNode(deletekey)
+ if FindStatus:
+ parentTree = DeleteTree.Parent
+ lastTree = DeleteTree.LastRel
+ nextTree = DeleteTree.NextRel
+ if parentTree:
+ index = parentTree.Child.index(DeleteTree)
+ del parentTree.Child[index]
+ if lastTree and nextTree:
+ lastTree.NextRel = nextTree
+ nextTree.LastRel = lastTree
+ elif lastTree:
+ lastTree.NextRel = None
+ elif nextTree:
+ nextTree.LastRel = None
+ return DeleteTree
+ else:
+ print('Could not find the target tree')
+ return None
+
+ def FindNode(self, key: str, Findlist: list) -> None:
+ if self.key == key or (self.Data and self.Data.Name == key) or (self.type == FFS_TREE and self.Data.UiName == key):
+ Findlist.append(self)
+ else:
+ for item in self.Child:
+ item.FindNode(key, Findlist)
+
+ def GetTreePath(self):
+ BiosTreePath = [self]
+ while self.Parent:
+ BiosTreePath.insert(0, self.Parent)
+ self = self.Parent
+ return BiosTreePath
+
+ def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0) -> None:
+ Key = list(TargetDict.keys())[0]
+ if TargetDict[Key]["Type"] in RootType:
+ Info.append("Image File: {}".format(Key))
+ Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum')))
+ Info.append("\n")
+ elif TargetDict[Key]["Type"] in FvType:
+ space += 2
+ if TargetDict[Key]["Type"] == SEC_FV_TREE:
+ Info.append("{}Child FV named {} of {}".format(space*" ", Key, self.FvId))
+ space += 2
+ else:
+ Info.append("FvId: {}".format(Key))
+ self.FvId = Key
+ Info.append("{}FvNameGuid: {}".format(space*" ", TargetDict.get(Key).get('FvNameGuid')))
+ Info.append("{}Attributes: {}".format(space*" ", TargetDict.get(Key).get('Attributes')))
+ Info.append("{}Total Volume Size: {}".format(space*" ", TargetDict.get(Key).get('Size')))
+ Info.append("{}Free Volume Size: {}".format(space*" ", TargetDict.get(Key).get('FreeSize')))
+ Info.append("{}Volume Offset: {}".format(space*" ", TargetDict.get(Key).get('Offset')))
+ Info.append("{}FilesNum: {}".format(space*" ", TargetDict.get(Key).get('FilesNum')))
+ elif TargetDict[Key]["Type"] in FfsType:
+ space += 2
+ if TargetDict.get(Key).get('UiName') != "b''":
+ Info.append("{}File: {} / {}".format(space*" ", Key, TargetDict.get(Key).get('UiName')))
+ else:
+ Info.append("{}File: {}".format(space*" ", Key))
+ if "Files" in list(TargetDict[Key].keys()):
+ for item in TargetDict[Key]["Files"]:
+ self.parserTree(item, Info, space)
+
+ def ExportTree(self,TreeInfo: dict=None) -> dict:
+ if TreeInfo is None:
+ TreeInfo =collections.OrderedDict()
+
+ if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
+ key = str(self.key)
+ TreeInfo[self.key] = collections.OrderedDict()
+ TreeInfo[self.key]["Name"] = key
+ TreeInfo[self.key]["Type"] = self.type
+ TreeInfo[self.key]["FilesNum"] = len(self.Child)
+ elif self.type == FV_TREE or self.type == SEC_FV_TREE:
+ key = str(self.Data.FvId)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ if self.Data.FvId != self.Data.Name:
+ TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes)
+ TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
+ TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self.type == FFS_TREE:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
+ TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self.type == SECTION_TREE and self.Data.Type == 0x02:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + self.Data.HeaderLength)
+ TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+ elif self is not None:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["Size"] = hex(self.Data.Size)
+ TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
+ TreeInfo[key]["FilesNum"] = len(self.Child)
+
+ for item in self.Child:
+ TreeInfo[key].setdefault('Files',[]).append( item.ExportTree())
+
+ return TreeInfo
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
new file mode 100644
index 000000000000..b77d9100e7b3
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
@@ -0,0 +1,191 @@
+## @file
+# This file is used to define the BIOS Tree Node.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from PI.FvHeader import *
+from PI.FfsFileHeader import *
+from PI.SectionHeader import *
+from PI.Common import *
+import uuid
+
+SectionHeaderType = {
+ 0x01:'EFI_COMPRESSION_SECTION',
+ 0x02:'EFI_GUID_DEFINED_SECTION',
+ 0x03:'EFI_SECTION_DISPOSABLE',
+ 0x10:'EFI_SECTION_PE32',
+ 0x11:'EFI_SECTION_PIC',
+ 0x12:'EFI_SECTION_TE',
+ 0x13:'EFI_SECTION_DXE_DEPEX',
+ 0x14:'EFI_SECTION_VERSION',
+ 0x15:'EFI_SECTION_USER_INTERFACE',
+ 0x16:'EFI_SECTION_COMPATIBILITY16',
+ 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
+ 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
+ 0x19:'EFI_SECTION_RAW',
+ 0x1B:'EFI_SECTION_PEI_DEPEX',
+ 0x1C:'EFI_SECTION_MM_DEPEX'
+}
+HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
+
+class BinaryNode:
+ def __init__(self, name: str) -> None:
+ self.Size = 0
+ self.Name = "BINARY" + str(name)
+ self.HOffset = 0
+ self.Data = b''
+
+class FvNode:
+ def __init__(self, name, buffer: bytes) -> None:
+ self.Header = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
+ Map_num = (self.Header.HeaderLength - 56)//8
+ self.Header = Refine_FV_Header(Map_num).from_buffer_copy(buffer)
+ self.FvId = "FV" + str(name)
+ self.Name = "FV" + str(name)
+ if self.Header.ExtHeaderOffset:
+ self.ExtHeader = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header.ExtHeaderOffset:])
+ self.Name = uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
+ self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
+ if self.ExtHeader.ExtHeaderSize != 20:
+ self.ExtEntryExist = 1
+ self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntryOffset:])
+ self.ExtTypeExist = 1
+ if self.ExtEntry.ExtEntryType == 0x01:
+ nums = (self.ExtEntry.ExtEntrySize - 8) // 16
+ self.ExtEntry = Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
+ elif self.ExtEntry.ExtEntryType == 0x02:
+ nums = self.ExtEntry.ExtEntrySize - 20
+ self.ExtEntry = Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
+ elif self.ExtEntry.ExtEntryType == 0x03:
+ self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(buffer[self.ExtEntryOffset:])
+ else:
+ self.ExtTypeExist = 0
+ else:
+ self.ExtEntryExist = 0
+ self.Size = self.Header.FvLength
+ self.HeaderLength = self.Header.HeaderLength
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ if self.Header.Signature != 1213613663:
+ print('Invalid! Fv Header Signature {} is not "_FVH".'.format(self.Header.Signature))
+ with open(str(self.Name)+'.fd', "wb") as f:
+ f.write(struct2stream(self.Header))
+ assert False
+ self.PadData = b''
+ self.Free_Space = 0
+ self.ModCheckSum()
+
+ def ModCheckSum(self) -> None:
+ # Fv Header Sums to 0.
+ Header = struct2stream(self.Header)[::-1]
+ Size = self.HeaderLength // 2
+ Sum = 0
+ for i in range(Size):
+ Sum += int(Header[i*2: i*2 + 2].hex(), 16)
+ if Sum & 0xffff:
+ self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - self.Header.Checksum)[-4:], 16)), 16)
+
+ def ModFvExt(self) -> None:
+ # If used space changes and self.ExtEntry.UsedSize exists, self.ExtEntry.UsedSize need to be changed.
+ if self.Header.ExtHeaderOffset and self.ExtEntryExist and self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType == 0x03:
+ self.ExtEntry.UsedSize = self.Header.FvLength - self.Free_Space
+
+ def ModFvSize(self) -> None:
+ # If Fv Size changed, self.Header.FvLength and self.Header.BlockMap[i].NumBlocks need to be changed.
+ BlockMapNum = len(self.Header.BlockMap)
+ for i in range(BlockMapNum):
+ if self.Header.BlockMap[i].Length:
+ self.Header.BlockMap[i].NumBlocks = self.Header.FvLength // self.Header.BlockMap[i].Length
+
+ def ModExtHeaderData(self) -> None:
+ if self.Header.ExtHeaderOffset:
+ ExtHeaderData = struct2stream(self.ExtHeader)
+ ExtHeaderDataOffset = self.Header.ExtHeaderOffset - self.HeaderLength
+ self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData + self.Data[ExtHeaderDataOffset+20:]
+ if self.Header.ExtHeaderOffset and self.ExtEntryExist:
+ ExtHeaderEntryData = struct2stream(self.ExtEntry)
+ ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + 20 - self.HeaderLength
+ self.Data = self.Data[:ExtHeaderEntryDataOffset] + ExtHeaderEntryData + self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
+
+class FfsNode:
+ def __init__(self, buffer: bytes) -> None:
+ self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
+ # self.Attributes = unpack("<B", buffer[21:22])[0]
+ if self.Header.Size != 0 and self.Header.Attributes == 0x01:
+ print('Error Ffs Header! Ffs Header Size and Attributes is not matched!')
+ if self.Header.Size == 0 and self.Header.Attributes == 0x01:
+ self.Header = EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
+ self.Name = uuid.UUID(bytes_le=struct2stream(self.Header.Name))
+ self.UiName = b''
+ self.Version = b''
+ self.Size = self.Header.FFS_FILE_SIZE
+ self.HeaderLength = self.Header.HeaderLength
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ self.PadData = b''
+
+ def ModCheckSum(self) -> None:
+ HeaderData = struct2stream(self.Header)
+ HeaderSum = 0
+ for item in HeaderData:
+ HeaderSum += item
+ HeaderSum -= self.Header.State
+ HeaderSum -= self.Header.IntegrityCheck.Checksum.File
+ if HeaderSum & 0xff:
+ Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 - int(hex(HeaderSum)[-2:], 16)
+ self.Header.IntegrityCheck.Checksum.Header = int(hex(Header)[-2:], 16)
+
+class SectionNode:
+ def __init__(self, buffer: bytes) -> None:
+ if buffer[0:3] != b'\xff\xff\xff':
+ self.Header = EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
+ else:
+ self.Header = EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
+ if self.Header.Type in SectionHeaderType:
+ self.Name = SectionHeaderType[self.Header.Type]
+ elif self.Header.Type == 0:
+ self.Name = "EFI_SECTION_RAW"
+ else:
+ self.Name = "SECTION"
+ if self.Header.Type in HeaderType:
+ self.ExtHeader = self.GetExtHeader(self.Header.Type, buffer[self.Header.Common_Header_Size():], (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
+ self.HeaderLength = self.Header.Common_Header_Size() + self.ExtHeader.ExtHeaderSize()
+ else:
+ self.ExtHeader = None
+ self.HeaderLength = self.Header.Common_Header_Size()
+ self.Size = self.Header.SECTION_SIZE
+ self.Type = self.Header.Type
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ self.OriData = b''
+ self.OriHeader = b''
+ self.PadData = b''
+
+ def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None:
+ if Type == 0x01:
+ return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
+ elif Type == 0x02:
+ return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
+ elif Type == 0x14:
+ return Get_VERSION_Header((nums - 2)//2).from_buffer_copy(buffer)
+ elif Type == 0x15:
+ return Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
+ elif Type == 0x18:
+ return EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
+
+class FreeSpaceNode:
+ def __init__(self, buffer: bytes) -> None:
+ self.Name = 'Free_Space'
+ self.Data = buffer
+ self.Size = len(buffer)
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.PadData = b''
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
new file mode 100644
index 000000000000..e42565965909
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
@@ -0,0 +1,140 @@
+## @file
+# This file is used to define the functions to operate bios binary file.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from core.FMMTParser import *
+from core.FvHandler import *
+from utils.FvLayoutPrint import *
+
+global Fv_count
+Fv_count = 0
+
+# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE'
+def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # 3. Log Output
+ InfoDict = FmmtParser.WholeFvTree.ExportTree()
+ FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
+ GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
+ if logfile:
+ GetFormatter(logfile.lower()).dump(InfoDict, FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile),".{}".format(logfile.lower())))
+ # 4. Data Encapsultion
+ if outputfile:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # 3. Data Modify
+ FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist)
+ # Choose the Specfic DeleteFfs with Fv info
+ if Fv_name:
+ for item in FmmtParser.WholeFvTree.Findlist:
+ if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
+ FmmtParser.WholeFvTree.Findlist.remove(item)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
+ FfsMod = FvHandler(None, Delete_Ffs)
+ Status = FfsMod.DeleteFfs()
+ else:
+ print('Target Ffs not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ # Get Target Fv and Target Ffs_Pad
+ FmmtParser.WholeFvTree.FindNode(Fv_name, FmmtParser.WholeFvTree.Findlist)
+ # Create new ffs Tree
+ with open(newffsfile, "rb") as f:
+ new_ffs_data = f.read()
+ NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
+ Status = False
+ # 3. Data Modify
+ if FmmtParser.WholeFvTree.Findlist:
+ for TargetFv in FmmtParser.WholeFvTree.Findlist:
+ TargetFfsPad = TargetFv.Child[-1]
+ if TargetFfsPad.type == FFS_FREE_SPACE:
+ NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset)
+ else:
+ NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
+ FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], TargetFfsPad)
+ Status = FfsMod.AddFfs()
+ else:
+ print('Target Fv not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
+ # 1. Data Prepare
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ # 2. DataTree Create
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ with open(newffsfile, "rb") as f:
+ new_ffs_data = f.read()
+ newFmmtParser = FMMTParser(newffsfile, FV_TREE)
+ newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, new_ffs_data)
+ Status = False
+ # 3. Data Modify
+ new_ffs = newFmmtParser.WholeFvTree.Child[0]
+ new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
+ FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
+ if Fv_name:
+ for item in FmmtParser.WholeFvTree.Findlist:
+ if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
+ FmmtParser.WholeFvTree.Findlist.remove(item)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ for TargetFfs in FmmtParser.WholeFvTree.Findlist:
+ FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs)
+ Status = FfsMod.ReplaceFfs()
+ else:
+ print('Target Ffs not found!!!')
+ # 4. Data Encapsultion
+ if Status:
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
+ with open(outputfile, "wb") as f:
+ f.write(FmmtParser.FinalData)
+
+def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
+ with open(inputfile, "rb") as f:
+ whole_data = f.read()
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
+ FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
+ if FmmtParser.WholeFvTree.Findlist != []:
+ TargetNode = FmmtParser.WholeFvTree.Findlist[0]
+ TargetFv = TargetNode.Parent
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ TargetNode.Data.Header.State = c_uint8(
+ ~TargetNode.Data.Header.State)
+ FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data
+ with open(outputfile, "wb") as f:
+ f.write(FinalData)
+ else:
+ print('Target Ffs not found!!!')
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
new file mode 100644
index 000000000000..6f35d4dd76cf
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
@@ -0,0 +1,86 @@
+## @file
+# This file is used to define the interface of Bios Parser.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from PI.Common import *
+from core.BinaryFactoryProduct import ParserEntry
+from core.BiosTreeNode import *
+from core.BiosTree import *
+from core.GuidTools import *
+
+class FMMTParser:
+ def __init__(self, name: str, TYPE: str) -> None:
+ self.WholeFvTree = BIOSTREE(name)
+ self.WholeFvTree.type = TYPE
+ self.FinalData = b''
+ self.BinaryInfo = []
+
+ ## Parser the nodes in WholeTree.
+ def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', Reloffset: int=0) -> None:
+ if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE:
+ ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset)
+ else:
+ ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset)
+ for Child in WholeFvTree.Child:
+ self.ParserFromRoot(Child, "")
+
+ ## Encapuslation all the data in tree into self.FinalData
+ def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
+ # If current node is Root node, skip it.
+ if rootTree.type == ROOT_TREE or rootTree.type == ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type == ROOT_SECTION_TREE:
+ print('Start at Root !')
+ # If current node do not have Header, just add Data.
+ elif rootTree.type == BINARY_DATA or rootTree.type == FFS_FREE_SPACE:
+ self.FinalData += rootTree.Data.Data
+ rootTree.Child = []
+ # If current node do not have Child and ExtHeader, just add its Header and Data.
+ elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
+ self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ if ParTree.type != 'ROOT':
+ self.FinalData += ParTree.Data.PadData
+ rootTree.Child = []
+ # If current node is not Section node and may have Child and ExtHeader, add its Header,ExtHeader. If do not have Child, add its Data.
+ elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or rootTree.type == SEC_FV_TREE:
+ if rootTree.HasChild():
+ self.FinalData += struct2stream(rootTree.Data.Header)
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ if ParTree.type != 'ROOT':
+ self.FinalData += ParTree.Data.PadData
+ # If current node is Section, need to consider its ExtHeader, Child and Compressed Status.
+ elif rootTree.type == SECTION_TREE:
+ # Not compressed section
+ if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != b'' and CompressStatus):
+ if rootTree.HasChild():
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader)
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header)
+ else:
+ Data = rootTree.Data.Data
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ self.FinalData += ParTree.Data.PadData
+ # If compressed section
+ else:
+ Data = rootTree.Data.OriData
+ rootTree.Child = []
+ if rootTree.Data.ExtHeader:
+ self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data + rootTree.Data.PadData
+ else:
+ self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
+ if rootTree.isFinalChild():
+ ParTree = rootTree.Parent
+ self.FinalData += ParTree.Data.PadData
+ for Child in rootTree.Child:
+ self.Encapsulation(Child, CompressStatus)
diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py
new file mode 100644
index 000000000000..7809e1598c1e
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
@@ -0,0 +1,521 @@
+## @file
+# This file is used to the implementation of Bios layout handler.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+from core.BiosTree import *
+from core.GuidTools import GUIDTools
+from core.BiosTreeNode import *
+from PI.Common import *
+
+EFI_FVB2_ERASE_POLARITY = 0x00000800
+
+def ChangeSize(TargetTree, size_delta: int=0) -> None:
+ if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or type(TargetTree.Data.Header) == type(EFI_COMMON_SECTION_HEADER2()):
+ TargetTree.Data.Size -= size_delta
+ TargetTree.Data.Header.ExtendedSize -= size_delta
+ elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
+ OriSize = TargetTree.Data.Header.SECTION_SIZE
+ OriSize -= size_delta
+ TargetTree.Data.Header.Size[0] = OriSize % (16**2)
+ TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
+ TargetTree.Data.Header.Size[2] = OriSize // (16**4)
+ else:
+ TargetTree.Data.Size -= size_delta
+ TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
+ TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) //(16**2)
+ TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
+
+def ModifyFfsType(TargetFfs) -> None:
+ if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and (TargetFfs.Data.HeaderLength + TargetFfs.Data.Size) > 0xFFFFFF:
+ ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
+ New_Header = EFI_FFS_FILE_HEADER2()
+ New_Header.Name = TargetFfs.Data.Header.Name
+ New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
+ New_Header.Type = TargetFfs.Data.Header.Type
+ New_Header.Attributes = TargetFfs.Data.Header.Attributes
+ New_Header.Size = 0
+ New_Header.State = TargetFfs.Data.Header.State
+ New_Header.ExtendedSize = ExtendSize
+ TargetFfs.Data.Header = New_Header
+ TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
+ TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
+ TargetFfs.Data.ModCheckSum()
+ elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and (TargetFfs.Data.HeaderLength + TargetFfs.Data.Size) <= 0xFFFFFF:
+ New_Header = EFI_FFS_FILE_HEADER()
+ New_Header.Name = TargetFfs.Data.Header.Name
+ New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
+ New_Header.Type = TargetFfs.Data.Header.Type
+ New_Header.Attributes = TargetFfs.Data.Header.Attributes
+ New_Header.Size = TargetFfs.Data.HeaderLength + TargetFfs.Data.Size
+ New_Header.State = TargetFfs.Data.Header.State
+ TargetFfs.Data.Header = New_Header
+ TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
+ TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
+ TargetFfs.Data.ModCheckSum()
+ if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
+ NeedChange = True
+ for item in TargetFfs.Parent.Child:
+ if type(item.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
+ NeedChange = False
+ if NeedChange:
+ TargetFfs.Parent.Data.Header.FileSystemGuid = ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
+
+ if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
+ TarParent = TargetFfs.Parent
+ while TarParent:
+ if TarParent.type == FV_TREE and struct2stream(TarParent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
+ TarParent.Data.Header.FileSystemGuid = ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
+ TarParent = TarParent.Parent
+
+class FvHandler:
+ def __init__(self, NewFfs, TargetFfs) -> None:
+ self.NewFfs = NewFfs
+ self.TargetFfs = TargetFfs
+ self.Status = False
+ self.Remain_New_Free_Space = 0
+
+ ## Use for Compress the Section Data
+ def CompressData(self, TargetTree) -> None:
+ TreePath = TargetTree.GetTreePath()
+ pos = len(TreePath)
+ self.Status = True
+ while pos:
+ if self.Status:
+ if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-1].Data.Type == 0x02:
+ self.CompressSectionData(TreePath[pos-1], None, TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
+ else:
+ if pos == len(TreePath):
+ self.CompressSectionData(TreePath[pos-1], pos)
+ else:
+ self.CompressSectionData(TreePath[pos-1], None)
+ pos -= 1
+
+ def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> None:
+ NewData = b''
+ temp_save_child = TargetTree.Child
+ if TargetTree.Data:
+ for item in temp_save_child:
+ if item.type == SECTION_TREE and not item.Data.OriData and item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.OriData and not item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + item.Data.OriData + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.OriData and item.Data.ExtHeader:
+ NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ elif item.type == FFS_FREE_SPACE:
+ NewData += item.Data.Data + item.Data.PadData
+ else:
+ NewData += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
+ if TargetTree.type == FFS_TREE:
+ New_Pad_Size = GetPadSize(len(NewData), 8)
+ Size_delta = len(NewData) - len(TargetTree.Data.Data)
+ ChangeSize(TargetTree, -Size_delta)
+ Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
+ self.Remain_New_Free_Space += Delta_Pad_Size
+ TargetTree.Data.PadData = b'\xff' * New_Pad_Size
+ TargetTree.Data.ModCheckSum()
+ elif TargetTree.type == FV_TREE or TargetTree.type == SEC_FV_TREE and not pos:
+ if self.Remain_New_Free_Space:
+ if TargetTree.Data.Free_Space:
+ TargetTree.Data.Free_Space += self.Remain_New_Free_Space
+ NewData += self.Remain_New_Free_Space * b'\xff'
+ TargetTree.Child[-1].Data.Data += self.Remain_New_Free_Space * b'\xff'
+ else:
+ TargetTree.Data.Data += self.Remain_New_Free_Space * b'\xff'
+ New_Free_Space = BIOSTREE('FREE_SPACE')
+ New_Free_Space.type = FFS_FREE_SPACE
+ New_Free_Space.Data = FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
+ TargetTree.insertChild(New_Free_Space)
+ self.Remain_New_Free_Space = 0
+ if TargetTree.type == SEC_FV_TREE:
+ Size_delta = len(NewData) + self.Remain_New_Free_Space - len(TargetTree.Data.Data)
+ TargetTree.Data.Header.FvLength += Size_delta
+ TargetTree.Data.ModFvExt()
+ TargetTree.Data.ModFvSize()
+ TargetTree.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetTree)
+ TargetTree.Data.ModCheckSum()
+ elif TargetTree.type == SECTION_TREE and TargetTree.Data.Type != 0x02:
+ New_Pad_Size = GetPadSize(len(NewData), 4)
+ Size_delta = len(NewData) - len(TargetTree.Data.Data)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
+ self.Remain_New_Free_Space += Delta_Pad_Size
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ TargetTree.Data.Data = NewData
+ if GuidTool:
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
+ ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
+ CompressedData = guidtool.pack(TargetTree.Data.Data)
+ if len(CompressedData) < len(TargetTree.Data.OriData):
+ New_Pad_Size = GetPadSize(len(CompressedData), 4)
+ Size_delta = len(CompressedData) - len(TargetTree.Data.OriData)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ self.Remain_New_Free_Space = len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - len(CompressedData) - New_Pad_Size
+ else:
+ TargetTree.Data.PadData = b''
+ self.Remain_New_Free_Space = len(TargetTree.Data.OriData) - len(CompressedData)
+ TargetTree.Data.OriData = CompressedData
+ elif len(CompressedData) == len(TargetTree.Data.OriData):
+ TargetTree.Data.OriData = CompressedData
+ elif len(CompressedData) > len(TargetTree.Data.OriData):
+ New_Pad_Size = GetPadSize(CompressedData, 4)
+ self.Remain_New_Free_Space = len(CompressedData) + New_Pad_Size - len(TargetTree.Data.OriData) - len(TargetTree.Data.PadData)
+ Size_delta = len(TargetTree.Data.OriData) - len(CompressedData)
+ ChangeSize(TargetTree, -Size_delta)
+ if TargetTree.NextRel:
+ TargetTree.Data.PadData = b'\x00' * New_Pad_Size
+ TargetTree.Data.OriData = CompressedData
+ self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
+ self.Status = False
+
+ def ModifyFvExtData(self, TreeNode) -> None:
+ FvExtData = b''
+ if TreeNode.Data.Header.ExtHeaderOffset:
+ FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
+ FvExtData += FvExtHeader
+ if TreeNode.Data.Header.ExtHeaderOffset and TreeNode.Data.ExtEntryExist:
+ FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
+ FvExtData += FvExtEntry
+ if FvExtData:
+ InfoNode = TreeNode.Child[0]
+ InfoNode.Data.Data = FvExtData + InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
+ InfoNode.Data.ModCheckSum()
+
+ def ModifyTest(self, ParTree, Needed_Space: int) -> None:
+ if Needed_Space > 0:
+ if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
+ ParTree.Data.Data = b''
+ Needed_Space = Needed_Space - ParTree.Data.Free_Space
+ if Needed_Space < 0:
+ ParTree.Child[-1].Data.Data = b'\xff' * (-Needed_Space)
+ ParTree.Data.Free_Space = (-Needed_Space)
+ self.Status = True
+ else:
+ if ParTree.type == FV_TREE:
+ self.Status = False
+ else:
+ BlockSize = ParTree.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - Needed_Space%BlockSize
+ if New_Add_Len % BlockSize:
+ ParTree.Child[-1].Data.Data = b'\xff' * New_Add_Len
+ ParTree.Data.Free_Space = New_Add_Len
+ Needed_Space += New_Add_Len
+ else:
+ ParTree.Child.remove(ParTree.Child[-1])
+ ParTree.Data.Free_Space = 0
+ ParTree.Data.Size += Needed_Space
+ ParTree.Data.Header.Fvlength = ParTree.Data.Size
+ for item in ParTree.Child:
+ if item.type == FFS_FREE_SPACE:
+ ParTree.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ ParTree.Data.ModFvExt()
+ ParTree.Data.ModFvSize()
+ ParTree.Data.ModExtHeaderData()
+ self.ModifyFvExtData(ParTree)
+ ParTree.Data.ModCheckSum()
+ elif ParTree.type == FFS_TREE:
+ ParTree.Data.Data = b''
+ for item in ParTree.Child:
+ if item.Data.OriData:
+ if item.Data.ExtHeader:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData
+ else:
+ if item.Data.ExtHeader:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ ChangeSize(ParTree, -Needed_Space)
+ New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ Needed_Space += Delta_Pad_Size
+ ParTree.Data.PadData = b'\xff' * GetPadSize(ParTree.Data.Size, 8)
+ ParTree.Data.ModCheckSum()
+ elif ParTree.type == SECTION_TREE:
+ OriData = ParTree.Data.Data
+ ParTree.Data.Data = b''
+ for item in ParTree.Child:
+ if item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type != 0x02:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data + item.Data.PadData
+ elif item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type == 0x02:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData + item.Data.PadData
+ else:
+ ParTree.Data.Data += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
+ if ParTree.Data.Type == 0x02:
+ ParTree.Data.Size += Needed_Space
+ ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+ ToolPath = os.path.join(os.path.dirname(ParPath), r'FMMTConfig.ini')
+ guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.SectionDefinitionGuid))
+ CompressedData = guidtool.pack(ParTree.Data.Data)
+ Needed_Space = len(CompressedData) - len(ParTree.Data.OriData)
+ ParTree.Data.OriData = CompressedData
+ New_Size = ParTree.Data.HeaderLength + len(CompressedData)
+ ParTree.Data.Header.Size[0] = New_Size % (16**2)
+ ParTree.Data.Header.Size[1] = New_Size % (16**4) //(16**2)
+ ParTree.Data.Header.Size[2] = New_Size // (16**4)
+ if ParTree.NextRel:
+ New_Pad_Size = GetPadSize(New_Size, 4)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ ParTree.Data.PadData = b'\x00' * New_Pad_Size
+ Needed_Space += Delta_Pad_Size
+ else:
+ ParTree.Data.PadData = b''
+ elif Needed_Space:
+ ChangeSize(ParTree, -Needed_Space)
+ New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
+ Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ Needed_Space += Delta_Pad_Size
+ ParTree.Data.PadData = b'\x00' * New_Pad_Size
+ NewParTree = ParTree.Parent
+ ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE, ROOT_TREE]
+ if NewParTree and NewParTree.type not in ROOT_TYPE:
+ self.ModifyTest(NewParTree, Needed_Space)
+ else:
+ self.Status = True
+
+ def ReplaceFfs(self) -> bool:
+ TargetFv = self.TargetFfs.Parent
+ # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ # NewFfs parsing will not calculate the PadSize, thus recalculate.
+ self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
+ if self.NewFfs.Data.Size > self.TargetFfs.Data.Size:
+ Needed_Space = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData)
+ # If TargetFv have enough free space, just move part of the free space to NewFfs.
+ if TargetFv.Data.Free_Space >= Needed_Space:
+ # Modify TargetFv Child info and BiosTree.
+ TargetFv.Child[-1].Data.Data = b'\xff' * (TargetFv.Data.Free_Space - Needed_Space)
+ TargetFv.Data.Free_Space -= Needed_Space
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ # Modify TargetFv Header and ExtHeader info.
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # return the Status
+ self.Status = True
+ # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ else:
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ else:
+ # Recalculate TargetFv needed space to keep it match the BlockSize setting.
+ Needed_Space -= TargetFv.Data.Free_Space
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - Needed_Space%BlockSize
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ if New_Add_Len % BlockSize:
+ TargetFv.Child[-1].Data.Data = b'\xff' * New_Add_Len
+ TargetFv.Data.Free_Space = New_Add_Len
+ Needed_Space += New_Add_Len
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ TargetFv.Child.remove(self.TargetFfs)
+ else:
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.Data.Free_Space = 0
+ TargetFv.insertChild(self.NewFfs)
+ # Encapsulate the Fv Data for update.
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ TargetFv.Data.Size += Needed_Space
+ # Modify TargetFv Data Header and ExtHeader info.
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # Start free space calculating and moving process.
+ self.ModifyTest(TargetFv.Parent, Needed_Space)
+ else:
+ New_Free_Space = self.TargetFfs.Data.Size - self.NewFfs.Data.Size
+ # If TargetFv already have free space, move the new free space into it.
+ if TargetFv.Data.Free_Space:
+ TargetFv.Child[-1].Data.Data += b'\xff' * New_Free_Space
+ TargetFv.Data.Free_Space += New_Free_Space
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ self.Status = True
+ # If TargetFv do not have free space, create free space for Fv.
+ else:
+ New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
+ New_Free_Space_Tree.type = FFS_FREE_SPACE
+ New_Free_Space_Tree.Data = FfsNode(b'\xff' * New_Free_Space)
+ TargetFv.Data.Free_Space = New_Free_Space
+ TargetFv.insertChild(New_Free_Space)
+ Target_index = TargetFv.Child.index(self.TargetFfs)
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs, Target_index)
+ self.Status = True
+ # Modify TargetFv Header and ExtHeader info.
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ return self.Status
+
+ def AddFfs(self) -> bool:
+ # NewFfs parsing will not calculate the PadSize, thus recalculate.
+ self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
+ if self.TargetFfs.type == FFS_FREE_SPACE:
+ TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size - len(self.TargetFfs.Data.PadData)
+ TargetFv = self.TargetFfs.Parent
+ # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ # If TargetFv have enough free space, just move part of the free space to NewFfs, split free space to NewFfs and new free space.
+ if TargetLen < 0:
+ self.Status = True
+ self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
+ TargetFv.Data.Free_Space = (-TargetLen)
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ TargetFv.insertChild(self.NewFfs, -1)
+ ModifyFfsType(self.NewFfs)
+ elif TargetLen == 0:
+ self.Status = True
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs)
+ ModifyFfsType(self.NewFfs)
+ # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ else:
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ elif TargetFv.type == SEC_FV_TREE:
+ # Recalculate TargetFv needed space to keep it match the BlockSize setting.
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - TargetLen%BlockSize
+ if New_Add_Len % BlockSize:
+ self.TargetFfs.Data.Data = b'\xff' * New_Add_Len
+ self.TargetFfs.Data.Size = New_Add_Len
+ TargetLen += New_Add_Len
+ TargetFv.insertChild(self.NewFfs, -1)
+ TargetFv.Data.Free_Space = New_Add_Len
+ else:
+ TargetFv.Child.remove(self.TargetFfs)
+ TargetFv.insertChild(self.NewFfs)
+ TargetFv.Data.Free_Space = 0
+ ModifyFfsType(self.NewFfs)
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ # Encapsulate the Fv Data for update.
+ TargetFv.Data.Size += TargetLen
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ # Start free space calculating and moving process.
+ self.ModifyTest(TargetFv.Parent, TargetLen)
+ else:
+ # If TargetFv do not have free space, need directly move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs.
+ TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData)
+ TargetFv = self.TargetFfs.Parent
+ if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
+ self.NewFfs.Data.Header.State = c_uint8(
+ ~self.NewFfs.Data.Header.State)
+ if TargetFv.type == FV_TREE:
+ self.Status = False
+ elif TargetFv.type == SEC_FV_TREE:
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length
+ New_Add_Len = BlockSize - TargetLen%BlockSize
+ if New_Add_Len % BlockSize:
+ New_Free_Space = BIOSTREE('FREE_SPACE')
+ New_Free_Space.type = FFS_FREE_SPACE
+ New_Free_Space.Data = FreeSpaceNode(b'\xff' * New_Add_Len)
+ TargetLen += New_Add_Len
+ TargetFv.Data.Free_Space = New_Add_Len
+ TargetFv.insertChild(self.NewFfs)
+ TargetFv.insertChild(New_Free_Space)
+ else:
+ TargetFv.insertChild(self.NewFfs)
+ ModifyFfsType(self.NewFfs)
+ TargetFv.Data.Data = b''
+ for item in TargetFv.Child:
+ if item.type == FFS_FREE_SPACE:
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData
+ else:
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
+ TargetFv.Data.Size += TargetLen
+ TargetFv.Data.Header.FvLength = TargetFv.Data.Size
+ TargetFv.Data.ModFvExt()
+ TargetFv.Data.ModFvSize()
+ TargetFv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(TargetFv)
+ TargetFv.Data.ModCheckSum()
+ self.ModifyTest(TargetFv.Parent, TargetLen)
+ return self.Status
+
+ def DeleteFfs(self) -> bool:
+ Delete_Ffs = self.TargetFfs
+ Delete_Fv = Delete_Ffs.Parent
+ Add_Free_Space = Delete_Ffs.Data.Size + len(Delete_Ffs.Data.PadData)
+ if Delete_Fv.Data.Free_Space:
+ if Delete_Fv.type == SEC_FV_TREE:
+ Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
+ BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
+ New_Free_Space = BlockSize - Used_Size % BlockSize
+ self.Remain_New_Free_Space += Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
+ Delete_Fv.Child[-1].Data.Data = New_Free_Space * b'\xff'
+ Delete_Fv.Data.Free_Space = New_Free_Space
+ else:
+ Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
+ Delete_Fv.Child[-1].Data.Data += Add_Free_Space * b'\xff'
+ Delete_Fv.Data.Free_Space += Add_Free_Space
+ New_Free_Space = Delete_Fv.Data.Free_Space + Add_Free_Space
+ else:
+ if Delete_Fv.type == SEC_FV_TREE:
+ Used_Size = Delete_Fv.Data.Size - Add_Free_Space
+ BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
+ New_Free_Space = BlockSize - Used_Size % BlockSize
+ self.Remain_New_Free_Space += Add_Free_Space - New_Free_Space
+ Add_Free_Space = New_Free_Space
+ else:
+ Used_Size = Delete_Fv.Data.Size - Add_Free_Space
+ New_Free_Space = Add_Free_Space
+ New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
+ New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
+ New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
+ New_Ffs_Tree.type = FFS_FREE_SPACE
+ New_Ffs_Tree.Data = New_Free_Space_Info
+ Delete_Fv.insertChild(New_Ffs_Tree)
+ Delete_Fv.Data.Free_Space = Add_Free_Space
+ Delete_Fv.Child.remove(Delete_Ffs)
+ Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
+ Delete_Fv.Data.ModFvExt()
+ Delete_Fv.Data.ModFvSize()
+ Delete_Fv.Data.ModExtHeaderData()
+ self.ModifyFvExtData(Delete_Fv)
+ Delete_Fv.Data.ModCheckSum()
+ self.CompressData(Delete_Fv)
+ self.Status = True
+ return self.Status
diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py b/BaseTools/Source/Python/FMMT/core/GuidTools.py
new file mode 100644
index 000000000000..287b949cc32f
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
@@ -0,0 +1,152 @@
+## @file
+# This file is used to define the FMMT dependent external tool management class.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import glob
+import logging
+import os
+import shutil
+import sys
+import tempfile
+import uuid
+from PI.Common import *
+from utils.FmmtLogger import FmmtLogger as logger
+import subprocess
+
+def ExecuteCommand(cmd: list) -> None:
+ subprocess.run(cmd,stdout=subprocess.DEVNULL)
+
+class GUIDTool:
+ def __init__(self, guid: str, short_name: str, command: str) -> None:
+ self.guid: str = guid
+ self.short_name: str = short_name
+ self.command: str = command
+
+ def pack(self, buffer: bytes) -> bytes:
+ """
+ compress file.
+ """
+ tool = self.command
+ if tool:
+ tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
+ ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")
+ ToolOuputFile = os.path.join(tmp, "pack_sec_file")
+ try:
+ file = open(ToolInputFile, "wb")
+ file.write(buffer)
+ file.close()
+ command = [tool, '-e', '-o', ToolOuputFile,
+ ToolInputFile]
+ ExecuteCommand(command)
+ buf = open(ToolOuputFile, "rb")
+ res_buffer = buf.read()
+ except Exception as msg:
+ logger.error(msg)
+ return ""
+ else:
+ buf.close()
+ if os.path.exists(tmp):
+ shutil.rmtree(tmp)
+ return res_buffer
+ else:
+ logger.error(
+ "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
+ logger.info("Its GUID is: %s" % self.guid)
+ return ""
+
+
+ def unpack(self, buffer: bytes) -> bytes:
+ """
+ buffer: remove common header
+ uncompress file
+ """
+ tool = self.command
+ if tool:
+ tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
+ ToolInputFile = os.path.join(tmp, "unpack_sec_file")
+ ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")
+ try:
+ file = open(ToolInputFile, "wb")
+ file.write(buffer)
+ file.close()
+ command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]
+ ExecuteCommand(command)
+ buf = open(ToolOuputFile, "rb")
+ res_buffer = buf.read()
+ except Exception as msg:
+ logger.error(msg)
+ return ""
+ else:
+ buf.close()
+ if os.path.exists(tmp):
+ shutil.rmtree(tmp)
+ return res_buffer
+ else:
+ logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
+ logger.info("Its GUID is: %s" % self.guid)
+ return ""
+
+class GUIDTools:
+ '''
+ GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools.
+ '''
+ default_tools = {
+ struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", "TianoCompress"),
+ struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", "LzmaCompress"),
+ struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", "GenCrc32"),
+ struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", "LzmaF86Compress"),
+ struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", "BrotliCompress"),
+ }
+
+ def __init__(self, tooldef_file: str=None) -> None:
+ self.dir = os.path.dirname(__file__)
+ self.tooldef_file = tooldef_file if tooldef_file else os.path.join(
+ self.dir, "FMMTConfig.ini")
+ self.tooldef = dict()
+ self.load()
+
+ def VerifyTools(self) -> None:
+ """
+ Verify Tools and Update Tools path.
+ """
+ path_env = os.environ.get("PATH")
+ path_env_list = path_env.split(os.pathsep)
+ path_env_list.append(os.path.dirname(__file__))
+ path_env_list = list(set(path_env_list))
+ for tool in self.tooldef.values():
+ cmd = tool.command
+ if os.path.isabs(cmd):
+ if not os.path.exists(cmd):
+ print("Tool Not found %s" % cmd)
+ else:
+ for syspath in path_env_list:
+ if glob.glob(os.path.join(syspath, cmd+"*")):
+ break
+ else:
+ print("Tool Not found %s" % cmd)
+
+ def load(self) -> None:
+ if os.path.exists(self.tooldef_file):
+ with open(self.tooldef_file, "r") as fd:
+ config_data = fd.readlines()
+ for line in config_data:
+ try:
+ guid, short_name, command = line.split()
+ new_format_guid = struct2stream(ModifyGuidFormat(guid.strip()))
+ self.tooldef[new_format_guid] = GUIDTool(
+ guid.strip(), short_name.strip(), command.strip())
+ except:
+ print("GuidTool load error!")
+ continue
+ else:
+ self.tooldef.update(self.default_tools)
+
+ self.VerifyTools()
+
+ def __getitem__(self, guid) -> None:
+ return self.tooldef.get(guid)
+
+
+guidtools = GUIDTools()
diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
new file mode 100644
index 000000000000..5289fc27049a
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
@@ -0,0 +1,18 @@
+## @file
+# This file is used to define the Fmmt Logger.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+##
+
+import logging
+import sys
+
+FmmtLogger = logging.getLogger('FMMT')
+FmmtLogger.setLevel(logging.INFO)
+
+lh=logging.StreamHandler(sys.stdout)
+lf=logging.Formatter("%(levelname)-8s: %(message)s")
+lh.setFormatter(lf)
+FmmtLogger.addHandler(lh)
\ No newline at end of file
diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
new file mode 100644
index 000000000000..83a31aeea3fe
--- /dev/null
+++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
@@ -0,0 +1,54 @@
+## @file
+# This file is used to define the printer for Bios layout.
+#
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+def GetFormatter(layout_format: str):
+ if layout_format == 'json':
+ return JsonFormatter()
+ elif layout_format == 'yaml':
+ return YamlFormatter()
+ elif layout_format == 'html':
+ return HtmlFormatter()
+ else:
+ return TxtFormatter()
+
+class Formatter(object):
+ def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
+ raise NotImplemented
+
+class JsonFormatter(Formatter):
+ def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
+ try:
+ import json
+ except:
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
+ return
+ print(outputfile)
+ if outputfile:
+ with open(outputfile,"w") as fw:
+ json.dump(layoutdict, fw, indent=2)
+ else:
+ print(json.dumps(layoutdict,indent=2))
+
+class TxtFormatter(Formatter):
+ def LogPrint(self,layoutlist: list) -> None:
+ for item in layoutlist:
+ print(item)
+ print('\n')
+
+ def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
+ print(outputfile)
+ with open(outputfile, "w") as f:
+ for item in layoutlist:
+ f.writelines(item + '\n')
+
+class YamlFormatter(Formatter):
+ def dump(self,layoutdict, layoutlist, outputfile = None):
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
+
+class HtmlFormatter(Formatter):
+ def dump(self,layoutdict, layoutlist, outputfile = None):
+ TxtFormatter().dump(layoutdict, layoutlist, outputfile)
\ No newline at end of file
--
2.27.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
2021-11-09 0:09 Yuwei Chen
@ 2021-11-09 0:29 ` Michael D Kinney
2021-11-09 1:34 ` Yuwei Chen
0 siblings, 1 reply; 6+ messages in thread
From: Michael D Kinney @ 2021-11-09 0:29 UTC (permalink / raw)
To: devel@edk2.groups.io, Chen, Christine, Kinney, Michael D
Cc: Feng, Bob C, Liming Gao
Hi Christine,
Is this the same version of the sources that were submitted to the
edk2-basetools repo as the following PR?
https://github.com/tianocore/edk2-basetools/pull/11
The goal is to delete the sources from BaseTools/Source/Python and have all
edk2 developers use the python tools published by edk2-basetools project.
The edk2-basetools project also has more extensive CI checks for python sources
and we do not to accept source changes into BaseTools/Source/Python that do
not pass all the edk2-basetools CI checks.
Thanks,
Mike
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yuwei Chen
> Sent: Monday, November 8, 2021 4:09 PM
> To: devel@edk2.groups.io
> Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>
> Subject: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
>
> From: Bob Feng <bob.c.feng@intel.com>
>
> The FMMT python tool is used for firmware files operation, which has
> the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function.
> Currently the FMMT C tool is saved in edk2-staging repo, but its
> quality and coding style can't meet the Edk2 quality, which is hard to
> maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
> The new Python version keeps same functions with origin C version. It
> has higher quality and better coding style, and it is much easier to
> extend new functions and to maintain.
>
> RFC: https://edk2.groups.io/g/devel/message/82877
> Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
>
> Cc: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
> ---
> BaseTools/BinWrappers/PosixLike/FMMT | 14 +
> BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
> BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
> BaseTools/Source/Python/FMMT/FMMTConfig.ini | 5 +
> .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
> .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906 bytes
> BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
> .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++
> BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++
> .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++
> BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
> BaseTools/Source/Python/FMMT/README.md | 180 ++++++
> BaseTools/Source/Python/FMMT/__init__.py | 0
> .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
> BaseTools/Source/Python/FMMT/core/BiosTree.py | 199 +++++++
> .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
> .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
> .../Source/Python/FMMT/core/FMMTParser.py | 86 +++
> .../Source/Python/FMMT/core/FvHandler.py | 521 ++++++++++++++++++
> .../Source/Python/FMMT/core/GuidTools.py | 152 +++++
> .../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
> .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
> 22 files changed, 2427 insertions(+)
> create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
> create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
> create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
> create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
> create mode 100644 BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> create mode 100644 BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
> create mode 100644 BaseTools/Source/Python/FMMT/README.md
> create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/FMMTParser.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
> create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
> create mode 100644 BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> create mode 100644 BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
>
> diff --git a/BaseTools/BinWrappers/PosixLike/FMMT b/BaseTools/BinWrappers/PosixLike/FMMT
> new file mode 100644
> index 000000000000..5f5519e1e1b6
> --- /dev/null
> +++ b/BaseTools/BinWrappers/PosixLike/FMMT
> @@ -0,0 +1,14 @@
> +#!/usr/bin/env bash
> +#python `dirname $0`/RunToolFromSource.py `basename $0` $*
> +
> +# If a ${PYTHON_COMMAND} command is available, use it in preference to python
> +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
> + python_exe=${PYTHON_COMMAND}
> +fi
> +
> +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice
> here
> +dir=$(dirname "$full_cmd")
> +cmd=${full_cmd##*/}
> +
> +export PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
> +exec "${python_exe:-python}" -m $cmd.$cmd "$@"
> diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> new file mode 100644
> index 000000000000..259d6cd6ddea
> --- /dev/null
> +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> @@ -0,0 +1,4 @@
> +@setlocal
> +@set ToolName=%~n0%
> +@set PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%BASE_TOOLS_PATH%\Source\Python\FMMT
> +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
> diff --git a/BaseTools/Source/Python/FMMT/FMMT.py b/BaseTools/Source/Python/FMMT/FMMT.py
> new file mode 100644
> index 000000000000..1c41face7308
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/FMMT.py
> @@ -0,0 +1,117 @@
> +# @file
> +# Firmware Module Management Tool.
> +#
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +# Import Modules
> +#
> +import argparse
> +import sys
> +from core.FMMTOperation import *
> +
> +parser = argparse.ArgumentParser(description='''
> +View the Binary Structure of FD/FV/Ffs/Section, and Delete/Extract/Add/Replace a Ffs from/into a FV.
> +''')
> +parser.add_argument("--version", action="version", version='%(prog)s Version 1.0',
> + help="Print debug information.")
> +parser.add_argument("-v", "--View", dest="View", nargs='+',
> + help="View each FV and the named files within each FV: '-v inputfile outputfile,
> inputfiletype(.Fd/.Fv/.ffs/.sec)'")
> +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
> + help="Delete a Ffs from FV: '-d inputfile TargetFfsName outputfile TargetFvName(Optional,\
> + If not given, wil delete all the existed target Ffs)'")
> +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
> + help="Extract a Ffs Info: '-e inputfile TargetFfsName outputfile'")
> +parser.add_argument("-a", "--Add", dest="Add", nargs='+',
> + help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'")
> +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
> + help="Replace a Ffs in a FV: '-r inputfile TargetFfsName newffsfile outputfile
> TargetFvName(Optional,\
> + If not given, wil replace all the existed target Ffs with new Ffs file)'")
> +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
> + help="The format of log file which saves Binary layout. Currently supports: json, txt. More formats
> will be added in the future")
> +
> +def print_banner():
> + print("")
> +
> +class FMMT():
> + def __init__(self) -> None:
> + self.firmware_packet = {}
> +
> + def CheckFfsName(self, FfsName:str) -> str:
> + try:
> + return uuid.UUID(FfsName)
> + except:
> + return FfsName
> +
> + def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None) -> None:
> + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
> + filetype = os.path.splitext(inputfile)[1].lower()
> + if filetype == '.fd':
> + ROOT_TYPE = ROOT_TREE
> + elif filetype == '.fv':
> + ROOT_TYPE = ROOT_FV_TREE
> + elif filetype == '.ffs':
> + ROOT_TYPE = ROOT_FFS_TREE
> + elif filetype == '.sec':
> + ROOT_TYPE = ROOT_SECTION_TREE
> + else:
> + ROOT_TYPE = ROOT_TREE
> + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
> +
> + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
> + if Fv_name:
> + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile, uuid.UUID(Fv_name))
> + else:
> + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name), outputfile)
> +
> + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None:
> + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
> +
> + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
> + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile, outputfile)
> +
> + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
> + if Fv_name:
> + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile, uuid.UUID(Fv_name))
> + else:
> + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)
> +
> +
> +def main():
> + args=parser.parse_args()
> + status=0
> +
> + try:
> + fmmt=FMMT()
> + if args.View:
> + if args.LogFileType:
> + fmmt.View(args.View[0], args.LogFileType[0])
> + else:
> + fmmt.View(args.View[0])
> + if args.Delete:
> + if len(args.Delete) == 4:
> + fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
> + else:
> + fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
> + if args.Extract:
> + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
> + if args.Add:
> + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
> + if args.Replace:
> + if len(args.Replace) == 5:
> + fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3],args.Replace[4])
> + else:
> + fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])
> + # TODO:
> + '''Do the main work'''
> + except Exception as e:
> + print(e)
> +
> + return status
> +
> +
> +if __name__ == "__main__":
> + exit(main())
> diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> new file mode 100644
> index 000000000000..e4bf03c41f4e
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> @@ -0,0 +1,5 @@
> +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
> +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
> +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
> +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
> +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
> diff --git a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> new file mode 100644
> index 0000000000000000000000000000000000000000..7cc806a0133413a4aa037f1d43d80000546a5246
> GIT binary patch
> literal 29515
> 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
>
> literal 0
> HcmV?d00001
>
> diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> new file mode 100644
> index 0000000000000000000000000000000000000000..6335653ece1605cd0c53bd2cc2bc21d57d213dae
> GIT binary patch
> literal 79906
> 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
> RBat2OV|2<CTVmi8`9DHIo&o>>
>
> literal 0
> HcmV?d00001
>
> diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py b/BaseTools/Source/Python/FMMT/PI/Common.py
> new file mode 100644
> index 000000000000..683341094429
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/Common.py
> @@ -0,0 +1,81 @@
> +## @file
> +# This file is used to define the common C struct and functions.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from ctypes import *
> +import uuid
> +
> +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
> +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID('{8C8CE578-8A3D-4f1c-9935-896185C32DD3}')
> +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID('{5473C07A-3DCB-4dca-BD6F-1E9689E7349A}')
> +# EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID('{1BA0062E-C779-4582-8566-336AE8F78F09}')
> +
> +EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE = EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
> +EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE = b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
> +EFI_SYSTEM_NVDATA_FV_GUID = uuid.UUID("fff12b8d-7696-4c8b-a985-2747075b4f50")
> +EFI_SYSTEM_NVDATA_FV_GUID_BYTE = b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
> +EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID("1ba0062e-c779-4582-8566-336ae8f78f09")
> +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE = b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
> +ZEROVECTOR_BYTE = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
> +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
> +FVH_SIGNATURE = b'_FVH'
> +
> +class GUID(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Guid1', c_uint32),
> + ('Guid2', c_uint16),
> + ('Guid3', c_uint16),
> + ('Guid4', ARRAY(c_uint8, 8)),
> + ]
> +
> + def from_list(self, listformat: list) -> None:
> + self.Guid1 = listformat[0]
> + self.Guid2 = listformat[1]
> + self.Guid3 = listformat[2]
> + for i in range(8):
> + self.Guid4[i] = listformat[i+3]
> +
> + def __cmp__(self, otherguid) -> bool:
> + if not isinstance(otherguid, GUID):
> + return 'Input is not the GUID instance!'
> + rt = False
> + if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2 and self.Guid3 == otherguid.Guid3:
> + rt = True
> + for i in range(8):
> + rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
> + return rt
> +
> +def ModifyGuidFormat(target_guid: str) -> GUID:
> + target_guid = target_guid.replace('-', '')
> + target_list = []
> + start = [0,8,12,16,18,20,22,24,26,28,30]
> + end = [8,12,16,18,20,22,24,26,28,30,32]
> + num = len(start)
> + for pos in range(num):
> + new_value = int(target_guid[start[pos]:end[pos]], 16)
> + target_list.append(new_value)
> + new_format = GUID()
> + new_format.from_list(target_list)
> + return new_format
> +
> +
> +# Get data from ctypes to bytes.
> +def struct2stream(s) -> bytes:
> + length = sizeof(s)
> + p = cast(pointer(s), POINTER(c_char * length))
> + return p.contents.raw
> +
> +
> +
> +def GetPadSize(Size: int, alignment: int) -> int:
> + if Size % alignment == 0:
> + return 0
> + Pad_Size = alignment - Size % alignment
> + return Pad_Size
> diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> new file mode 100644
> index 000000000000..fb0100420ecc
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> @@ -0,0 +1,66 @@
> +## @file
> +# This file is used to define the Ffs Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +EFI_FFS_FILE_HEADER_LEN = 24
> +EFI_FFS_FILE_HEADER2_LEN = 32
> +
> +class CHECK_SUM(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Header', c_uint8),
> + ('File', c_uint8),
> + ]
> +
> +class EFI_FFS_INTEGRITY_CHECK(Union):
> + _pack_ = 1
> + _fields_ = [
> + ('Checksum', CHECK_SUM),
> + ('Checksum16', c_uint16),
> + ]
> +
> +
> +class EFI_FFS_FILE_HEADER(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Name', GUID),
> + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> + ('Type', c_uint8),
> + ('Attributes', c_uint8),
> + ('Size', ARRAY(c_uint8, 3)),
> + ('State', c_uint8),
> + ]
> +
> + @property
> + def FFS_FILE_SIZE(self) -> int:
> + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> +
> + @property
> + def HeaderLength(self) -> int:
> + return 24
> +
> +class EFI_FFS_FILE_HEADER2(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Name', GUID),
> + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> + ('Type', c_uint8),
> + ('Attributes', c_uint8),
> + ('Size', ARRAY(c_uint8, 3)),
> + ('State', c_uint8),
> + ('ExtendedSize', c_uint64),
> + ]
> +
> + @property
> + def FFS_FILE_SIZE(self) -> int:
> + return self.ExtendedSize
> +
> + @property
> + def HeaderLength(self) -> int:
> + return 32
> diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> new file mode 100644
> index 000000000000..51cb15ddac28
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> @@ -0,0 +1,112 @@
> +## @file
> +# This file is used to define the FV Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from ast import Str
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +class EFI_FV_BLOCK_MAP_ENTRY(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('NumBlocks', c_uint32),
> + ('Length', c_uint32),
> + ]
> +
> +
> +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> + _fields_ = [
> + ('ZeroVector', ARRAY(c_uint8, 16)),
> + ('FileSystemGuid', GUID),
> + ('FvLength', c_uint64),
> + ('Signature', c_uint32),
> + ('Attributes', c_uint32),
> + ('HeaderLength', c_uint16),
> + ('Checksum', c_uint16),
> + ('ExtHeaderOffset', c_uint16),
> + ('Reserved', c_uint8),
> + ('Revision', c_uint8),
> + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, 1)),
> + ]
> +
> +def Refine_FV_Header(nums):
> + class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> + _fields_ = [
> + ('ZeroVector', ARRAY(c_uint8, 16)),
> + ('FileSystemGuid', GUID),
> + ('FvLength', c_uint64),
> + ('Signature', c_uint32),
> + ('Attributes', c_uint32),
> + ('HeaderLength', c_uint16),
> + ('Checksum', c_uint16),
> + ('ExtHeaderOffset', c_uint16),
> + ('Reserved', c_uint8),
> + ('Revision', c_uint8),
> + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
> + ]
> + return EFI_FIRMWARE_VOLUME_HEADER
> +
> +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
> + _fields_ = [
> + ('FvName', GUID),
> + ('ExtHeaderSize', c_uint32)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
> + _fields_ = [
> + ('ExtEntrySize', c_uint16),
> + ('ExtEntryType', c_uint16)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32),
> + ('Types', ARRAY(GUID, 1))
> + ]
> +
> +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
> + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('TypeMask', c_uint32),
> + ('Types', ARRAY(GUID, nums))
> + ]
> + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID)
> + ]
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID),
> + ('Data', ARRAY(c_uint8, 1))
> + ]
> +
> +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) -> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
> + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('FormatType', GUID),
> + ('Data', ARRAY(c_uint8, nums))
> + ]
> + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
> +
> +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
> + _fields_ = [
> + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> + ('UsedSize', c_uint32)
> + ]
> diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> new file mode 100644
> index 000000000000..8c6229819a18
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> @@ -0,0 +1,110 @@
> +## @file
> +# This file is used to define the Section Header C Struct.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from struct import *
> +from ctypes import *
> +from PI.Common import *
> +
> +EFI_COMMON_SECTION_HEADER_LEN = 4
> +EFI_COMMON_SECTION_HEADER2_LEN = 8
> +
> +class EFI_COMMON_SECTION_HEADER(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Size', ARRAY(c_uint8, 3)),
> + ('Type', c_uint8),
> + ]
> +
> + @property
> + def SECTION_SIZE(self) -> int:
> + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> +
> + def Common_Header_Size(self) -> int:
> + return 4
> +
> +class EFI_COMMON_SECTION_HEADER2(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('Size', ARRAY(c_uint8, 3)),
> + ('Type', c_uint8),
> + ('ExtendedSize', c_uint32),
> + ]
> +
> + @property
> + def SECTION_SIZE(self) -> int:
> + return self.ExtendedSize
> +
> + def Common_Header_Size(self) -> int:
> + return 8
> +
> +class EFI_COMPRESSION_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('UncompressedLength', c_uint32),
> + ('CompressionType', c_uint8),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 5
> +
> +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('SubTypeGuid', GUID),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 16
> +
> +class EFI_GUID_DEFINED_SECTION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('SectionDefinitionGuid', GUID),
> + ('DataOffset', c_uint16),
> + ('Attributes', c_uint16),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 20
> +
> +def Get_USER_INTERFACE_Header(nums: int):
> + class EFI_SECTION_USER_INTERFACE(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('FileNameString', ARRAY(c_uint16, nums)),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 2 * nums
> +
> + def GetUiString(self) -> str:
> + UiString = ''
> + for i in range(nums):
> + if self.FileNameString[i]:
> + UiString += chr(self.FileNameString[i])
> + return UiString
> +
> + return EFI_SECTION_USER_INTERFACE
> +
> +def Get_VERSION_Header(nums: int):
> + class EFI_SECTION_VERSION(Structure):
> + _pack_ = 1
> + _fields_ = [
> + ('BuildNumber', c_uint16),
> + ('VersionString', ARRAY(c_uint16, nums)),
> + ]
> +
> + def ExtHeaderSize(self) -> int:
> + return 2 * (nums+1)
> +
> + def GetVersionString(self) -> str:
> + VersionString = ''
> + for i in range(nums):
> + if self.VersionString[i]:
> + VersionString += chr(self.VersionString[i])
> + return VersionString
> +
> + return EFI_SECTION_VERSION
> diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py b/BaseTools/Source/Python/FMMT/PI/__init__.py
> new file mode 100644
> index 000000000000..21cbd82effc5
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
> @@ -0,0 +1,6 @@
> +## @file
> +# This file is used to define the FMMT dependent external tool management class.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/README.md b/BaseTools/Source/Python/FMMT/README.md
> new file mode 100644
> index 000000000000..cfbc966a6af6
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/README.md
> @@ -0,0 +1,180 @@
> +# FMMT
> +## Overview
> +This FMMT tool is the python implementation of the edk2 FMMT tool which locates at https://github.com/tianocore/edk2-
> staging/tree/FceFmmt.
> +This implementation has the same usage as the edk2 FMMT, but it's more readable and relaiable.
> +
> +# FMMT User Guide
> +
> +#### Last updated October 13, 2021
> +
> +Important Changes and Updates:
> +
> +- Oct 13, 2021 Initial Draft of FMMT Python Tool
> +
> +#### Note:
> +
> +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is much easier to maintain and extend other functions.
> +
> +
> +
> +# 1. Introduction
> +
> +## 1.1 Overview
> +
> +The Firmware Device is a persistent physical repository that contains firmware code and/or data. The firmware code and/or
> data stored in Firmware Volumes. Detail layout of Firmware Volumes is described in “Figure 1. The Firmware Volume Format”.
> +
> +![](Img/FirmwareVolumeFormat.png)
> +
> + Figure 1. The Firmware
> Volume Format
> +
> +In firmware development, binary file has its firmware layout following the Platform-Initialization Specification. Thus,
> operation on FV file / FFS file (Firmware File) is an efficient and convenient way for firmware function testing and
> developing. FMMT Python tool is used for firmware files operation.
> +
> +## 1.2 Tool Capabilities
> +
> +The FMMT tool is capable of:
> +
> +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware Files)
> +
> +- Add a new FFS into a FV file (both included in a FD file or not)
> +
> +- Replace an FFS in a FV file with a new FFS file
> +
> +- Delete an FFS in a FV file (both included in a FD file or not)
> +
> +- Extract the FFS from a FV file (both included in a FD file or not)
> +
> +## 1.3 References
> +
> +| Document |
> +| ------------------------------------------------ |
> +| UEFI Platform Initialization (PI) Specification |
> +
> +
> +
> +# 2. FMMT Python Tool Usage
> +
> +## 2.1 Required Files
> +
> +### 2.1.1 Independent use
> +
> +When independent use the FMMT Python Tool, the following files and settings are required:
> +
> +- GuidTool executable files used for Decompress/Compress Firmware data.
> +
> +- Environment variables path with GuidTool path setting.
> +
> +### 2.1.2 Use with Build System
> +
> +When use the FMMT Python Tool with Build System:
> +
> +- If only use Edk2 based GuidTool, do not need other preparation.
> +
> +- If use other customized GuidTool, need prepare the config file with GuidTool info. The syntax for GuidTool definition
> shown as follow:
> +
> + ***ToolsGuid ShortName Command***
> +
> + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress***
> +
> +## 2.2 Syntax
> +
> +### 2.2.1 Syntax for Parse file
> +
> + ***-v < Inputfile > < Outputfile > -l < LogFileType >***
> +
> +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is optional, if inputs, the *Inputfile* will be
> encapsulated into *Outputfile* following the parsed firmware layout. *"-l LogFileType"* is optional, it decides the format
> of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future.
> +
> +### 2.2.2 Syntax for Add a new FFS
> +
> + ***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >***
> +
> +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* (Name or Guid) is the TargetFv which *NewFfsFile*
> will be added into.
> +
> +### 2.2.3 Syntax for Delete an FFS
> +
> + ***-d < Inputfile > < TargetFfsName > < Outputfile > < TargetFvName/TargetFvGuid >***
> +
> +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs which will be deleted.
> *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
> +
> +### 2.2.4 Syntax for Replace an FFS
> +
> + ***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile > < TargetFvName/TargetFvGuid >***
> +
> +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs which will be replaced.
> *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
> +
> +### 2.2.5 Syntax for Extract an FFS
> +
> + ***-e < Inputfile > < TargetFfsName > < Outputfile >***
> +
> +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs which will be extracted.
> +
> +
> +
> +# 3. FMMT Python Tool Design
> +
> +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each Node have its Data field, which saves the
> FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the parse/add/delete/replace/extract operations are based on the
> NodeTree (adjusting the layout and data).
> +
> +## 3.1 NodeTree
> +
> +A whole NodeTree saves all the Firmware info.
> +
> +- Parent & Child relationship figured out the Firmware layout.
> +
> +- Each Node have several fields. ‘Data’ field saves an FirmwareClass instance which contains all the data info of the
> info.
> +
> +### 3.1.1 NodeTree Format
> +
> +The NodeTree will be created with parse function. When parse a file, a Root Node will be initialized firstly. The Data
> split and Tree construction process is described with an FD file shown as ‘Figure 2. The NodeTree format’:
> +
> +- A Root Node is initialized.
> +
> +- Use the ‘FV Signature’ as FV key to split Whole FD Data. ‘FV0’, ‘FV1’, ‘FV2’… Node created.
> +
> +- After FV level Node created, use the ‘Ffs Data Size’ as FFS key to split each FV Data. ‘Ffs0’...Node created.
> +
> +- After FFS level Node created, use the ‘Section Data Size’ as Section key to split each Ffs Data. ‘Section0’...Node
> created.
> +
> +- If some of Section includes other Sections, continue use the ‘Section Data Size’ as Section key to split each Section
> Data.
> +
> +- After all Node created, the whole NodeTree saves all the info. (Can be used in other functions or print the whole
> firmware layout into log file)
> +
> +![](Img/NodeTreeFormat.png)
> +
> +
> Figure 2. The NodeTree format
> +
> +### 3.1.2 Node Factory and Product
> +
> +As 3.1.1, Each Node is created by data split and recognition. To extend the NodeTree usage, Factory pattern is used in
> Node created process.
> +
> +Each Node have its Factory to create Product and use Product ParserData function to deal with the data.
> +
> +## 3.2 GuidTool
> +
> +There are two ways to set the GuidTool. One from Config file, another from environment variables.
> +
> +Current GuidTool first check if has Config file.
> +
> +- If have, load the config GuidTool Information.
> +
> +- Else get from environment variables.
> +
> +### 3.2.1 Get from Config file
> +
> +- Config file should in same folder with FMMT.py or the path in environment variables.
> +
> +- Content should follow the format:
> +
> + ***ToolsGuid ShortName Command***
> +
> +### 3.2.2 Get from Environment Variables
> +
> +- The GuidTool Command used must be set in environment variables.
> +
> +### 3.2.3 Edk2 Based GuidTool
> +
> +| ***Guid*** | ***ShortName*** | ***Command*** |
> +| ------------------------------------------ | --------------- | --------------------- |
> +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** | ***TianoCompress*** |
> +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** | ***LzmaCompress*** |
> +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** | ***GenCrc32*** |
> +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** | ***LzmaF86Compress*** |
> +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** | ***BrotliCompress*** |
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/__init__.py b/BaseTools/Source/Python/FMMT/__init__.py
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> new file mode 100644
> index 000000000000..afc0a90bd0cd
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> @@ -0,0 +1,371 @@
> +## @file
> +# This file is used to implement of the various bianry parser.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from re import T
> +import copy
> +import os
> +from PI.Common import *
> +from core.BiosTreeNode import *
> +from core.BiosTree import *
> +from core.GuidTools import *
> +
> +ROOT_TREE = 'ROOT'
> +ROOT_FV_TREE = 'ROOT_FV_TREE'
> +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> +
> +FV_TREE = 'FV'
> +DATA_FV_TREE = 'DATA_FV'
> +FFS_TREE = 'FFS'
> +FFS_PAD = 'FFS_PAD'
> +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> +SECTION_TREE = 'SECTION'
> +SEC_FV_TREE = 'SEC_FV_IMAGE'
> +BINARY_DATA = 'BINARY'
> +Fv_count = 0
> +
> +## Abstract factory
> +class BinaryFactory():
> + type:list = []
> +
> + def Create_Product():
> + pass
> +
> +class BinaryProduct():
> + ## Use GuidTool to decompress data.
> + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
> + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
> + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> + guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> + DecompressedData = guidtool.unpack(Section_Data)
> + return DecompressedData
> +
> + def ParserData():
> + pass
> +
> +class SectionFactory(BinaryFactory):
> + type = [SECTION_TREE]
> +
> + def Create_Product():
> + return SectionProduct()
> +
> +class FfsFactory(BinaryFactory):
> + type = [ROOT_SECTION_TREE, FFS_TREE]
> +
> + def Create_Product():
> + return FfsProduct()
> +
> +class FvFactory(BinaryFactory):
> + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
> +
> + def Create_Product():
> + return FvProduct()
> +
> +class FdFactory(BinaryFactory):
> + type = [ROOT_FV_TREE, ROOT_TREE]
> +
> + def Create_Product():
> + return FdProduct()
> +
> +class SectionProduct(BinaryProduct):
> + ## Decompress the compressed section.
> + def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
> + if Section_Tree.Data.Type == 0x01:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + self.ParserFfs(Section_Tree, b'')
> + # Guided Define Section
> + elif Section_Tree.Data.Type == 0x02:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + DeCompressGuidTool = Section_Tree.Data.ExtHeader.SectionDefinitionGuid
> + Section_Tree.Data.Data = self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
> + Section_Tree.Data.Size = len(Section_Tree.Data.Data) + Section_Tree.Data.HeaderLength
> + self.ParserFfs(Section_Tree, b'')
> + elif Section_Tree.Data.Type == 0x03:
> + Section_Tree.Data.OriData = Section_Tree.Data.Data
> + self.ParserFfs(Section_Tree, b'')
> + # SEC_FV Section
> + elif Section_Tree.Data.Type == 0x17:
> + global Fv_count
> + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
> + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
> + Sec_Fv_Tree.type = SEC_FV_TREE
> + Sec_Fv_Tree.Data = Sec_Fv_Info
> + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
> + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset + Sec_Fv_Tree.Data.Header.HeaderLength
> + Sec_Fv_Tree.Data.Data = Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
> + Section_Tree.insertChild(Sec_Fv_Tree)
> + Fv_count += 1
> +
> + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
> + Rel_Offset = 0
> + Section_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Section_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Section recorded in its Parent Section.
> + while Rel_Offset < Data_Size:
> + # Create a SectionNode and set it as the SectionTree's Data
> + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> + Section_Tree = BIOSTREE(Section_Info.Name)
> + Section_Tree.type = SECTION_TREE
> + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
> + Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
> + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> + Section_Info.ROffset = Rel_Offset
> + if Section_Info.Header.Type == 0:
> + break
> + # The final Section in parent Section does not need to add padding, else must be 4-bytes align with parent
> Section start offset
> + Pad_Size = 0
> + if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
> + Pad_Size = GetPadSize(Section_Info.Size, 4)
> + Section_Info.PadData = Pad_Size * b'\x00'
> + if Section_Info.Header.Type == 0x02:
> + Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> Rel_Offset+Section_Info.Size]
> + if Section_Info.Header.Type == 0x14:
> + ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
> + if Section_Info.Header.Type == 0x15:
> + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
> + Section_Offset += Section_Info.Size + Pad_Size
> + Rel_Offset += Section_Info.Size + Pad_Size
> + Section_Tree.Data = Section_Info
> + ParTree.insertChild(Section_Tree)
> +
> +class FfsProduct(BinaryProduct):
> + # ParserFFs / GetSection
> + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
> + Rel_Offset = 0
> + Section_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Section_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Section recorded in Ffs.
> + while Rel_Offset < Data_Size:
> + # Create a SectionNode and set it as the SectionTree's Data
> + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> + Section_Tree = BIOSTREE(Section_Info.Name)
> + Section_Tree.type = SECTION_TREE
> + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.HeaderLength: Rel_Offset+Section_Info.Size]
> + Section_Info.DOffset = Section_Offset + Section_Info.HeaderLength + Rel_Whole_Offset
> + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> + Section_Info.ROffset = Rel_Offset
> + if Section_Info.Header.Type == 0:
> + break
> + # The final Section in Ffs does not need to add padding, else must be 4-bytes align with Ffs start offset
> + Pad_Size = 0
> + if (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) != Data_Size):
> + Pad_Size = GetPadSize(Section_Info.Size, 4)
> + Section_Info.PadData = Pad_Size * b'\x00'
> + if Section_Info.Header.Type == 0x02:
> + Section_Info.DOffset = Section_Offset + Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> + Section_Info.Data = Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> Rel_Offset+Section_Info.Size]
> + # If Section is Version or UI type, it saves the version and UI info of its parent Ffs.
> + if Section_Info.Header.Type == 0x14:
> + ParTree.Data.Version = Section_Info.ExtHeader.GetVersionString()
> + if Section_Info.Header.Type == 0x15:
> + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
> + Section_Offset += Section_Info.Size + Pad_Size
> + Rel_Offset += Section_Info.Size + Pad_Size
> + Section_Tree.Data = Section_Info
> + ParTree.insertChild(Section_Tree)
> +
> +class FvProduct(BinaryProduct):
> + ## ParserFv / GetFfs
> + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
> + Ffs_Offset = 0
> + Rel_Offset = 0
> + # Get the Data from parent tree, if do not have the tree then get it from the whole_data.
> + if ParTree.Data != None:
> + Data_Size = len(ParTree.Data.Data)
> + Ffs_Offset = ParTree.Data.DOffset
> + Whole_Data = ParTree.Data.Data
> + else:
> + Data_Size = len(Whole_Data)
> + # Parser all the data to collect all the Ffs recorded in Fv.
> + while Rel_Offset < Data_Size:
> + # Create a FfsNode and set it as the FFsTree's Data
> + if Data_Size - Rel_Offset < 24:
> + Ffs_Tree = BIOSTREE('Free_Space')
> + Ffs_Tree.type = FFS_FREE_SPACE
> + Ffs_Tree.Data = FreeSpaceNode(Whole_Data[Rel_Offset:])
> + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
> + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
> + ParTree.Data.Free_Space = Data_Size - Rel_Offset
> + ParTree.insertChild(Ffs_Tree)
> + Rel_Offset = Data_Size
> + else:
> + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
> + Ffs_Tree = BIOSTREE(Ffs_Info.Name)
> + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
> + Ffs_Info.DOffset = Ffs_Offset + Ffs_Info.Header.HeaderLength + Rel_Whole_Offset
> + Ffs_Info.ROffset = Rel_Offset
> + if Ffs_Info.Name == PADVECTOR:
> + Ffs_Tree.type = FFS_PAD
> + Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
> + Ffs_Info.Size = len(Ffs_Info.Data) + Ffs_Info.Header.HeaderLength
> + # if current Ffs is the final ffs of Fv and full of b'\xff', define it with Free_Space
> + if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') == b'':
> + Ffs_Tree.type = FFS_FREE_SPACE
> + Ffs_Info.Data = Whole_Data[Rel_Offset:]
> + Ffs_Info.Size = len(Ffs_Info.Data)
> + ParTree.Data.Free_Space = Ffs_Info.Size
> + else:
> + Ffs_Tree.type = FFS_TREE
> + Ffs_Info.Data = Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength: Rel_Offset+Ffs_Info.Size]
> + # The final Ffs in Fv does not need to add padding, else must be 8-bytes align with Fv start offset
> + Pad_Size = 0
> + if Ffs_Tree.type != FFS_FREE_SPACE and (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) !=
> Data_Size):
> + Pad_Size = GetPadSize(Ffs_Info.Size, 8)
> + Ffs_Info.PadData = Pad_Size * b'\xff'
> + Ffs_Offset += Ffs_Info.Size + Pad_Size
> + Rel_Offset += Ffs_Info.Size + Pad_Size
> + Ffs_Tree.Data = Ffs_Info
> + ParTree.insertChild(Ffs_Tree)
> +
> +class FdProduct(BinaryProduct):
> + type = [ROOT_FV_TREE, ROOT_TREE]
> +
> + ## Create DataTree with first level /fv Info, then parser each Fv.
> + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0) -> None:
> + # Get all Fv image in Fd with offset and length
> + Fd_Struct = self.GetFvFromFd(whole_data)
> + data_size = len(whole_data)
> + Binary_count = 0
> + global Fv_count
> + # If the first Fv image is the Binary Fv, add it into the tree.
> + if Fd_Struct[0][1] != 0:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset = 0 + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> + # Add the first collected Fv image into the tree.
> + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
> + Cur_node.type = Fd_Struct[0][0]
> + Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
> + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
> + Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> + Cur_node.Data.Data =
> whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[0][1]+Cur_node.Data.Size]
> + WholeFvTree.insertChild(Cur_node)
> + Fv_count += 1
> + Fv_num = len(Fd_Struct)
> + # Add all the collected Fv image and the Binary Fv image between them into the tree.
> + for i in range(Fv_num-1):
> + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data = whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset = Fd_Struct[i][1]+Fd_Struct[i][2][0] + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
> + Cur_node.type = Fd_Struct[i+1][0]
> + Cur_node.Data = FvNode(Fv_count, whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
> + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
> + Cur_node.Data.DOffset = Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> + Cur_node.Data.Data =
> whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Struct[i+1][1]+Cur_node.Data.Size]
> + WholeFvTree.insertChild(Cur_node)
> + Fv_count += 1
> + # If the final Fv image is the Binary Fv, add it into the tree
> + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
> + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> + Binary_node.type = BINARY_DATA
> + Binary_node.Data = BinaryNode(str(Binary_count))
> + Binary_node.Data.Data = whole_data[Fd_Struct[-1][1]+Fd_Struct[-1][2][0]:]
> + Binary_node.Data.Size = len(Binary_node.Data.Data)
> + Binary_node.Data.HOffset = Fd_Struct[-1][1]+Fd_Struct[-1][2][0] + offset
> + WholeFvTree.insertChild(Binary_node)
> + Binary_count += 1
> +
> + ## Get the first level Fv from Fd file.
> + def GetFvFromFd(self, whole_data: bytes=b'') -> list:
> + Fd_Struct = []
> + data_size = len(whole_data)
> + cur_index = 0
> + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV image offset and length.
> + while cur_index < data_size:
> + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in whole_data[cur_index:]:
> + target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE) + cur_index
> + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-
> 16:target_index] == ZEROVECTOR_BYTE:
> + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q",
> whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + cur_index = 0
> + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV image offset and length.
> + while cur_index < data_size:
> + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in whole_data[cur_index:]:
> + target_index = whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE) + cur_index
> + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-
> 16:target_index] == ZEROVECTOR_BYTE:
> + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q",
> whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + cur_index = 0
> + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image offset and length.
> + while cur_index < data_size:
> + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in whole_data[cur_index:]:
> + target_index = whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) + cur_index
> + if whole_data[target_index+24:target_index+28] == FVH_SIGNATURE and whole_data[target_index-
> 16:target_index] == ZEROVECTOR_BYTE:
> + Fd_Struct.append([DATA_FV_TREE, target_index - 16, unpack("Q",
> whole_data[target_index+16:target_index+24])])
> + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> + else:
> + cur_index = target_index + 16
> + else:
> + cur_index = data_size
> + # Sort all the collect Fv image with offset.
> + Fd_Struct.sort(key=lambda x:x[1])
> + tmp_struct = copy.deepcopy(Fd_Struct)
> + tmp_index = 0
> + Fv_num = len(Fd_Struct)
> + # Remove the Fv image included in another Fv image.
> + for i in range(1,Fv_num):
> + if tmp_struct[i][1]+tmp_struct[i][2][0] < tmp_struct[i-1][1]+tmp_struct[i-1][2][0]:
> + Fd_Struct.remove(Fd_Struct[i-tmp_index])
> + tmp_index += 1
> + return Fd_Struct
> +
> +class ParserEntry():
> + FactoryTable:dict = {
> + SECTION_TREE: SectionFactory,
> + ROOT_SECTION_TREE: FfsFactory,
> + FFS_TREE: FfsFactory,
> + ROOT_FFS_TREE: FvFactory,
> + FV_TREE: FvFactory,
> + SEC_FV_TREE: FvFactory,
> + ROOT_FV_TREE: FdFactory,
> + ROOT_TREE: FdFactory,
> + }
> +
> + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
> + if Tree_type in self.FactoryTable:
> + return self.FactoryTable[Tree_type]
> +
> + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data: bytes, Offset: int) -> None:
> + New_Product = TargetFactory.Create_Product()
> + New_Product.ParserData(Tree, Data, Offset)
> +
> + def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
> + TargetFactory = self.GetTargetFactory(Tree.type)
> + if TargetFactory:
> + self.Generate_Product(TargetFactory, Tree, Data, Offset)
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> new file mode 100644
> index 000000000000..b2cdb49f9f3f
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> @@ -0,0 +1,199 @@
> +## @file
> +# This file is used to define the Bios layout tree structure and related operations.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import collections
> +from typing import OrderedDict
> +from PI.Common import *
> +
> +ROOT_TREE = 'ROOT'
> +ROOT_FV_TREE = 'ROOT_FV_TREE'
> +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> +
> +FV_TREE = 'FV'
> +DATA_FV_TREE = 'DATA_FV'
> +FFS_TREE = 'FFS'
> +FFS_PAD = 'FFS_PAD'
> +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> +SECTION_TREE = 'SECTION'
> +SEC_FV_TREE = 'SEC_FV_IMAGE'
> +BINARY_DATA = 'BINARY'
> +
> +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE]
> +FvType = [FV_TREE, SEC_FV_TREE]
> +FfsType = FFS_TREE
> +SecType = SECTION_TREE
> +
> +class BIOSTREE:
> + def __init__(self, NodeName: str) -> None:
> + self.key = NodeName
> + self.type = None
> + self.Data = None
> + self.Child = []
> + self.Findlist = []
> + self.Parent = None
> + self.NextRel = None
> + self.LastRel = None
> +
> + def HasChild(self) -> bool:
> + if self.Child == []:
> + return False
> + else:
> + return True
> +
> + def isFinalChild(self) -> bool:
> + ParTree = self.Parent
> + if ParTree:
> + if ParTree.Child[-1] == self:
> + return True
> + return False
> +
> + # FvTree.insertChild()
> + def insertChild(self, newNode, pos: int=None) -> None:
> + if len(self.Child) == 0:
> + self.Child.append(newNode)
> + else:
> + if not pos:
> + LastTree = self.Child[-1]
> + self.Child.append(newNode)
> + LastTree.NextRel = newNode
> + newNode.LastRel = LastTree
> + else:
> + newNode.NextRel = self.Child[pos-1].NextRel
> + newNode.LastRel = self.Child[pos].LastRel
> + self.Child[pos-1].NextRel = newNode
> + self.Child[pos].LastRel = newNode
> + self.Child.insert(pos, newNode)
> + newNode.Parent = self
> +
> + # lastNode.insertRel(newNode)
> + def insertRel(self, newNode) -> None:
> + if self.Parent:
> + parentTree = self.Parent
> + new_index = parentTree.Child.index(self) + 1
> + parentTree.Child.insert(new_index, newNode)
> + self.NextRel = newNode
> + newNode.LastRel = self
> +
> + def deleteNode(self, deletekey: str) -> None:
> + FindStatus, DeleteTree = self.FindNode(deletekey)
> + if FindStatus:
> + parentTree = DeleteTree.Parent
> + lastTree = DeleteTree.LastRel
> + nextTree = DeleteTree.NextRel
> + if parentTree:
> + index = parentTree.Child.index(DeleteTree)
> + del parentTree.Child[index]
> + if lastTree and nextTree:
> + lastTree.NextRel = nextTree
> + nextTree.LastRel = lastTree
> + elif lastTree:
> + lastTree.NextRel = None
> + elif nextTree:
> + nextTree.LastRel = None
> + return DeleteTree
> + else:
> + print('Could not find the target tree')
> + return None
> +
> + def FindNode(self, key: str, Findlist: list) -> None:
> + if self.key == key or (self.Data and self.Data.Name == key) or (self.type == FFS_TREE and self.Data.UiName ==
> key):
> + Findlist.append(self)
> + else:
> + for item in self.Child:
> + item.FindNode(key, Findlist)
> +
> + def GetTreePath(self):
> + BiosTreePath = [self]
> + while self.Parent:
> + BiosTreePath.insert(0, self.Parent)
> + self = self.Parent
> + return BiosTreePath
> +
> + def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0) -> None:
> + Key = list(TargetDict.keys())[0]
> + if TargetDict[Key]["Type"] in RootType:
> + Info.append("Image File: {}".format(Key))
> + Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum')))
> + Info.append("\n")
> + elif TargetDict[Key]["Type"] in FvType:
> + space += 2
> + if TargetDict[Key]["Type"] == SEC_FV_TREE:
> + Info.append("{}Child FV named {} of {}".format(space*" ", Key, self.FvId))
> + space += 2
> + else:
> + Info.append("FvId: {}".format(Key))
> + self.FvId = Key
> + Info.append("{}FvNameGuid: {}".format(space*" ", TargetDict.get(Key).get('FvNameGuid')))
> + Info.append("{}Attributes: {}".format(space*" ", TargetDict.get(Key).get('Attributes')))
> + Info.append("{}Total Volume Size: {}".format(space*" ", TargetDict.get(Key).get('Size')))
> + Info.append("{}Free Volume Size: {}".format(space*" ", TargetDict.get(Key).get('FreeSize')))
> + Info.append("{}Volume Offset: {}".format(space*" ", TargetDict.get(Key).get('Offset')))
> + Info.append("{}FilesNum: {}".format(space*" ", TargetDict.get(Key).get('FilesNum')))
> + elif TargetDict[Key]["Type"] in FfsType:
> + space += 2
> + if TargetDict.get(Key).get('UiName') != "b''":
> + Info.append("{}File: {} / {}".format(space*" ", Key, TargetDict.get(Key).get('UiName')))
> + else:
> + Info.append("{}File: {}".format(space*" ", Key))
> + if "Files" in list(TargetDict[Key].keys()):
> + for item in TargetDict[Key]["Files"]:
> + self.parserTree(item, Info, space)
> +
> + def ExportTree(self,TreeInfo: dict=None) -> dict:
> + if TreeInfo is None:
> + TreeInfo =collections.OrderedDict()
> +
> + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type ==
> ROOT_SECTION_TREE:
> + key = str(self.key)
> + TreeInfo[self.key] = collections.OrderedDict()
> + TreeInfo[self.key]["Name"] = key
> + TreeInfo[self.key]["Type"] = self.type
> + TreeInfo[self.key]["FilesNum"] = len(self.Child)
> + elif self.type == FV_TREE or self.type == SEC_FV_TREE:
> + key = str(self.Data.FvId)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + if self.Data.FvId != self.Data.Name:
> + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes)
> + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
> + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self.type == FFS_TREE:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
> + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self.type == SECTION_TREE and self.Data.Type == 0x02:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) + self.Data.HeaderLength)
> + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> + elif self is not None:
> + key = str(self.Data.Name)
> + TreeInfo[key] = collections.OrderedDict()
> + TreeInfo[key]["Name"] = key
> + TreeInfo[key]["Type"] = self.type
> + TreeInfo[key]["Size"] = hex(self.Data.Size)
> + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> + TreeInfo[key]["FilesNum"] = len(self.Child)
> +
> + for item in self.Child:
> + TreeInfo[key].setdefault('Files',[]).append( item.ExportTree())
> +
> + return TreeInfo
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> new file mode 100644
> index 000000000000..b77d9100e7b3
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> @@ -0,0 +1,191 @@
> +## @file
> +# This file is used to define the BIOS Tree Node.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from PI.FvHeader import *
> +from PI.FfsFileHeader import *
> +from PI.SectionHeader import *
> +from PI.Common import *
> +import uuid
> +
> +SectionHeaderType = {
> + 0x01:'EFI_COMPRESSION_SECTION',
> + 0x02:'EFI_GUID_DEFINED_SECTION',
> + 0x03:'EFI_SECTION_DISPOSABLE',
> + 0x10:'EFI_SECTION_PE32',
> + 0x11:'EFI_SECTION_PIC',
> + 0x12:'EFI_SECTION_TE',
> + 0x13:'EFI_SECTION_DXE_DEPEX',
> + 0x14:'EFI_SECTION_VERSION',
> + 0x15:'EFI_SECTION_USER_INTERFACE',
> + 0x16:'EFI_SECTION_COMPATIBILITY16',
> + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
> + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
> + 0x19:'EFI_SECTION_RAW',
> + 0x1B:'EFI_SECTION_PEI_DEPEX',
> + 0x1C:'EFI_SECTION_MM_DEPEX'
> +}
> +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
> +
> +class BinaryNode:
> + def __init__(self, name: str) -> None:
> + self.Size = 0
> + self.Name = "BINARY" + str(name)
> + self.HOffset = 0
> + self.Data = b''
> +
> +class FvNode:
> + def __init__(self, name, buffer: bytes) -> None:
> + self.Header = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
> + Map_num = (self.Header.HeaderLength - 56)//8
> + self.Header = Refine_FV_Header(Map_num).from_buffer_copy(buffer)
> + self.FvId = "FV" + str(name)
> + self.Name = "FV" + str(name)
> + if self.Header.ExtHeaderOffset:
> + self.ExtHeader = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Header.ExtHeaderOffset:])
> + self.Name = uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
> + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
> + if self.ExtHeader.ExtHeaderSize != 20:
> + self.ExtEntryExist = 1
> + self.ExtEntry = EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEntryOffset:])
> + self.ExtTypeExist = 1
> + if self.ExtEntry.ExtEntryType == 0x01:
> + nums = (self.ExtEntry.ExtEntrySize - 8) // 16
> + self.ExtEntry =
> Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
> + elif self.ExtEntry.ExtEntryType == 0x02:
> + nums = self.ExtEntry.ExtEntrySize - 20
> + self.ExtEntry =
> Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buffer[self.ExtEntryOffset:])
> + elif self.ExtEntry.ExtEntryType == 0x03:
> + self.ExtEntry =
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(buffer[self.ExtEntryOffset:])
> + else:
> + self.ExtTypeExist = 0
> + else:
> + self.ExtEntryExist = 0
> + self.Size = self.Header.FvLength
> + self.HeaderLength = self.Header.HeaderLength
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + if self.Header.Signature != 1213613663:
> + print('Invalid! Fv Header Signature {} is not "_FVH".'.format(self.Header.Signature))
> + with open(str(self.Name)+'.fd', "wb") as f:
> + f.write(struct2stream(self.Header))
> + assert False
> + self.PadData = b''
> + self.Free_Space = 0
> + self.ModCheckSum()
> +
> + def ModCheckSum(self) -> None:
> + # Fv Header Sums to 0.
> + Header = struct2stream(self.Header)[::-1]
> + Size = self.HeaderLength // 2
> + Sum = 0
> + for i in range(Size):
> + Sum += int(Header[i*2: i*2 + 2].hex(), 16)
> + if Sum & 0xffff:
> + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum - self.Header.Checksum)[-4:], 16)), 16)
> +
> + def ModFvExt(self) -> None:
> + # If used space changes and self.ExtEntry.UsedSize exists, self.ExtEntry.UsedSize need to be changed.
> + if self.Header.ExtHeaderOffset and self.ExtEntryExist and self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType ==
> 0x03:
> + self.ExtEntry.UsedSize = self.Header.FvLength - self.Free_Space
> +
> + def ModFvSize(self) -> None:
> + # If Fv Size changed, self.Header.FvLength and self.Header.BlockMap[i].NumBlocks need to be changed.
> + BlockMapNum = len(self.Header.BlockMap)
> + for i in range(BlockMapNum):
> + if self.Header.BlockMap[i].Length:
> + self.Header.BlockMap[i].NumBlocks = self.Header.FvLength // self.Header.BlockMap[i].Length
> +
> + def ModExtHeaderData(self) -> None:
> + if self.Header.ExtHeaderOffset:
> + ExtHeaderData = struct2stream(self.ExtHeader)
> + ExtHeaderDataOffset = self.Header.ExtHeaderOffset - self.HeaderLength
> + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData + self.Data[ExtHeaderDataOffset+20:]
> + if self.Header.ExtHeaderOffset and self.ExtEntryExist:
> + ExtHeaderEntryData = struct2stream(self.ExtEntry)
> + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + 20 - self.HeaderLength
> + self.Data = self.Data[:ExtHeaderEntryDataOffset] + ExtHeaderEntryData +
> self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
> +
> +class FfsNode:
> + def __init__(self, buffer: bytes) -> None:
> + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
> + # self.Attributes = unpack("<B", buffer[21:22])[0]
> + if self.Header.Size != 0 and self.Header.Attributes == 0x01:
> + print('Error Ffs Header! Ffs Header Size and Attributes is not matched!')
> + if self.Header.Size == 0 and self.Header.Attributes == 0x01:
> + self.Header = EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
> + self.Name = uuid.UUID(bytes_le=struct2stream(self.Header.Name))
> + self.UiName = b''
> + self.Version = b''
> + self.Size = self.Header.FFS_FILE_SIZE
> + self.HeaderLength = self.Header.HeaderLength
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + self.PadData = b''
> +
> + def ModCheckSum(self) -> None:
> + HeaderData = struct2stream(self.Header)
> + HeaderSum = 0
> + for item in HeaderData:
> + HeaderSum += item
> + HeaderSum -= self.Header.State
> + HeaderSum -= self.Header.IntegrityCheck.Checksum.File
> + if HeaderSum & 0xff:
> + Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 - int(hex(HeaderSum)[-2:], 16)
> + self.Header.IntegrityCheck.Checksum.Header = int(hex(Header)[-2:], 16)
> +
> +class SectionNode:
> + def __init__(self, buffer: bytes) -> None:
> + if buffer[0:3] != b'\xff\xff\xff':
> + self.Header = EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
> + else:
> + self.Header = EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
> + if self.Header.Type in SectionHeaderType:
> + self.Name = SectionHeaderType[self.Header.Type]
> + elif self.Header.Type == 0:
> + self.Name = "EFI_SECTION_RAW"
> + else:
> + self.Name = "SECTION"
> + if self.Header.Type in HeaderType:
> + self.ExtHeader = self.GetExtHeader(self.Header.Type, buffer[self.Header.Common_Header_Size():],
> (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
> + self.HeaderLength = self.Header.Common_Header_Size() + self.ExtHeader.ExtHeaderSize()
> + else:
> + self.ExtHeader = None
> + self.HeaderLength = self.Header.Common_Header_Size()
> + self.Size = self.Header.SECTION_SIZE
> + self.Type = self.Header.Type
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.Data = b''
> + self.OriData = b''
> + self.OriHeader = b''
> + self.PadData = b''
> +
> + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None:
> + if Type == 0x01:
> + return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
> + elif Type == 0x02:
> + return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
> + elif Type == 0x14:
> + return Get_VERSION_Header((nums - 2)//2).from_buffer_copy(buffer)
> + elif Type == 0x15:
> + return Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
> + elif Type == 0x18:
> + return EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
> +
> +class FreeSpaceNode:
> + def __init__(self, buffer: bytes) -> None:
> + self.Name = 'Free_Space'
> + self.Data = buffer
> + self.Size = len(buffer)
> + self.HOffset = 0
> + self.DOffset = 0
> + self.ROffset = 0
> + self.PadData = b''
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> new file mode 100644
> index 000000000000..e42565965909
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> @@ -0,0 +1,140 @@
> +## @file
> +# This file is used to define the functions to operate bios binary file.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from core.FMMTParser import *
> +from core.FvHandler import *
> +from utils.FvLayoutPrint import *
> +
> +global Fv_count
> +Fv_count = 0
> +
> +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE'
> +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile: str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # 3. Log Output
> + InfoDict = FmmtParser.WholeFvTree.ExportTree()
> + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
> + GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
> + if logfile:
> + GetFormatter(logfile.lower()).dump(InfoDict,
> FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfile),".{}".format(logfile.lower())))
> + # 4. Data Encapsultion
> + if outputfile:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # 3. Data Modify
> + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist)
> + # Choose the Specfic DeleteFfs with Fv info
> + if Fv_name:
> + for item in FmmtParser.WholeFvTree.Findlist:
> + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
> + FmmtParser.WholeFvTree.Findlist.remove(item)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
> + FfsMod = FvHandler(None, Delete_Ffs)
> + Status = FfsMod.DeleteFfs()
> + else:
> + print('Target Ffs not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + # Get Target Fv and Target Ffs_Pad
> + FmmtParser.WholeFvTree.FindNode(Fv_name, FmmtParser.WholeFvTree.Findlist)
> + # Create new ffs Tree
> + with open(newffsfile, "rb") as f:
> + new_ffs_data = f.read()
> + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
> + Status = False
> + # 3. Data Modify
> + if FmmtParser.WholeFvTree.Findlist:
> + for TargetFv in FmmtParser.WholeFvTree.Findlist:
> + TargetFfsPad = TargetFv.Child[-1]
> + if TargetFfsPad.type == FFS_FREE_SPACE:
> + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset)
> + else:
> + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data,
> TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
> + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], TargetFfsPad)
> + Status = FfsMod.AddFfs()
> + else:
> + print('Target Fv not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None:
> + # 1. Data Prepare
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + # 2. DataTree Create
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + with open(newffsfile, "rb") as f:
> + new_ffs_data = f.read()
> + newFmmtParser = FMMTParser(newffsfile, FV_TREE)
> + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, new_ffs_data)
> + Status = False
> + # 3. Data Modify
> + new_ffs = newFmmtParser.WholeFvTree.Child[0]
> + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
> + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
> + if Fv_name:
> + for item in FmmtParser.WholeFvTree.Findlist:
> + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name:
> + FmmtParser.WholeFvTree.Findlist.remove(item)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + for TargetFfs in FmmtParser.WholeFvTree.Findlist:
> + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs)
> + Status = FfsMod.ReplaceFfs()
> + else:
> + print('Target Ffs not found!!!')
> + # 4. Data Encapsultion
> + if Status:
> + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> + with open(outputfile, "wb") as f:
> + f.write(FmmtParser.FinalData)
> +
> +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
> + with open(inputfile, "rb") as f:
> + whole_data = f.read()
> + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist)
> + if FmmtParser.WholeFvTree.Findlist != []:
> + TargetNode = FmmtParser.WholeFvTree.Findlist[0]
> + TargetFv = TargetNode.Parent
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + TargetNode.Data.Header.State = c_uint8(
> + ~TargetNode.Data.Header.State)
> + FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data
> + with open(outputfile, "wb") as f:
> + f.write(FinalData)
> + else:
> + print('Target Ffs not found!!!')
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> new file mode 100644
> index 000000000000..6f35d4dd76cf
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> @@ -0,0 +1,86 @@
> +## @file
> +# This file is used to define the interface of Bios Parser.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +from PI.Common import *
> +from core.BinaryFactoryProduct import ParserEntry
> +from core.BiosTreeNode import *
> +from core.BiosTree import *
> +from core.GuidTools import *
> +
> +class FMMTParser:
> + def __init__(self, name: str, TYPE: str) -> None:
> + self.WholeFvTree = BIOSTREE(name)
> + self.WholeFvTree.type = TYPE
> + self.FinalData = b''
> + self.BinaryInfo = []
> +
> + ## Parser the nodes in WholeTree.
> + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', Reloffset: int=0) -> None:
> + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE:
> + ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset)
> + else:
> + ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset)
> + for Child in WholeFvTree.Child:
> + self.ParserFromRoot(Child, "")
> +
> + ## Encapuslation all the data in tree into self.FinalData
> + def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
> + # If current node is Root node, skip it.
> + if rootTree.type == ROOT_TREE or rootTree.type == ROOT_FV_TREE or rootTree.type == ROOT_FFS_TREE or rootTree.type
> == ROOT_SECTION_TREE:
> + print('Start at Root !')
> + # If current node do not have Header, just add Data.
> + elif rootTree.type == BINARY_DATA or rootTree.type == FFS_FREE_SPACE:
> + self.FinalData += rootTree.Data.Data
> + rootTree.Child = []
> + # If current node do not have Child and ExtHeader, just add its Header and Data.
> + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
> + self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + if ParTree.type != 'ROOT':
> + self.FinalData += ParTree.Data.PadData
> + rootTree.Child = []
> + # If current node is not Section node and may have Child and ExtHeader, add its Header,ExtHeader. If do not have
> Child, add its Data.
> + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or rootTree.type == SEC_FV_TREE:
> + if rootTree.HasChild():
> + self.FinalData += struct2stream(rootTree.Data.Header)
> + else:
> + self.FinalData += struct2stream(rootTree.Data.Header) + rootTree.Data.Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + if ParTree.type != 'ROOT':
> + self.FinalData += ParTree.Data.PadData
> + # If current node is Section, need to consider its ExtHeader, Child and Compressed Status.
> + elif rootTree.type == SECTION_TREE:
> + # Not compressed section
> + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != b'' and CompressStatus):
> + if rootTree.HasChild():
> + if rootTree.Data.ExtHeader:
> + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader)
> + else:
> + self.FinalData += struct2stream(rootTree.Data.Header)
> + else:
> + Data = rootTree.Data.Data
> + if rootTree.Data.ExtHeader:
> + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) +
> Data + rootTree.Data.PadData
> + else:
> + self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + self.FinalData += ParTree.Data.PadData
> + # If compressed section
> + else:
> + Data = rootTree.Data.OriData
> + rootTree.Child = []
> + if rootTree.Data.ExtHeader:
> + self.FinalData += struct2stream(rootTree.Data.Header) + struct2stream(rootTree.Data.ExtHeader) + Data
> + rootTree.Data.PadData
> + else:
> + self.FinalData += struct2stream(rootTree.Data.Header) + Data + rootTree.Data.PadData
> + if rootTree.isFinalChild():
> + ParTree = rootTree.Parent
> + self.FinalData += ParTree.Data.PadData
> + for Child in rootTree.Child:
> + self.Encapsulation(Child, CompressStatus)
> diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> new file mode 100644
> index 000000000000..7809e1598c1e
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> @@ -0,0 +1,521 @@
> +## @file
> +# This file is used to the implementation of Bios layout handler.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +from core.BiosTree import *
> +from core.GuidTools import GUIDTools
> +from core.BiosTreeNode import *
> +from PI.Common import *
> +
> +EFI_FVB2_ERASE_POLARITY = 0x00000800
> +
> +def ChangeSize(TargetTree, size_delta: int=0) -> None:
> + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or type(TargetTree.Data.Header) ==
> type(EFI_COMMON_SECTION_HEADER2()):
> + TargetTree.Data.Size -= size_delta
> + TargetTree.Data.Header.ExtendedSize -= size_delta
> + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
> + OriSize = TargetTree.Data.Header.SECTION_SIZE
> + OriSize -= size_delta
> + TargetTree.Data.Header.Size[0] = OriSize % (16**2)
> + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
> + TargetTree.Data.Header.Size[2] = OriSize // (16**4)
> + else:
> + TargetTree.Data.Size -= size_delta
> + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
> + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4) //(16**2)
> + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
> +
> +def ModifyFfsType(TargetFfs) -> None:
> + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and (TargetFfs.Data.HeaderLength + TargetFfs.Data.Size)
> > 0xFFFFFF:
> + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
> + New_Header = EFI_FFS_FILE_HEADER2()
> + New_Header.Name = TargetFfs.Data.Header.Name
> + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
> + New_Header.Type = TargetFfs.Data.Header.Type
> + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> + New_Header.Size = 0
> + New_Header.State = TargetFfs.Data.Header.State
> + New_Header.ExtendedSize = ExtendSize
> + TargetFfs.Data.Header = New_Header
> + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
> + TargetFfs.Data.ModCheckSum()
> + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and (TargetFfs.Data.HeaderLength +
> TargetFfs.Data.Size) <= 0xFFFFFF:
> + New_Header = EFI_FFS_FILE_HEADER()
> + New_Header.Name = TargetFfs.Data.Header.Name
> + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
> + New_Header.Type = TargetFfs.Data.Header.Type
> + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> + New_Header.Size = TargetFfs.Data.HeaderLength + TargetFfs.Data.Size
> + New_Header.State = TargetFfs.Data.Header.State
> + TargetFfs.Data.Header = New_Header
> + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
> + TargetFfs.Data.ModCheckSum()
> + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) == EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
> + NeedChange = True
> + for item in TargetFfs.Parent.Child:
> + if type(item.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> + NeedChange = False
> + if NeedChange:
> + TargetFfs.Parent.Data.Header.FileSystemGuid = ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> +
> + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> + TarParent = TargetFfs.Parent
> + while TarParent:
> + if TarParent.type == FV_TREE and struct2stream(TarParent.Data.Header.FileSystemGuid) ==
> EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
> + TarParent.Data.Header.FileSystemGuid = ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> + TarParent = TarParent.Parent
> +
> +class FvHandler:
> + def __init__(self, NewFfs, TargetFfs) -> None:
> + self.NewFfs = NewFfs
> + self.TargetFfs = TargetFfs
> + self.Status = False
> + self.Remain_New_Free_Space = 0
> +
> + ## Use for Compress the Section Data
> + def CompressData(self, TargetTree) -> None:
> + TreePath = TargetTree.GetTreePath()
> + pos = len(TreePath)
> + self.Status = True
> + while pos:
> + if self.Status:
> + if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-1].Data.Type == 0x02:
> + self.CompressSectionData(TreePath[pos-1], None, TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
> + else:
> + if pos == len(TreePath):
> + self.CompressSectionData(TreePath[pos-1], pos)
> + else:
> + self.CompressSectionData(TreePath[pos-1], None)
> + pos -= 1
> +
> + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) -> None:
> + NewData = b''
> + temp_save_child = TargetTree.Child
> + if TargetTree.Data:
> + for item in temp_save_child:
> + if item.type == SECTION_TREE and not item.Data.OriData and item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.Data +
> item.Data.PadData
> + elif item.type == SECTION_TREE and item.Data.OriData and not item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) + item.Data.OriData + item.Data.PadData
> + elif item.type == SECTION_TREE and item.Data.OriData and item.Data.ExtHeader:
> + NewData += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) + item.Data.OriData +
> item.Data.PadData
> + elif item.type == FFS_FREE_SPACE:
> + NewData += item.Data.Data + item.Data.PadData
> + else:
> + NewData += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
> + if TargetTree.type == FFS_TREE:
> + New_Pad_Size = GetPadSize(len(NewData), 8)
> + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> + ChangeSize(TargetTree, -Size_delta)
> + Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
> + self.Remain_New_Free_Space += Delta_Pad_Size
> + TargetTree.Data.PadData = b'\xff' * New_Pad_Size
> + TargetTree.Data.ModCheckSum()
> + elif TargetTree.type == FV_TREE or TargetTree.type == SEC_FV_TREE and not pos:
> + if self.Remain_New_Free_Space:
> + if TargetTree.Data.Free_Space:
> + TargetTree.Data.Free_Space += self.Remain_New_Free_Space
> + NewData += self.Remain_New_Free_Space * b'\xff'
> + TargetTree.Child[-1].Data.Data += self.Remain_New_Free_Space * b'\xff'
> + else:
> + TargetTree.Data.Data += self.Remain_New_Free_Space * b'\xff'
> + New_Free_Space = BIOSTREE('FREE_SPACE')
> + New_Free_Space.type = FFS_FREE_SPACE
> + New_Free_Space.Data = FreeSpaceNode(b'\xff' * self.Remain_New_Free_Space)
> + TargetTree.insertChild(New_Free_Space)
> + self.Remain_New_Free_Space = 0
> + if TargetTree.type == SEC_FV_TREE:
> + Size_delta = len(NewData) + self.Remain_New_Free_Space - len(TargetTree.Data.Data)
> + TargetTree.Data.Header.FvLength += Size_delta
> + TargetTree.Data.ModFvExt()
> + TargetTree.Data.ModFvSize()
> + TargetTree.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetTree)
> + TargetTree.Data.ModCheckSum()
> + elif TargetTree.type == SECTION_TREE and TargetTree.Data.Type != 0x02:
> + New_Pad_Size = GetPadSize(len(NewData), 4)
> + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
> + self.Remain_New_Free_Space += Delta_Pad_Size
> + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> + TargetTree.Data.Data = NewData
> + if GuidTool:
> + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"..")
> + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> + guidtool = GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> + CompressedData = guidtool.pack(TargetTree.Data.Data)
> + if len(CompressedData) < len(TargetTree.Data.OriData):
> + New_Pad_Size = GetPadSize(len(CompressedData), 4)
> + Size_delta = len(CompressedData) - len(TargetTree.Data.OriData)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> + self.Remain_New_Free_Space = len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) -
> len(CompressedData) - New_Pad_Size
> + else:
> + TargetTree.Data.PadData = b''
> + self.Remain_New_Free_Space = len(TargetTree.Data.OriData) - len(CompressedData)
> + TargetTree.Data.OriData = CompressedData
> + elif len(CompressedData) == len(TargetTree.Data.OriData):
> + TargetTree.Data.OriData = CompressedData
> + elif len(CompressedData) > len(TargetTree.Data.OriData):
> + New_Pad_Size = GetPadSize(CompressedData, 4)
> + self.Remain_New_Free_Space = len(CompressedData) + New_Pad_Size - len(TargetTree.Data.OriData) -
> len(TargetTree.Data.PadData)
> + Size_delta = len(TargetTree.Data.OriData) - len(CompressedData)
> + ChangeSize(TargetTree, -Size_delta)
> + if TargetTree.NextRel:
> + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> + TargetTree.Data.OriData = CompressedData
> + self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
> + self.Status = False
> +
> + def ModifyFvExtData(self, TreeNode) -> None:
> + FvExtData = b''
> + if TreeNode.Data.Header.ExtHeaderOffset:
> + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
> + FvExtData += FvExtHeader
> + if TreeNode.Data.Header.ExtHeaderOffset and TreeNode.Data.ExtEntryExist:
> + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
> + FvExtData += FvExtEntry
> + if FvExtData:
> + InfoNode = TreeNode.Child[0]
> + InfoNode.Data.Data = FvExtData + InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
> + InfoNode.Data.ModCheckSum()
> +
> + def ModifyTest(self, ParTree, Needed_Space: int) -> None:
> + if Needed_Space > 0:
> + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
> + ParTree.Data.Data = b''
> + Needed_Space = Needed_Space - ParTree.Data.Free_Space
> + if Needed_Space < 0:
> + ParTree.Child[-1].Data.Data = b'\xff' * (-Needed_Space)
> + ParTree.Data.Free_Space = (-Needed_Space)
> + self.Status = True
> + else:
> + if ParTree.type == FV_TREE:
> + self.Status = False
> + else:
> + BlockSize = ParTree.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - Needed_Space%BlockSize
> + if New_Add_Len % BlockSize:
> + ParTree.Child[-1].Data.Data = b'\xff' * New_Add_Len
> + ParTree.Data.Free_Space = New_Add_Len
> + Needed_Space += New_Add_Len
> + else:
> + ParTree.Child.remove(ParTree.Child[-1])
> + ParTree.Data.Free_Space = 0
> + ParTree.Data.Size += Needed_Space
> + ParTree.Data.Header.Fvlength = ParTree.Data.Size
> + for item in ParTree.Child:
> + if item.type == FFS_FREE_SPACE:
> + ParTree.Data.Data += item.Data.Data + item.Data.PadData
> + else:
> + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + ParTree.Data.ModFvExt()
> + ParTree.Data.ModFvSize()
> + ParTree.Data.ModExtHeaderData()
> + self.ModifyFvExtData(ParTree)
> + ParTree.Data.ModCheckSum()
> + elif ParTree.type == FFS_TREE:
> + ParTree.Data.Data = b''
> + for item in ParTree.Child:
> + if item.Data.OriData:
> + if item.Data.ExtHeader:
> + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.OriData + item.Data.PadData
> + else:
> + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.OriData + item.Data.PadData
> + else:
> + if item.Data.ExtHeader:
> + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.Data + item.Data.PadData
> + else:
> + ParTree.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + ChangeSize(ParTree, -Needed_Space)
> + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
> + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> + Needed_Space += Delta_Pad_Size
> + ParTree.Data.PadData = b'\xff' * GetPadSize(ParTree.Data.Size, 8)
> + ParTree.Data.ModCheckSum()
> + elif ParTree.type == SECTION_TREE:
> + OriData = ParTree.Data.Data
> + ParTree.Data.Data = b''
> + for item in ParTree.Child:
> + if item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type != 0x02:
> + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.Data + item.Data.PadData
> + elif item.type == SECTION_TREE and item.Data.ExtHeader and item.Data.Type == 0x02:
> + ParTree.Data.Data += struct2stream(item.Data.Header) + struct2stream(item.Data.ExtHeader) +
> item.Data.OriData + item.Data.PadData
> + else:
> + ParTree.Data.Data += struct2stream(item.Data.Header) + item.Data.Data + item.Data.PadData
> + if ParTree.Data.Type == 0x02:
> + ParTree.Data.Size += Needed_Space
> + ParPath = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
> + ToolPath = os.path.join(os.path.dirname(ParPath), r'FMMTConfig.ini')
> + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.SectionDefinitionGuid))
> + CompressedData = guidtool.pack(ParTree.Data.Data)
> + Needed_Space = len(CompressedData) - len(ParTree.Data.OriData)
> + ParTree.Data.OriData = CompressedData
> + New_Size = ParTree.Data.HeaderLength + len(CompressedData)
> + ParTree.Data.Header.Size[0] = New_Size % (16**2)
> + ParTree.Data.Header.Size[1] = New_Size % (16**4) //(16**2)
> + ParTree.Data.Header.Size[2] = New_Size // (16**4)
> + if ParTree.NextRel:
> + New_Pad_Size = GetPadSize(New_Size, 4)
> + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> + Needed_Space += Delta_Pad_Size
> + else:
> + ParTree.Data.PadData = b''
> + elif Needed_Space:
> + ChangeSize(ParTree, -Needed_Space)
> + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
> + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> + Needed_Space += Delta_Pad_Size
> + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> + NewParTree = ParTree.Parent
> + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE, ROOT_TREE]
> + if NewParTree and NewParTree.type not in ROOT_TYPE:
> + self.ModifyTest(NewParTree, Needed_Space)
> + else:
> + self.Status = True
> +
> + def ReplaceFfs(self) -> bool:
> + TargetFv = self.TargetFfs.Parent
> + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + # NewFfs parsing will not calculate the PadSize, thus recalculate.
> + self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
> + if self.NewFfs.Data.Size > self.TargetFfs.Data.Size:
> + Needed_Space = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> len(self.TargetFfs.Data.PadData)
> + # If TargetFv have enough free space, just move part of the free space to NewFfs.
> + if TargetFv.Data.Free_Space >= Needed_Space:
> + # Modify TargetFv Child info and BiosTree.
> + TargetFv.Child[-1].Data.Data = b'\xff' * (TargetFv.Data.Free_Space - Needed_Space)
> + TargetFv.Data.Free_Space -= Needed_Space
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + # Modify TargetFv Header and ExtHeader info.
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # return the Status
> + self.Status = True
> + # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to
> TargetFv/NewFfs.
> + else:
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + else:
> + # Recalculate TargetFv needed space to keep it match the BlockSize setting.
> + Needed_Space -= TargetFv.Data.Free_Space
> + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - Needed_Space%BlockSize
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + if New_Add_Len % BlockSize:
> + TargetFv.Child[-1].Data.Data = b'\xff' * New_Add_Len
> + TargetFv.Data.Free_Space = New_Add_Len
> + Needed_Space += New_Add_Len
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + TargetFv.Child.remove(self.TargetFfs)
> + else:
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.Data.Free_Space = 0
> + TargetFv.insertChild(self.NewFfs)
> + # Encapsulate the Fv Data for update.
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> + else:
> + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + TargetFv.Data.Size += Needed_Space
> + # Modify TargetFv Data Header and ExtHeader info.
> + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # Start free space calculating and moving process.
> + self.ModifyTest(TargetFv.Parent, Needed_Space)
> + else:
> + New_Free_Space = self.TargetFfs.Data.Size - self.NewFfs.Data.Size
> + # If TargetFv already have free space, move the new free space into it.
> + if TargetFv.Data.Free_Space:
> + TargetFv.Child[-1].Data.Data += b'\xff' * New_Free_Space
> + TargetFv.Data.Free_Space += New_Free_Space
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + self.Status = True
> + # If TargetFv do not have free space, create free space for Fv.
> + else:
> + New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
> + New_Free_Space_Tree.type = FFS_FREE_SPACE
> + New_Free_Space_Tree.Data = FfsNode(b'\xff' * New_Free_Space)
> + TargetFv.Data.Free_Space = New_Free_Space
> + TargetFv.insertChild(New_Free_Space)
> + Target_index = TargetFv.Child.index(self.TargetFfs)
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs, Target_index)
> + self.Status = True
> + # Modify TargetFv Header and ExtHeader info.
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + return self.Status
> +
> + def AddFfs(self) -> bool:
> + # NewFfs parsing will not calculate the PadSize, thus recalculate.
> + self.NewFfs.Data.PadData = b'\xff' * GetPadSize(self.NewFfs.Data.Size, 8)
> + if self.TargetFfs.type == FFS_FREE_SPACE:
> + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> len(self.TargetFfs.Data.PadData)
> + TargetFv = self.TargetFfs.Parent
> + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs Header State need be reversed.
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + # If TargetFv have enough free space, just move part of the free space to NewFfs, split free space to NewFfs
> and new free space.
> + if TargetLen < 0:
> + self.Status = True
> + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
> + TargetFv.Data.Free_Space = (-TargetLen)
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + TargetFv.insertChild(self.NewFfs, -1)
> + ModifyFfsType(self.NewFfs)
> + elif TargetLen == 0:
> + self.Status = True
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs)
> + ModifyFfsType(self.NewFfs)
> + # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to
> TargetFv/NewFfs.
> + else:
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + elif TargetFv.type == SEC_FV_TREE:
> + # Recalculate TargetFv needed space to keep it match the BlockSize setting.
> + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - TargetLen%BlockSize
> + if New_Add_Len % BlockSize:
> + self.TargetFfs.Data.Data = b'\xff' * New_Add_Len
> + self.TargetFfs.Data.Size = New_Add_Len
> + TargetLen += New_Add_Len
> + TargetFv.insertChild(self.NewFfs, -1)
> + TargetFv.Data.Free_Space = New_Add_Len
> + else:
> + TargetFv.Child.remove(self.TargetFfs)
> + TargetFv.insertChild(self.NewFfs)
> + TargetFv.Data.Free_Space = 0
> + ModifyFfsType(self.NewFfs)
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> + else:
> + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + # Encapsulate the Fv Data for update.
> + TargetFv.Data.Size += TargetLen
> + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + # Start free space calculating and moving process.
> + self.ModifyTest(TargetFv.Parent, TargetLen)
> + else:
> + # If TargetFv do not have free space, need directly move part of the free space of TargetFv's parent Fv to
> TargetFv/NewFfs.
> + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData)
> + TargetFv = self.TargetFfs.Parent
> + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> + self.NewFfs.Data.Header.State = c_uint8(
> + ~self.NewFfs.Data.Header.State)
> + if TargetFv.type == FV_TREE:
> + self.Status = False
> + elif TargetFv.type == SEC_FV_TREE:
> + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> + New_Add_Len = BlockSize - TargetLen%BlockSize
> + if New_Add_Len % BlockSize:
> + New_Free_Space = BIOSTREE('FREE_SPACE')
> + New_Free_Space.type = FFS_FREE_SPACE
> + New_Free_Space.Data = FreeSpaceNode(b'\xff' * New_Add_Len)
> + TargetLen += New_Add_Len
> + TargetFv.Data.Free_Space = New_Add_Len
> + TargetFv.insertChild(self.NewFfs)
> + TargetFv.insertChild(New_Free_Space)
> + else:
> + TargetFv.insertChild(self.NewFfs)
> + ModifyFfsType(self.NewFfs)
> + TargetFv.Data.Data = b''
> + for item in TargetFv.Child:
> + if item.type == FFS_FREE_SPACE:
> + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> + else:
> + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData
> + TargetFv.Data.Size += TargetLen
> + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> + TargetFv.Data.ModFvExt()
> + TargetFv.Data.ModFvSize()
> + TargetFv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(TargetFv)
> + TargetFv.Data.ModCheckSum()
> + self.ModifyTest(TargetFv.Parent, TargetLen)
> + return self.Status
> +
> + def DeleteFfs(self) -> bool:
> + Delete_Ffs = self.TargetFfs
> + Delete_Fv = Delete_Ffs.Parent
> + Add_Free_Space = Delete_Ffs.Data.Size + len(Delete_Ffs.Data.PadData)
> + if Delete_Fv.Data.Free_Space:
> + if Delete_Fv.type == SEC_FV_TREE:
> + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
> + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> + New_Free_Space = BlockSize - Used_Size % BlockSize
> + self.Remain_New_Free_Space += Delete_Fv.Data.Free_Space + Add_Free_Space - New_Free_Space
> + Delete_Fv.Child[-1].Data.Data = New_Free_Space * b'\xff'
> + Delete_Fv.Data.Free_Space = New_Free_Space
> + else:
> + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space - Add_Free_Space
> + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * b'\xff'
> + Delete_Fv.Data.Free_Space += Add_Free_Space
> + New_Free_Space = Delete_Fv.Data.Free_Space + Add_Free_Space
> + else:
> + if Delete_Fv.type == SEC_FV_TREE:
> + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> + New_Free_Space = BlockSize - Used_Size % BlockSize
> + self.Remain_New_Free_Space += Add_Free_Space - New_Free_Space
> + Add_Free_Space = New_Free_Space
> + else:
> + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> + New_Free_Space = Add_Free_Space
> + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
> + New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
> + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
> + New_Ffs_Tree.type = FFS_FREE_SPACE
> + New_Ffs_Tree.Data = New_Free_Space_Info
> + Delete_Fv.insertChild(New_Ffs_Tree)
> + Delete_Fv.Data.Free_Space = Add_Free_Space
> + Delete_Fv.Child.remove(Delete_Ffs)
> + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
> + Delete_Fv.Data.ModFvExt()
> + Delete_Fv.Data.ModFvSize()
> + Delete_Fv.Data.ModExtHeaderData()
> + self.ModifyFvExtData(Delete_Fv)
> + Delete_Fv.Data.ModCheckSum()
> + self.CompressData(Delete_Fv)
> + self.Status = True
> + return self.Status
> diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> new file mode 100644
> index 000000000000..287b949cc32f
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> @@ -0,0 +1,152 @@
> +## @file
> +# This file is used to define the FMMT dependent external tool management class.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import glob
> +import logging
> +import os
> +import shutil
> +import sys
> +import tempfile
> +import uuid
> +from PI.Common import *
> +from utils.FmmtLogger import FmmtLogger as logger
> +import subprocess
> +
> +def ExecuteCommand(cmd: list) -> None:
> + subprocess.run(cmd,stdout=subprocess.DEVNULL)
> +
> +class GUIDTool:
> + def __init__(self, guid: str, short_name: str, command: str) -> None:
> + self.guid: str = guid
> + self.short_name: str = short_name
> + self.command: str = command
> +
> + def pack(self, buffer: bytes) -> bytes:
> + """
> + compress file.
> + """
> + tool = self.command
> + if tool:
> + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> + ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")
> + ToolOuputFile = os.path.join(tmp, "pack_sec_file")
> + try:
> + file = open(ToolInputFile, "wb")
> + file.write(buffer)
> + file.close()
> + command = [tool, '-e', '-o', ToolOuputFile,
> + ToolInputFile]
> + ExecuteCommand(command)
> + buf = open(ToolOuputFile, "rb")
> + res_buffer = buf.read()
> + except Exception as msg:
> + logger.error(msg)
> + return ""
> + else:
> + buf.close()
> + if os.path.exists(tmp):
> + shutil.rmtree(tmp)
> + return res_buffer
> + else:
> + logger.error(
> + "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
> + logger.info("Its GUID is: %s" % self.guid)
> + return ""
> +
> +
> + def unpack(self, buffer: bytes) -> bytes:
> + """
> + buffer: remove common header
> + uncompress file
> + """
> + tool = self.command
> + if tool:
> + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> + ToolInputFile = os.path.join(tmp, "unpack_sec_file")
> + ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")
> + try:
> + file = open(ToolInputFile, "wb")
> + file.write(buffer)
> + file.close()
> + command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]
> + ExecuteCommand(command)
> + buf = open(ToolOuputFile, "rb")
> + res_buffer = buf.read()
> + except Exception as msg:
> + logger.error(msg)
> + return ""
> + else:
> + buf.close()
> + if os.path.exists(tmp):
> + shutil.rmtree(tmp)
> + return res_buffer
> + else:
> + logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
> + logger.info("Its GUID is: %s" % self.guid)
> + return ""
> +
> +class GUIDTools:
> + '''
> + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools.
> + '''
> + default_tools = {
> + struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-
> 127f4c984779", "TIANO", "TianoCompress"),
> + struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-
> dc7bd79403cf", "LZMA", "LzmaCompress"),
> + struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-
> a4600d9dd083", "CRC32", "GenCrc32"),
> + struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-
> ca72a6eae889", "LZMAF86", "LzmaF86Compress"),
> + struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-
> 0f7f630d5afb", "BROTLI", "BrotliCompress"),
> + }
> +
> + def __init__(self, tooldef_file: str=None) -> None:
> + self.dir = os.path.dirname(__file__)
> + self.tooldef_file = tooldef_file if tooldef_file else os.path.join(
> + self.dir, "FMMTConfig.ini")
> + self.tooldef = dict()
> + self.load()
> +
> + def VerifyTools(self) -> None:
> + """
> + Verify Tools and Update Tools path.
> + """
> + path_env = os.environ.get("PATH")
> + path_env_list = path_env.split(os.pathsep)
> + path_env_list.append(os.path.dirname(__file__))
> + path_env_list = list(set(path_env_list))
> + for tool in self.tooldef.values():
> + cmd = tool.command
> + if os.path.isabs(cmd):
> + if not os.path.exists(cmd):
> + print("Tool Not found %s" % cmd)
> + else:
> + for syspath in path_env_list:
> + if glob.glob(os.path.join(syspath, cmd+"*")):
> + break
> + else:
> + print("Tool Not found %s" % cmd)
> +
> + def load(self) -> None:
> + if os.path.exists(self.tooldef_file):
> + with open(self.tooldef_file, "r") as fd:
> + config_data = fd.readlines()
> + for line in config_data:
> + try:
> + guid, short_name, command = line.split()
> + new_format_guid = struct2stream(ModifyGuidFormat(guid.strip()))
> + self.tooldef[new_format_guid] = GUIDTool(
> + guid.strip(), short_name.strip(), command.strip())
> + except:
> + print("GuidTool load error!")
> + continue
> + else:
> + self.tooldef.update(self.default_tools)
> +
> + self.VerifyTools()
> +
> + def __getitem__(self, guid) -> None:
> + return self.tooldef.get(guid)
> +
> +
> +guidtools = GUIDTools()
> diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> new file mode 100644
> index 000000000000..5289fc27049a
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> @@ -0,0 +1,18 @@
> +## @file
> +# This file is used to define the Fmmt Logger.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +##
> +
> +import logging
> +import sys
> +
> +FmmtLogger = logging.getLogger('FMMT')
> +FmmtLogger.setLevel(logging.INFO)
> +
> +lh=logging.StreamHandler(sys.stdout)
> +lf=logging.Formatter("%(levelname)-8s: %(message)s")
> +lh.setFormatter(lf)
> +FmmtLogger.addHandler(lh)
> \ No newline at end of file
> diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> new file mode 100644
> index 000000000000..83a31aeea3fe
> --- /dev/null
> +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> @@ -0,0 +1,54 @@
> +## @file
> +# This file is used to define the printer for Bios layout.
> +#
> +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +def GetFormatter(layout_format: str):
> + if layout_format == 'json':
> + return JsonFormatter()
> + elif layout_format == 'yaml':
> + return YamlFormatter()
> + elif layout_format == 'html':
> + return HtmlFormatter()
> + else:
> + return TxtFormatter()
> +
> +class Formatter(object):
> + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
> + raise NotImplemented
> +
> +class JsonFormatter(Formatter):
> + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
> + try:
> + import json
> + except:
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> + return
> + print(outputfile)
> + if outputfile:
> + with open(outputfile,"w") as fw:
> + json.dump(layoutdict, fw, indent=2)
> + else:
> + print(json.dumps(layoutdict,indent=2))
> +
> +class TxtFormatter(Formatter):
> + def LogPrint(self,layoutlist: list) -> None:
> + for item in layoutlist:
> + print(item)
> + print('\n')
> +
> + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) -> None:
> + print(outputfile)
> + with open(outputfile, "w") as f:
> + for item in layoutlist:
> + f.writelines(item + '\n')
> +
> +class YamlFormatter(Formatter):
> + def dump(self,layoutdict, layoutlist, outputfile = None):
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> +
> +class HtmlFormatter(Formatter):
> + def dump(self,layoutdict, layoutlist, outputfile = None):
> + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> \ No newline at end of file
> --
> 2.27.0.windows.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
2021-11-09 0:29 ` [edk2-devel] " Michael D Kinney
@ 2021-11-09 1:34 ` Yuwei Chen
0 siblings, 0 replies; 6+ messages in thread
From: Yuwei Chen @ 2021-11-09 1:34 UTC (permalink / raw)
To: Kinney, Michael D, devel@edk2.groups.io; +Cc: Feng, Bob C, Liming Gao
Hi Michael,
This patch code is the same version of the sources submitted to the edk2-basetools repo.
It has passed all the edk2-basetools CI checks.
I will update the patch and add the PR link into it.
Thanks,
Christine (Yuwei)
> -----Original Message-----
> From: Kinney, Michael D <michael.d.kinney@intel.com>
> Sent: Tuesday, November 9, 2021 8:29 AM
> To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>
> Subject: RE: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
>
> Hi Christine,
>
> Is this the same version of the sources that were submitted to the
> edk2-basetools repo as the following PR?
>
> https://github.com/tianocore/edk2-basetools/pull/11
>
> The goal is to delete the sources from BaseTools/Source/Python and have all
> edk2 developers use the python tools published by edk2-basetools project.
>
> The edk2-basetools project also has more extensive CI checks for python
> sources
> and we do not to accept source changes into BaseTools/Source/Python that
> do
> not pass all the edk2-basetools CI checks.
>
> Thanks,
>
> Mike
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yuwei
> Chen
> > Sent: Monday, November 8, 2021 4:09 PM
> > To: devel@edk2.groups.io
> > Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>
> > Subject: [edk2-devel] [PATCH 1/1] BaseTools: Add FMMT Tool
> >
> > From: Bob Feng <bob.c.feng@intel.com>
> >
> > The FMMT python tool is used for firmware files operation, which has
> > the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function.
> > Currently the FMMT C tool is saved in edk2-staging repo, but its
> > quality and coding style can't meet the Edk2 quality, which is hard to
> > maintain (Hard/Duplicate Code; Regression bugs; Restrict usage).
> > The new Python version keeps same functions with origin C version. It
> > has higher quality and better coding style, and it is much easier to
> > extend new functions and to maintain.
> >
> > RFC: https://edk2.groups.io/g/devel/message/82877
> > Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT
> >
> > Cc: Bob Feng <bob.c.feng@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
> > ---
> > BaseTools/BinWrappers/PosixLike/FMMT | 14 +
> > BaseTools/BinWrappers/WindowsLike/FMMT.bat | 4 +
> > BaseTools/Source/Python/FMMT/FMMT.py | 117 ++++
> > BaseTools/Source/Python/FMMT/FMMTConfig.ini | 5 +
> > .../Python/FMMT/Img/FirmwareVolumeFormat.png | Bin 0 -> 29515 bytes
> > .../Source/Python/FMMT/Img/NodeTreeFormat.png | Bin 0 -> 79906
> bytes
> > BaseTools/Source/Python/FMMT/PI/Common.py | 81 +++
> > .../Source/Python/FMMT/PI/FfsFileHeader.py | 66 +++
> > BaseTools/Source/Python/FMMT/PI/FvHeader.py | 112 ++++
> > .../Source/Python/FMMT/PI/SectionHeader.py | 110 ++++
> > BaseTools/Source/Python/FMMT/PI/__init__.py | 6 +
> > BaseTools/Source/Python/FMMT/README.md | 180 ++++++
> > BaseTools/Source/Python/FMMT/__init__.py | 0
> > .../Python/FMMT/core/BinaryFactoryProduct.py | 371 +++++++++++++
> > BaseTools/Source/Python/FMMT/core/BiosTree.py | 199 +++++++
> > .../Source/Python/FMMT/core/BiosTreeNode.py | 191 +++++++
> > .../Source/Python/FMMT/core/FMMTOperation.py | 140 +++++
> > .../Source/Python/FMMT/core/FMMTParser.py | 86 +++
> > .../Source/Python/FMMT/core/FvHandler.py | 521
> ++++++++++++++++++
> > .../Source/Python/FMMT/core/GuidTools.py | 152 +++++
> > .../Source/Python/FMMT/utils/FmmtLogger.py | 18 +
> > .../Source/Python/FMMT/utils/FvLayoutPrint.py | 54 ++
> > 22 files changed, 2427 insertions(+)
> > create mode 100644 BaseTools/BinWrappers/PosixLike/FMMT
> > create mode 100644 BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > create mode 100644 BaseTools/Source/Python/FMMT/FMMT.py
> > create mode 100644 BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > create mode 100644
> BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > create mode 100644
> BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/Common.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > create mode 100644 BaseTools/Source/Python/FMMT/PI/__init__.py
> > create mode 100644 BaseTools/Source/Python/FMMT/README.md
> > create mode 100644 BaseTools/Source/Python/FMMT/__init__.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/BiosTree.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/FvHandler.py
> > create mode 100644 BaseTools/Source/Python/FMMT/core/GuidTools.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > create mode 100644
> BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> >
> > diff --git a/BaseTools/BinWrappers/PosixLike/FMMT
> b/BaseTools/BinWrappers/PosixLike/FMMT
> > new file mode 100644
> > index 000000000000..5f5519e1e1b6
> > --- /dev/null
> > +++ b/BaseTools/BinWrappers/PosixLike/FMMT
> > @@ -0,0 +1,14 @@
> > +#!/usr/bin/env bash
> > +#python `dirname $0`/RunToolFromSource.py `basename $0` $*
> > +
> > +# If a ${PYTHON_COMMAND} command is available, use it in preference
> to python
> > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
> > + python_exe=${PYTHON_COMMAND}
> > +fi
> > +
> > +full_cmd=${BASH_SOURCE:-$0} # see
> http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a
> good choice
> > here
> > +dir=$(dirname "$full_cmd")
> > +cmd=${full_cmd##*/}
> > +
> > +export
> PYTHONPATH="$dir/../../Source/Python/FMMT:$dir/../../Source/Python${P
> YTHONPATH:+:"$PYTHONPATH"}"
> > +exec "${python_exe:-python}" -m $cmd.$cmd "$@"
> > diff --git a/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > new file mode 100644
> > index 000000000000..259d6cd6ddea
> > --- /dev/null
> > +++ b/BaseTools/BinWrappers/WindowsLike/FMMT.bat
> > @@ -0,0 +1,4 @@
> > +@setlocal
> > +@set ToolName=%~n0%
> > +@set
> PYTHONPATH=%PYTHONPATH%;%BASE_TOOLS_PATH%\Source\Python;%B
> ASE_TOOLS_PATH%\Source\Python\FMMT
> > +@%PYTHON_COMMAND% -m %ToolName%.%ToolName% %*
> > diff --git a/BaseTools/Source/Python/FMMT/FMMT.py
> b/BaseTools/Source/Python/FMMT/FMMT.py
> > new file mode 100644
> > index 000000000000..1c41face7308
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/FMMT.py
> > @@ -0,0 +1,117 @@
> > +# @file
> > +# Firmware Module Management Tool.
> > +#
> > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +# Import Modules
> > +#
> > +import argparse
> > +import sys
> > +from core.FMMTOperation import *
> > +
> > +parser = argparse.ArgumentParser(description='''
> > +View the Binary Structure of FD/FV/Ffs/Section, and
> Delete/Extract/Add/Replace a Ffs from/into a FV.
> > +''')
> > +parser.add_argument("--version", action="version", version='%(prog)s
> Version 1.0',
> > + help="Print debug information.")
> > +parser.add_argument("-v", "--View", dest="View", nargs='+',
> > + help="View each FV and the named files within each FV: '-v
> inputfile outputfile,
> > inputfiletype(.Fd/.Fv/.ffs/.sec)'")
> > +parser.add_argument("-d", "--Delete", dest="Delete", nargs='+',
> > + help="Delete a Ffs from FV: '-d inputfile TargetFfsName
> outputfile TargetFvName(Optional,\
> > + If not given, wil delete all the existed target Ffs)'")
> > +parser.add_argument("-e", "--Extract", dest="Extract", nargs='+',
> > + help="Extract a Ffs Info: '-e inputfile TargetFfsName outputfile'")
> > +parser.add_argument("-a", "--Add", dest="Add", nargs='+',
> > + help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile
> outputfile'")
> > +parser.add_argument("-r", "--Replace", dest="Replace", nargs='+',
> > + help="Replace a Ffs in a FV: '-r inputfile TargetFfsName
> newffsfile outputfile
> > TargetFvName(Optional,\
> > + If not given, wil replace all the existed target Ffs with new Ffs
> file)'")
> > +parser.add_argument("-l", "--LogFileType", dest="LogFileType", nargs='+',
> > + help="The format of log file which saves Binary layout. Currently
> supports: json, txt. More formats
> > will be added in the future")
> > +
> > +def print_banner():
> > + print("")
> > +
> > +class FMMT():
> > + def __init__(self) -> None:
> > + self.firmware_packet = {}
> > +
> > + def CheckFfsName(self, FfsName:str) -> str:
> > + try:
> > + return uuid.UUID(FfsName)
> > + except:
> > + return FfsName
> > +
> > + def View(self, inputfile: str, logfiletype: str=None, outputfile: str=None)
> -> None:
> > + # ParserFile(inputfile, ROOT_TYPE, logfile, outputfile)
> > + filetype = os.path.splitext(inputfile)[1].lower()
> > + if filetype == '.fd':
> > + ROOT_TYPE = ROOT_TREE
> > + elif filetype == '.fv':
> > + ROOT_TYPE = ROOT_FV_TREE
> > + elif filetype == '.ffs':
> > + ROOT_TYPE = ROOT_FFS_TREE
> > + elif filetype == '.sec':
> > + ROOT_TYPE = ROOT_SECTION_TREE
> > + else:
> > + ROOT_TYPE = ROOT_TREE
> > + ParserFile(inputfile, ROOT_TYPE, logfiletype, outputfile)
> > +
> > + def Delete(self, inputfile: str, TargetFfs_name: str, outputfile: str,
> Fv_name: str=None) -> None:
> > + if Fv_name:
> > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> outputfile, uuid.UUID(Fv_name))
> > + else:
> > + DeleteFfs(inputfile, self.CheckFfsName(TargetFfs_name),
> outputfile)
> > +
> > + def Extract(self, inputfile: str, Ffs_name: str, outputfile: str) -> None:
> > + ExtractFfs(inputfile, self.CheckFfsName(Ffs_name), outputfile)
> > +
> > + def Add(self, inputfile: str, Fv_name: str, newffsfile: str, outputfile: str)
> -> None:
> > + AddNewFfs(inputfile, self.CheckFfsName(Fv_name), newffsfile,
> outputfile)
> > +
> > + def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile:
> str, Fv_name: str=None) -> None:
> > + if Fv_name:
> > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile,
> outputfile, uuid.UUID(Fv_name))
> > + else:
> > + ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile,
> outputfile)
> > +
> > +
> > +def main():
> > + args=parser.parse_args()
> > + status=0
> > +
> > + try:
> > + fmmt=FMMT()
> > + if args.View:
> > + if args.LogFileType:
> > + fmmt.View(args.View[0], args.LogFileType[0])
> > + else:
> > + fmmt.View(args.View[0])
> > + if args.Delete:
> > + if len(args.Delete) == 4:
> > +
> fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2],args.Delete[3])
> > + else:
> > + fmmt.Delete(args.Delete[0],args.Delete[1],args.Delete[2])
> > + if args.Extract:
> > + fmmt.Extract(args.Extract[0],args.Extract[1],args.Extract[2])
> > + if args.Add:
> > + fmmt.Add(args.Add[0],args.Add[1],args.Add[2],args.Add[3])
> > + if args.Replace:
> > + if len(args.Replace) == 5:
> > +
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> 3],args.Replace[4])
> > + else:
> > +
> fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[
> 3])
> > + # TODO:
> > + '''Do the main work'''
> > + except Exception as e:
> > + print(e)
> > +
> > + return status
> > +
> > +
> > +if __name__ == "__main__":
> > + exit(main())
> > diff --git a/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > new file mode 100644
> > index 000000000000..e4bf03c41f4e
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/FMMTConfig.ini
> > @@ -0,0 +1,5 @@
> > +a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress
> > +ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress
> > +fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32
> > +d42ae6bd-1352-4bfb-909a-ca72a6eae889 LZMAF86 LzmaF86Compress
> > +3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
> > diff --git
> a/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > b/BaseTools/Source/Python/FMMT/Img/FirmwareVolumeFormat.png
> > new file mode 100644
> > index
> 0000000000000000000000000000000000000000..7cc806a0133413a4aa037f1d43
> d80000546a5246
> > GIT binary patch
> > literal 29515
> > zcmcG$bySpZzxIs{h;*kQ-
> QA%B(hbs~fb@{kr2^7}lF~VJNaui3BP|_6cXz|UdyT(+
> > z@4cV*xu0jfYp?bGHx8Fqo%KDA<8w}!x~kkWOma*#G_+?5@-
> mueX!oILX!ky#KL)-b
> >
> z*L=x<hV~pyLFSdVXX?&ufRXlk(!t$eWQUAWs6a&z4hb82a(FhbuXf8j8M331T
> xmKL
> > z!H*H;#x^;-U0hqXV6&1jfgcuHHo6(wtPm9?{5-
> *01vG}q*T?cd3(SjgooeVt#2I(K
> > zsH<QNhzIoHtij1haVbg5&bI})k`^V`jn)@_3Y<6WZ|mr@6F&u^(+1&!F1}6A-
> ~0Os
> > zomQa`7xm?Vn1W*P-%s-
> jnykPv=(IPgF`B5O(HA{p;xPYyYK_g+{^ty7^w7WOYTKu0
> >
> zA^Q8tpM+meOs7ygu*QzofkppB890#CH!vaY^9>J4dxmd4K5&@Bvj#t||Iyi*{
> )abe
> > z{I&G~u33SY%Zhw!or;12*-v@k`k_A=B>uMt_@7?l-
> @J?eZ>M^7i~SOv=Z7|He5*9B
> > z*-Jfk;((ApOh<DBpW00KVT-
> d`(_=5+Rb$5YAn{Zni!r4Nv_nO&2?akG)bWu0KC~_e
> > z5hX~!dqa>0Ni%KxN)V+;B<tNR(l-DX$jG6Wz>4>4tz91qe)gfE4g(?YCU-
> u*mWMw)
> >
> zYZ9ndV3HB4SQ8nO$7M7)G~o%W(JEAbO)~r^m;%8wqGZk66tMp^SusJR)1O
> K!@Kal=
> >
> zFkG_T1(S#Wdumz4sds}>;2sSjqjb6%<#>h~^<ynv53zVfT24b{*7y;g9jO=4WB0
> 41
> >
> z=$FJ1uc?nn$D<c}<|kCBkLssFq@L~P5`JW^?7drZ*GOR*Q`u`5%y4$M!+kxi(!7
> ^W
> > zXqH{ML)x#35z}x<`aV8yk7N|DPc;Gx-6CAy-
> 4#Vx^C$n*R(S2#<fkNRn8K6C!26<O
> > zbJ!y_4}?SBuis<Kweao56=nHw&5yS>15Cei)O^LmHVr^*^U&I<-
> BdBP<AmFX)1_0^
> > zphoUDj_aEpvqlQD(uil<hj!^?o%_^dN6}v*Fb}cO&g=U~3OI`2IHVY>robt-
> C5{L_
> >
> zKY7868Ua|J(c~4MfY3*(TH(nB2GP0P+Bxq&DSbY9)L*l2HfpW6U@eef<GM~
> @YoAv$
> > zg7tl~Kq^RbPmZvpAuX0fvSRm`l_t&lIp?YgqiAhS4b?SRXPx6j{^K=y`Tl5-b>&o%
> >
> z#9}QDAC=n^W?SEn@tay29_cH(Qj)(%kM8=<Qt3fs<IC_|iQd{J!a4mnKR@+O
> ToZlL
> > z&3gKW-
> 6^Vf#y668S!jqIoodn?gSJCO*!zSzK0f{yTRQaPa|Ii&t~@D~gfrf#(ptk`
> > zYfncLj2YRs5i(*1g&0ZS<dZl3RDC}X)eo3*@k`&_$*r}sknV=%HN<PZIscj@-
> nrRU
> >
> zr)BCKG}+9b(5C=0v{@*{xmzDkP4#BoWTW|6Z$l#hS$w!Vs;do3fG{lPY}($uXtK
> rk
> > z^7OAq1SAXvaSeUzY`WRIfIpy^nC!H8-`_boX-
> Sd(_WJqP_|B0b^CxF|AoL+M;CAVm
> >
> zm}1k@2fAaKkW>)db`vyuD929kh1kSlkjP_YnBzunpzF22s)kafVH^5GmG#>`rx
> T+5
> >
> z&7X7TiJ+^`+!Myi&54A&3`MFnX0=RZo37~5p^Rmf5I!1@U+{pnP@Wi;SXnWu
> D}JIY
> >
> zr^<u@I(qMWNz(*`F#pdG|IT73j?}IR?@FcwRcS0yRjsUyj^y{Q7+Dc)Bq=sw;fy
> Yy
> >
> z+fwVl+Vm*}=B(e9w+RoY;I;K#(>zxV2))8~J%94)<htIl@UjJ~Z3Z59c6s;nz>=Gk
> > znUnL(gA^3WY<fLCL1`LI#YXczxL*I>*ErV59QLuHV-
> =J0m0eEDjs15%NH+H9hW653
> > zz3kXsjNvzi(X;sY`z}o%w$Lr}Rcg=n+-ircv6uwuNZn5E^VY~hGQj!E_7ZYc312rz
> > z)x6VsL$EfMsh^8nVXMOrI<8jVs&!paI!bj-
> d|`jvIbK+si;&!T2_F_&_HNh<w9^L8
> > zu?$hyn4d$wdVWZ~+NEf&=!2BP6~=n}fQ*c+!~|yG@B-
> 8MDTh)0*RC#EN#u!^nVH$m
> > zzgh)3l-4|JU2GA^h^aCxz6Mv-Zhmg-
> ^Z7&bz___k1a7p>xHB|v!ubX%tr}+euxdm$
> >
> zr@UZ!Cb*Y9RjAa*@Ysvhor3#K*>m?e%y?Tu4~{uV_j?!Z`Q_advBucFI}vz_7^
> |1l
> > zs#*3J+AHPINX8;)QiLwy6-Z2S$&-
> jZ_3GKYZG<s+y{dSiyEdsfqsH}3VW~G}chcep
> >
> z+bz!N8P0v$7bmTDT!M~sI~P|J^A}%eUf`LngoTB@ySX_0J0`f7?s|%)M<yHZ81
> lAs
> > zD_nFX!e0mNU<}uiOlgt9o5>Vmp|#FX4#&z}Q`3+O7G=%A7y6~w0#YL$-
> *{a=n?K!V
> > zzqL5yH*wusZE9O|6aMn_gl(?HB=9@5WKgu9#{ZC_C(_{7zuN*H5Scl7-
> 918Sb}rWM
> > zKu}~4YZm`$e$42-
> HyX^*ARyqnSUwP&U1IL265jq`r~Al#d|yN<*_D@z5<)EzK4ksy
> >
> z?cq{q2ONGaLI+Gi*#WY?nwXi`0YMy{qT~|}?{ou)>0cOr*4Aq00ps&Ad2f=Wd
> UCN$
> >
> z3)<RtiJaz5$BZRUObU5d)SMIkP@5|pm0UO>pHvd?nrquvYW5RI&wU>uQgK
> G|Lx3X6
> >
> zHQK_7&MSD(#jg`*Qr#e=8|%+2t+Bz$`Ym)E;_}tQgP}S19bEo(JV9H#sgqdVfhk
> tP
> > z4}!3MY9t1~*EvD4lR~M)=-
> uo73Np^_<_#SkowbWApZV)_)SI`kc66lik4?_aJ69P!
> >
> zdAyOE<@D`H@a*zwt=*1^oMD5zN5C?=Z%o{M?&Jgbgl4MGx0=gxb?_0pb8
> b3+@WmhX
> > z>ZGUkb+ts3Tk&n$W-
> n50EmVPV4rbP{sY<e)9~bnpn!SQ{)bFUN$S>hnPWD2CQkvs@
> > zj)=>LWtfOq<($18M;{J)eP!RJ8w@ikz)-
> !o_k?1CJInjgyPOhp1A%MDgUMftCS$J~
> > zs~z=IeuEWX?~IM;x16IPm|$IzVscrUQA-
> 1pvp;SGObla#%wB7pN+^fnJc#a?jT)B8
> > zr)Khe^ksZp$9->R)AM#A5a)`Aoc6w{mKMSJe1MeeS|6EzSmEf&-
> l~CT@#e0@&vmX7
> > zJ_wp%vzi$5r<=7kljM~V`|f>zT5Y+)*XvX2RACO$-}Y*-
> 7<1UbT|>O|@l;?iY=`N4
> > z(9OA%WUAZzNO!6Ai;3l$oSs)rly;5Lhg-}wddzR;%=bruKV8JvIpR~ss`}fAUYg*%
> > zg_$H!-
> &YS|{8p9oIhAV8;2~ZS;`RCFob(pNdtZux21525n^Jh;!h3xnEs~6{D|!eW
> >
> z@1oXWwkPBEgbB^o&Q5N@iOeu+2OO=b<MU~iXM`#ZKa2d?e2H)3^jdycSi
> ^(F<T-(}
> >
> zU9bQwqC@~@4%#T&M2@~I;`IHT<fATT>utq0e!@A>BqQ6+lbopLu|0YyVZy`
> TJt!CY
> > zZezN}4wz=94~>e){&{8Z-
> !pi_<_>Q*^E1xO`K8rfPMi?eMFO=Zmh^t}F=TnWq=cPC
> >
> z?nTG*M)zIv%gfoipFO?3A&Zedg`2Z?$#a6#(w*KE<P$0WU3fo%!qklP>T)n(@
> 4|bv
> >
> zC*D6&CiG{W)gW~uD@nWSO)bzKhXyC2EyTe*(564ZbA8OeQUB}9`FBlP+00lb
> HJ6Kn
> > zcW5oArH&O&iy$dE`i=$R|12WEk|rl78-
> 3{^BqoMr9wIa>5?kd89e6FZh*HvTIrq;E
> >
> zMtpFH;58k<B5Q|a2VLYCvKc0I1QacM+CI6ee^TIFv<WNBhD7Q)3cvzncM6D9u
> N5=1
> >
> z{ht*Uo&~?TA}&7|Fx{896v5!>6Xvq2cbFBGlBJVbKs34)FK@4>`#3yQb*PL<o?F
> uS
> >
> zn)`wKJJt$w)YDDdOz!E;Q^_%wW1WoBr?IqyAqFljl!Lu3+N^CZCV54L>qBBo<D
> p?;
> > zS=rg2r>6}ntEx~-?7dz;mytY`lpE5hI|UU-o=JL^Q!$$DxKo`Bj-roO<vWM~1;i)%
> >
> zND(q|Lzk{yf^06hp@J7ecXs}I=C_XGpECbg#?|wd`p#;D(wSNkGu%gAD|w#;h
> wZ%2
> > z(<Y{8>x3bTp!XGe>@cBiIOGlMW19)-
> jP94JlcGPOz|I@CnNHq}U5WPPK6dNBl;utt
> > z^X^6_m~Xoocok!;eVHcC9`CkU=)In7wB8yNVM>^2u-
> 9w%D+WylIItDc+R{L*5W0`!
> >
> z>WG@K7WQnJExgUBC@9XqZS(w;a4OVhwY9bNcHHQE8D+N}frp$UxYs_v59
> {es93C0D
> >
> zx4n`V_yp%nG(mgLhYt7R7{(+4Z3hKxRYfuS`WI<Q2m^C%%T<?9%RN0N0!T@
> >3g{x5
> > z9vUc{Wq4aFGhTb~XTVR~wsouO9sylgL}Sq5Qo#AH=bq@`kNtdT^-
> 1kaKB+d7TDrx2
> >
> ziyvyS!K0OwOa~Ux+Y7i9WD+>pjBQLDHhFMGis_gZ?y9s{qUigUajT}VdhxC7U
> B(wX
> >
> zwR^dzsvK7e+XeI2%3Ml~VZVk)M>|qQTz_|WFK%dX^^RcDKGs%Nj*NUkv_
> u?3XkOqt
> >
> zYGwFphna|VjCs$XnJTt0Cj9Cwy$<GrXWnbEMAte851eKa^;1AB_FIR(u$lAg_y
> XDU
> >
> z)8b)fR7>yMnX0;XftbHtTen83qfbl<o46AhSN1v+4LAM*Z?cY)#K0vJIuaBr)?1Iy
> > z64j(LzHu=K+*tR0=h4>HJqCtrkLWoFE5>f3Y-
> oCVYo9xaw1S?6YWT`9V^=h<QFrQ}
> > zHAIHMg-
> ^<IJ%+qBH%rSFblH1xxV);9jT@K?gQZ;_uk(2wSpWm;hDue+2tJx=h0NyW
> > zI)!q*`yHlJrnRe?hu)X>7%Nz0cDuQ06n17ZI1NqJ(0vd*#G3t-
> !imMfLU8CUGd)w^
> >
> zoFpU_^xzr9Mdb`B1<Ep%lh>7|9g;{;s!TJ7+>7nqPU9!!bn%9*yE;Wp0i8~^P5W
> JL
> >
> zVyY{f1k_hWV%z)LX%{wzr&}aK4NM}ZP1IX)#tvsNNyA<Pe8(zBAF+4Q6L`7?18
> j}*
> > zbu=zgTiJy#ynK5jRs@N^w(fE>b}I$r-
> rE>0)ItNAt84JvNm_%AR4>7K`<AU_o!*Zb
> > z>*bd>3NHK<JVx$COj{NHO^+g00f|v^3M%b&wX8huF(38yZ-
> ?%k;$V^R5XclbB!ZjD
> > zt=UY&?7-X9<AFk^dEO%~_#P&-
> r*A2Q*ooOQ5|6Q3mxqD`%AAiv4FBLQ>BJ(=tOwMb
> >
> z3<75jkZUQ)j%Ms)vQ;2qjYp@x@8{>7XESnEQW3B|lQP(PYV@FRlRzllE~ANuK
> 0lL_
> >
> z*JZ{F2gL%2X2ihpY39SDl$6<Nedb*oQz8?_nxNduoYMX?3lid9PMYPdRnJCa=J
> +YC
> >
> zknPElJSSBUIv!eAG>w{<mq=P#+Qx_WT@PatnvB96Ue+kEQa%AzCN_i3Yi#{T
> cOCnX
> > za(JEARZw!k{Lix?3Y(d-Dz`6@jQlo_q-MN>Cf_t&UNh7-
> PWV~o9k)+h9?sds1ss@v
> > zSgaMn{Kb=7It4nMlG8iA*-
> tv(8s3A%CEq{t;8=O<kN<1VU2GCnx6}03MO1NHHY<UT
> >
> zM><Zliw&t1hjD7veb?}Gkd^67?zz)CC0o(Bc~$|@0tjko$=Us0^Smd%YG#=k8
> My7^
> >
> zHFgs~)y^m>Y0}kz;rw*tL*u)~59P__Q50&{N<`&%MP=6xI`XVy(=)}zCz;!HOg#
> uf
> > z9rMP(?=uq>)!=O_5T;Xn*ZEvFBS-
> w@qC>3ZSgiihc{E6Y0WMWLTM;qcN6|VoRA2ii
> >
> z8Wv<Jx`mS!ZQPU1a2G+ii*e$ZwujVd6ivOv;p))#{~Rs5)~1YP1iTOF(fkbmo~^N
> B
> > z5x1?lQ6?hL$xD?`OMxfhj9I3V(LXd;wIjy0%sde`C3*cVk$V-
> {XCZzitML(}hGq&W
> >
> zR6OY2zXDu`Ji`j=<r$efrCxmFCl{HwRD0RlCDaN_SemJ_pFR{!ymld(U#8rrcP<^q
> > zeC@D`Bk`qD-
> *FcHUgCG^*Ft)$0chR^nj0*^9Lo%3!LPy5Z`8aL7k~C)m&nb@VSbRs
> >
> zR)LYvt0z=`QnpP5lZXAajLZ+OW6PzbCC`nl5R`B*W7Z0ZIWb}Z3r!bDsjGSsZ}3qw
> >
> z@+>x$nN!4f2_$TxpPH`Bp+*zZwIjay=kXIxZ~b|bPjC@`RliTNSy{v1hxd3Y)_M
> b0
> >
> zbg!HYL7q=|)K)66X?l3BC=;)1JTi`*N%&6Af52{u5~9DZ!We)G0NrOXm_*p`s=9<
> 3
> >
> zC>yv*v4Be2^=L&QAcWUxG>cw5Pdc$F@LW<#_0^7;{ndNFeKxeuV4|P0fPn
> O7{FtVq
> > zO<`-
> jb>5LvPCzD<M7;dE%+q&J89wD*6#CxwyWJ5KGE`CeJSOJNqnoo<hxbuyT-Ie5
> >
> z&lvKA^zg*GlIiDaz9%X_gT<LY+*s=Av^2=h4om%$SSU72kmgYRrt%d*Fry9iu{j
> gu
> >
> zy9GEmH6OQaK&Pm)>b~^3OV#)=o9cTrUrt>!F28Jb$xdHL%*l^EeCFD9&Q;w
> VaGRj!
> >
> z?uUrJ8EsG_!cHQ=cGI;Pme{>%$;Opa9fj0Ml@p;f#7N!%k;ip?_lnSkZoQ`nX87D
> h
> >
> z&K&9P593<Dz!=*m&?rpMSmK2YDq&DTT?ATEdvRF;s(=<#O%v_3D~Gv9K!o
> M(_fvkH
> > zj+J$59%!#I24A*hWHJ-
> 4_Ctrw6E592b#LRWc>Ptu2scN=b2Ijeh=lB^bBZ}<nisY$
> >
> z9a*MSK}H<MjEzjr%ksZ{(m(4xnD=twqh@o%AwGU&+pC&6>pE`0@YC#<S;H
> @@5TTQn
> > z?CeY4{kuixEHc-m@xjfNtv~#=djVmES8qyY-f%Hw1>t_`OI)?|LFDDTFfc|-
> *^dW5
> > zPnA_GeDOVvSV?J&WdMOdDP;anz2WaI|HC3`e;@PO5o&OS>sSsoAjG-
> =t3xxw9x1s>
> > zVm#1b>P&Rq5mpJN=1;DQ8#6iB;fP?(yk)ztorQi*=MY&wlN(8NJq)-
> ^X=?*fdvDOD
> > z`(JGux-`GaNmsm5q-w4X%pe_@@+Y3)8H?8_`s)?=rQVZ-
> h^Vc`*v)kGJbP?dUI5#x
> >
> z`84_2H{tYJurhfeC?NC40xO$N%S)TU?yI}vs<5K$b^TLS%uYjUS|b)V3|0DaCk{o
> S
> >
> zg(nfG=VL~76{%+~krFd)LMa74o$iwJYAs<&=l>=C$ao?q<TY74aQVe85s036nK5
> sA
> >
> zZlF4U%8K&5(v9>;K6BghvpZFj_f|I?V+aV2Oxtwvj0pUDM~Y_7r0D%A=CBcD?
> A-H_
> >
> zaM|6YW0k057RWKFX()&h`2rEHRWN;$j1w#6y?k}tKvZqO5pdB?bN{VppLLrXq
> Cg}S
> > zLrkk-
> #H8FCX(~TuDr3@Czn7;N3r_W(8Cw)J0So_haVPLuFW76G=zQV@?(a{qB$or-
> >
> z+VMN2%ADrBi_|PspH2GZPrdwBTEioW8OQeX`i5Sb*l`|YPr)WT7V`}x{oHoGvz
> {}W
> >
> zX(smItA4K4FD0?L?CvwumiJ(~x~V!UqON78WtP&ZH7`k+k&oIy#6&Zw<~p|qj
> owW$
> > znAFU~_wY4f2q?dP-
> TA{<^Mn1>h(*+#lDQpI$IQDXBKM?{66ITiV?#qWM5N(}D&U93
> > zj|M%z_0A$&y8G65!Wr&Pnd5c&!OVJ9drZP&@55fj2IrWIQ}>-
> &vpdCAooZEI#wk{a
> > zgx#R4{ai15lIvqI^i!SW=(qjUKc1v27dP7Z8CgbtcNnyc0*O?G4Lj;Lw-z6u{d(T)
> >
> z+F&TQ3Z0eQBat347c;Kh@{>|v>E&2q>r6VMgn|dX3X{Nyd>`XCZuE^3vg|(I;c
> #~d
> >
> zb@`LnuXpJq+h_GYMf+*5Q<k>Rzc%K~Rg{xvlofJK_*c64xn6snyN9CD0%kWB
> tz0zq
> > z`{T8Kw42-WR+^3%EG0W*<~H~Y5^-!8$pgrwMF_^dwKelNGA()21;G~Z5-
> iu6OP@(+
> > zl3?OQBuGw%Kvy506y3D2Ealok+8w7b0K-PIj15aS`*DtCSF5P?(p-
> UTYHHHGHJa^R
> > z4e9LSAJ3h-
> L#Xl#|AfTWd?2PBdir}bJ#*uf0H*de30J{rlp&Jj?wWD1^K|`15UCeR
> >
> zuA#HAvAOz|4q>gKvj+17z#t(zN)0g;GE7o0Q*UuksdP*0_5icXGZ9fv=>~X8jO
> O<C
> > zIaO6rvgX1Sc)tpANWK;dxZK!_QCV$^B-
> aGV<R9j?#M^F4HzUbtwklL`dfBclo_Adu
> > z{P2CF_9~9+P&8xNjgy8qGur3l%7)lWs&<0y#B<54<-
> CE_@x)deTU#?kEtpbb>pfJQ
> > zHpmnRMmlhT^0sFnO^j;ri4e<fbW1#&h8)*(zCCmz__n=7W)<OMq#-
> <B(*%Bajw8bG
> >
> z8t|_vqFS;ct|XjQPILVEU_XvAy45$nmXd0n4iEBrh&mveC~u*x6Ty?@ThQ&fO
> 4pUp
> > z-
> SOHV7X1WPBb9M>=KevHO6q12M?qC}4Uo%$PK2}_{a@$%L0EWCuqmB<jkU
> EqfGQeE
> > zsxs)ys+*k-
> a<LS?0&`X7^FqA%;<^~8yW(q`yK4jdsFw1%6`nyXYW5~>l;>afDCY~j
> >
> zz0xRppPQh281I(n%<Ds5E^=ybvUnisUD)lJ*1NB(MI@ThFw%8)eNnfxu4Q2G
> *Aw_D
> > z`pX6=`~Txca<xNgGlAlLtXNkpUFznb-
> 9NHR2$sm!(C+=THSdf0G`*$wC{1<Jzqh1D
> >
> z^ID+>vSwaH^LlJAv~6je8V0!2J3fGM>JE0HpCJct4;A^5CIqv#+yRm*Dk>%VRb
> 7X^
> >
> zaEOW30T55U1mdYLACr^!+>)v)D*;`5XwKiV1v3is9wuCpmL9U?d_IkEq%eeOe
> pj>)
> >
> z8rj(mJCDhJ#=r^|)S^O6D=J;;6?LwAUK<rbGYrOKJX5xv8=vm5sbG_bVrUD_4I
> D<<
> >
> z+V*l*IUqI7jQnNKWCFOv=IkpI{<wtA>#!D7r|N$A<`AHK<;qzmmGP<CZCeLEF
> (`3v
> >
> zgckP^pN_kbow(BsTd37MKK#{m4Q^eeBGg5J^qQ4{p)=pT%Cf)Bn*YAKp<!=Z
> @Y8EQ
> > zWv~6Pm)z?6upGJQnAFrAPvnT26jgN=4=M>-
> &_T{>(E;Q4VrnQyjtaxZ$Y@4|Ar}<t
> >
> zFi~c_+%%6YTlVtuy8KFA%+Vo_ik<vx!3aV4#N}l=G%pwzdE7<eC@gtkQ)58wd
> +-Xd
> > zF@iS2N;c?&GGNFv1f-
> nCYX$GGw_pthGcYm1QLmS(&Y}yZ2qix;N5?AwhGp9zFlqL!
> >
> z^`{h;mc|=KfUv%1XVbwa>Reo6BUy;r)1;*Ix_5nOZ+3!7OcsC&l{Y~<^xnx)FPB)
> $
> >
> zT(wOsVE=(G6j6<Z#<IfE@spK<<NZLY2*03U4;4D?7mUBb<HOXQ9edSOVIF1
> MTTEJ1
> > z)85FA&k+NWVIwM!q-nl6>W!olBM$tvu&<7isI;$8$1LCkTs%Mn+-
> iRa;O_hx8v1pM
> >
> zytV;@Pd%7Hq5d&IS}DcM&c2crLcP?EBXt6N`!ERRbAA+Idh>ZbBVcYm3!U~#V
> Ji-E
> > z@yX%gA!JSy7+fjhUc6`+7#P4Q(T7a`MxUf-sO5jJX<w3#j_!sk95*{-
> <qQVg#k>78
> > zgkxfmcIZ1)Sn7}kn1C#g7=Zg@{tAo?!<E%UQ_G{3?h?~h)TQunf#-
> fvwHu8795}6W
> >
> z#H5eB2Vfbl%LkF(qMU(B+cDO3uQjqVqlTq@ry$%1Z`GMZ3$=@W&A@Qm6-
> `X2@$m4(
> >
> zkAA<n#eN<7ZqQ5Onyd9@IQknp?c<(IMksN_du|V|j!cT*I6BMlXeKc+pPy$;9
> rA*%
> > zYs#3InBRHdV-
> hebA9x6ZLhn6C6;mKArSn;j3?O?1VLd0)`fsW4V+|i4vChs;N(t}L
> >
> zzxORFDtbfp8Q1LVZ=j(c4{51Myauc~v<&~N!rm1u+Ms>lmfMuLU>#3re18H>0
> 99|n
> >
> zy(jMtEV}firKOM{ZFFZ>f8@65@vkQ|Xu`Kdpohdjvy;+?U{ksH!hn)<lYuBZ19&
> @u
> >
> zzur2DtEs92?jI=h7ah=_12c1S0)aLYO_w?y)$)&&4PD&s<!a3>DENKo+y3R5=6%
> Ib
> >
> zGzQdx3&`_%4`1XTX&gKPf@QdM5NQkG00{@&ilb@etG><|x&R#Xj<?@{mU
> *R)a;LqQ
> >
> zyP{CG;No^qJe&P|%j}_Vf3m=g|Mjkaq&zy$chr*fF%1y$LsbMMByeD`A}PP&
> wvUtt
> > zAno82YLb`qd{zS|fA16}(H`uS*3JF%IKYtVI9L;Ju$iiS4_pD=nGIE@Rk?e0|BD4c
> > zYjjx+S0ZC3yJM7@H*Rw8Uu{r!z&Eo%^_zRzhKAc0S5KraKE-
> {)&!(C4TBm|f@HQxf
> >
> zev{VufNzF|+;t3a_1zsb2xpD&afB0_JqOR!YcL97@POpi3UOib3JQmpha(xcaTz
> x&
> >
> zOu$Gx>L5_N;ING7<fW%E9V5Yok{&AdAX?hYE>o}WKa(L+zl#Sq)w)#13u5%=
> WmbM0
> > z<k;Iyw@_OaNL-$?o(UwTysnX)P*=ZekW2aF7IN8Fu`57+F1~q|40soqArlPDl-
> q36
> > zJ-V#v@2uVN;-fO$>Q3EFRGqzz+RL|C)SEv72I*ZVR7LxhgsDEe9(zERxLD6-
> LubBc
> > z={sgH-
> $it>Zu$Km0eAk{IXSQ{rXX~7V0`d=?2067?~0;;a@s`iU=+C0RX#PgRugha
> >
> zjp2*{uFE&z@GM)tDQqI8#mUZ4Nq_fIA7tJ1kI^;fz|)qZ`~gOeqHjf7rM2#VrND
> hg
> > zB<+^ij-ki!v}bU&*9f|^qzv4K^(1pB)lDoR(e>s(&CJBEz4iA#{Ohp`r!LIk5#>S$
> >
> z7o3T5Aw?;Ir~Q{0{tan@mVKmXfG!QilLZES2RC8c$<BTSV~@nWC{PYY4l2VwB
> k2bs
> >
> zWU&a@*gr5Yb$VC6Hg3V%A&i$|r$ln0h?X<~ejxRkDBW%3bjkL;&%&3+H1#(
> t_TQ<~
> > zPpkWLsyFv=kpB8wMCMJ461d6-
> pCbtOKF}LM597LXt^A&pRwRw98q!!F^8guBWqSJV
> > zr~@V68iN_D)Gs;XkCz0TsX-
> UHQ1Mi^sc##}gBjVZTlZpe_MN83lYe%tK`Sg&@uw9Z
> > zIQm^k)g4d<<I-`XDjPImuOoV3k-
> fz>|30ZAI|(k(W<|V6rfi2w?&bVP=E|GYt!3o@
> > z?NNVoMqm94?a?~(RyW7K;mU<QM5-Z=vnBp?f~acRU0XtZ-
> q&>D;Lu4Y*65q0=*^{N
> >
> zJ~z_keD3Z`w0~0%emEg?SSLF}R>u*S`g}&TwM4eMHWIfO;RJ(Su)h1YdScE5Ft
> TbF
> >
> ziDTuJrA!y&f=+^gL|`TtST1?31}M`#moTOg2qe`2_kyJVP~zd&y|78+zCZKrXIHv
> <
> >
> z)UF|RBN|!?16XpV&dJy);mH{rFB#D^b7oDY>z&>;j=k+UTyIVH8IGTJgEn2{J>X
> vL
> >
> zdgjTdzgd;q6>GA7MEl@M*wCdAvKV&S`|CX=t0%pehwYG>fgEzqD%AP16p?
> Y5g^7sU
> >
> zLf>7*JS&k}_6^20dy9IbDp%7JEsuW+wH!W^lEeSqNKiomj<^3KlckUhznKifZ0*
> >4
> >
> zE_!)y=_Ewh<SwI@`cIRD2N_}a3>LGL2K*Z6D7{86tEUr6Af>rW7a0vsE||xbk=t`!
> > zzUkq!kCo%uLaCr2D0!!GM4dVBn`v*$-
> 5rIw#A>R!$S=Y%YqN6p8ylZm`2kn%InZ;K
> > z7(3x`Ee(xdzXG2?^=>&bu~p2sZxg>4nRfOVpVo#cI)JlDzLI%-
> 1#f$3B_;fh#D$u=
> > z0SPWgD^lq8%^ky`)?URe2rJyep=)<^H-
> JdOHA$qRsqPN|9aQ#M)bXn83O8fh4VJ)p
> >
> zWC@ZRKOt8~{#dP46~F3A$CLt0er|(RLGgCCg1<&AieZ_Y(_nlcLcRN@pv{H3#
> MZ@o
> > z-uS-|mI+0|HP^V@kgUr6i8JxWAD=kS1>aE=x;G-
> ;I<V5t?h0H4ZJmY{X!kNZmp3lj
> >
> zHP1~KY8PZbwNa<67*>#8q+12=NL$%Y)L+k(Omwaq`GwWNh3{veQY5reoo#
> 0G7mqVU
> >
> zZ}4gfx2=tuUW)*$8Lf!xV*vrMwbtJI>?ITXWyR<*^}vJ^nd>Lv&VAoW<oa9AN
> x|C^
> > zHI?xRN2Da8K#5w~#^DR7VyPCuJBujkzhiio22&X$G2_PSQ2&;$Sdk>os-
> Y*<Arj@T
> >
> zBgZYqk&sZNmFl5wY?m`+eLu13SuH+zkA~TYqjSx!8OhT5*dlRct)*Y(S=y!*<vr!
> U
> > zv&u^91`JfQ*$6*pQVC-
> u91K$*C|OqggzBlgrS{#d6}kP8jk$3_NjD(*bXW$B1<`ZT
> > zM!<GFs}vS-7&0L%ha6ln2)&oLwe8<2qv9AvpAFFGB-
> Dh>thr$2oA7josXpNOr1+57
> >
> z5jy$&FT~Q#hoF~^`tk^(W1b}FA(;i)BCS2Lb(YG0+rOLId=LiC(7oJ{dEm@R!+fm~
> > zUK--
> r`G+6m>P#CX^^gGwFgFWdb7NfYzw7q!X89+`)cz;PoNcImsxT{?GExC@YdV-z
> >
> zQNMrLPkc0Mq61&ieAn&f<1E@hBp2U~t?*vXFlD!!lO1!t0DGb$zn|r!Iu(@oDY
> VB&
> >
> zn>g;JziSl^ICap5w{h5#eGWVB$J2=Sx~AE<ZS9jM`Q7BO#IAAG(1!LyT23~$*w*
> oz
> > z@o`0!-
> ;pxI%3>miLvJ(*K3{AHTZZ1r@s2bxPdi7ht&W6c{iRzPMlK&fVT1^jWbe`m
> > zSCR8?6JGt;@q-
> >Hx=&(%y<L!#y871I4uEhpSTZa;`_M^rKrWvZk^C{X1i$*e&B-{Y
> > z6n+-tCLkc^7WwalvMRxYYpwA9e_DE{_qqMceQQ(zjH(%sZ@Ec-
> |Ni}Ud%P6Tnb329
> > zn)?!Y8;8Fw%_7((T4XZnVN^5r#00ct>|pan^z)QWY-
> w@fzc7$VQ4tNhm5V8N(SdPS
> > zemjgX2%vWp%#H=-{5i+AdGbyyd-I-k#r$ed0s8()pll8;CnqF7-8-
> C&&+<Zy65#V5
> >
> z`muCcmU}w~g)h57u71)|mjZo^rF{9~IwTdpAD~X6WKA{T4NnvGg&hsfYb6uS
> whf!j
> > zHoj%V;v%{IZ#*G1QUmD{KDk(NxO5Abn&JHhr*xFazXZj)!E#;GH#Z}j-
> W2=miHTno
> > zX2~4?ou7zkNi;j=G2vMODkB-GC^A0To|hQ3vXLfA6;mW-1%->>1-
> qeL<q;^=2F}T|
> >
> zOx1EM0#4u+<(ESu7H_=m$RcREL?j&rJX$E469B5EpGLG%E_eUUI=kmW%(xC
> pwM(WO
> > z`0>B1JR`+)ZDiuFC!F7Fv-
> o{nNs}LjLmgaAC6@n7U0(G&%#Tte_%S&pL+Q?SKoF=-
> >
> zDtmlst&$pckUytb@##P0WaH?Co1;akE~Zvk6#AaOAIct)4pU6&*S@Y5`rEwHP
> (nm$
> > zgn7NXKD%P4(&M*qR-
> (Xa0ESFjytwle?((hbQ(+J%HI((eWV?|UN_$%s)~I_M41c<p
> > zdl5+YVUfoCx4z6{uA%Yv73`|Qa22(H#Pe7av-
> 4<bCdT@wTC>GBy~|DLthW;7TXboX
> > z-5&3FOX%1i^dQ2GnZ!Q`s0&McGxj=7?N$3RKF0@SL|U8?^U+q0i&C-
> ixZ#a}(P%71
> > zoBx|Sf4X*XHj^d$b^%BJ$C%pg-_(?ktAU2?<v)q(70gdju?J0dIpy00pg-
> Xm`x2Xg
> >
> z29yKpcnd2lKD%*tV6pX?e>p>E?CYBc=_%k(;7C*D{wNxkOC(}($k{4(TM>PI`LA
> qe
> >
> z3T7;){DYiS#d;XizuxUJL$SNo@~Ysw{k{+W7ot*gVo^s(DMlvR(W_n|;V;z!hRps
> 4
> >
> z=*8)G5{YRZrdlssB7+G)ktn&em?Jdj`2c1TJ!IWnsP@e)v+#1d{xGOk`|zrKt5H`8
> > z6E%O(^b~(EUXk%iX#>N>Lc9H_ln{cN(pT4P$E;ENu-
> 7UEtjFzgP5w#}NelsZ%yHT-
> > zH|7YArh@+FLkg-
> WyQf46u7m&^N)HT7NdQ=}0@MIxojeK!Md;ds_=`o<`7w}3UO`cs
> >
> zSq9bV`0WT)a{;h;xTzQsZYz+pMj(c>AFQ=DSU1aP8_^Spw^*etyn3;Y*umJCxL
> B)0
> >
> zVJ!(NVsq}huZVy?i_$ETPJ3j2dkyQkSflDW*bJKun$r%|8UdN9N9=#B#Ffq3JXl2
> 5
> > zwYj@;E^4?Qbs%M^x|g>zUX-
> moN|$od7~drZJroCY)J7+eSWPy2RV{nT%6_5A!IRJo
> > zi8=U=ZM=s)cYP!LsAB)eX5uM~{k1h8ZA^WE?DkQ}-
> u$+G_O!aRmQ{dO`@hXLwpm5C
> > zNU0E*bSwaA=y<p7h!n2{gdz^m6hjdNOsa4B$?xekd-
> 6Ob;XHAbX$!ujWY~NcR9fz?
> > zA{m&^E5y==&`JNCtrsVh*i&iF-
> ?WlG(O`6`mEL_JQUgwBaPs9#n0&1?v~&GzzdjmI
> > zz;x+PIX0*)!He3B3jXcux%i`s$1TSzmIhZ|A7~p-btFsIE3F3J4|sECJO+3NPmT;r
> > z(`8ufm$uiah2N>{^Qhe=|MhLVp0?h)DD98pPi-
> 6N<6qBRAbW>R|5Yvc<6M7$Kw`6V
> > zykER4;vQBS=$^%S^!I_lh+2`B+qv_Wb+~*G-
> KqAl?$!d7>ZZeK;OxmNkYMvFp2q4`
> >
> z*_X9xhA4LNtQQ)&M5X98{Cc}h1cMary%8+q#Wnmo$Qymy;)fmc|FZd?6#lO
> ^|E7=&
> > zinFr&rqO5i{Cmn-
> mAJE1N!glf#G~FQLF|qUdbujR_V?>J#%wH(*F9ik_ow}}_*Uab
> > zHc30pN2CH7^FPflV`?8Lkh=0-eEKCgLk}#seh5Il8IODKzrzPYl(CeA*!pA4!Y7FO
> >
> zcNK3hn^UbWsG=E5oFhhLR01NF<xqMLIn%ftP`eUoWj5`cj45HwZ^cp!`;(@A
> wn>R7
> >
> zEEjGQ5}5DUI9$~Ih*~?gcI)QdeUX3BCj2aW{>4V{DCIy<TH#C~;9t(FPF}Tst!xc#
> > zewYu%j%O4VIkhZkcWa(@`nbBocs8IhjubbMGdg?)z*90m648D6AVD`1)-
> %FkTXOBB
> >
> zP|d7HzCfgS*RL;hANHz_r~p!Hs6y0ZO@+!h^dm<`7mZ%Zof7$#MDt_Ao4elt`
> &uLj
> >
> zlTA~)`J0{6{AFmh>r<9;AS2ova>u)4Z1TkboMc&8vdDSB#{HD%CBS8|^oC>W({
> |*p
> > zRlWes_wf0Q$g*lOC7XR8&417+%2g^63_9()r=13yuP|1G41eo}^X-
> Z#BGRQr2oaKQ
> >
> zd#_$+Bg{K0^Up7W4+a{1r;$PL8Ssj_G$i|bLgIsVR!0QASuzrQ_;{v!^GnwR99Kt(
> > zbzOY7HA@@`o+0LcFXikznk{eR9I5V|q-
> =mGP;tP2mL@wi(xnoq6<%Cb76W9}fNy@K
> >
> zF4uDWWX@y?A2A7~G&*V}EuZ~zTROtt+d75Q^yxKVtQ@q#Ubg5IpK8&A(0
> OpL)Fq>4
> >
> zErMqAnr~LWvSvJfHSe1W@PUyj;UZ2At;;Q7Mj3n(H;m=ZyFLHX<^K(SZL7nG!
> yfMt
> >
> z<lKI>7NpD|;>s!T`pJy9MJHe@%}s<PgouB+T?Xtg_Z!oJo*p_zMoaE_&IbV3t@
> @Yi
> >
> zCZ%slP}8E+YP1XGbQS{uKHUm|flMd6J4@rg@~QrbJf!8pD35rBzsLrT#(YT7u<v
> E`
> > zjUtVz<q_fN%&R^EuacaYaBqF8KU2UJ_a5Y~(nc?yT%3%k-
> MbjCYgyG44iG*#uQ@)u
> >
> zC~Eo0+!?wXfF_mS@^V@9URG(UJyZo$#Zq8jtvc>xb50M~*bS8Dvdh%f3zOxi
> 4PQQA
> >
> z4N6Q0m5KFPLBQoh_3H|C6MzE&$Q904i+ZL*IxU)qSkhGy1@<>3O{I0mF5x4
> ~<o<8e
> >
> zJ}o`^kZknMj^K^@pf2%K;$BncL5PdD!y$`_9jPK>COL%E;+~G=GdHZ>+ERvEU`
> D<J
> >
> z=Wqq$#u+z+R=nqR{$^T7btF#I^z1vUF0Pnju%bYC6R{)QVoM2h`KX_$HLK&~
> F`F4&
> >
> zPs(%lZ$`Yqrg~lh7x;m4Qk#E}{JsOmT4;3ixhwytTqz0e0X_o`J@$XW@|e9&<Bb
> E5
> >
> z)u+jJ^U&eKVDByaVWZoE<V|~U7y5T2@0X%B;AYTtvrQS_1+2dVh+#4)rW7%
> z#~g=O
> > zh9{BD_R(v;_{}ERQ1I1{)S~QkD}x9$yg#cWJ4BpxESCfGRavH|BW13aNZTUNI-
> ke1
> > z-ZpJYw1!U7&e`HIVD~KgfNWY`f~PR5eFhBJF!X@;DRi-
> O@I~^x{;?=(JqlKKAP)z9
> >
> zPe)3O%QP@$YFP8XD+^%%H<rkhV(Vm=4|slnJh|aO7eO;x7Lm%F@v=vGeF
> %*F9!4P^
> > zyR*NJ%fROlEcM9ylHbSJR3%{Cx(Xf;^dv$z8$)CH;$?BoY@-
> LMnpxxcdeCt4<N)x`
> >
> zeaXSE9Sj!T9KIyL<W774x5aQ(OW^pVa`En27HV&SEQh|@pu4RQgzOlfCq82#h
> x6wR
> > z28k-
> jcUY5ppm9h3L;t#(2GQ#6lWs`@p(qB|7<)eFYmFBgp@wBRt0RPfDXYFp%FUzQ
> >
> zn}6@up?J+S92#hdiV%=9_J@fH$KjmA$&^W4>W1z~Zrh3Y%P|~N1U)EaR+vb
> 4G2Su$
> > zH^C%0{a1qN(iF(+(w#;|+rd$r68U3Rbui~QXFz#$U51!&-
> TpdZ4Sm%Z^!(mu%Q-d6
> > z8CSq{iA^TAM+Sba`K-
> HlTk6WjIG_wd9C79k1pK0eXjm%0^IIaM;|$XBS{d|BrFdqw
> > z#ofha9&>zehtJv05)YpWl;=*6Vj}fRiXqo~|NWMDdrL;baJJt7$1m_Z)2{i7L8!Ci
> > zg!H?V9hYfEzZ>b2-$<+b<AztA(jUwsHd^O;@~4#2cDLNrS`yXTbu8v!<76-
> YD!;>m
> >
> zjB&$De#dJ{mHM*pwbUUD*Pf8A%@rNWH@7AzTxQxg6mG!STMF%$$lWW
> DlU4VKO$Q7#
> >
> zj<tVmn{k<vCivQalJFk;exw5ND}7Geo?M1%aynP+doG9^H=|82azn9_WrgMJ
> Fm!6A
> > z4@VEIi?>7&LjzOGr54aZ7ezt8w6N{*-
> Vgc2$XvJ4eZQ_!I8<s`ny9v+Fo^KWgt8s2
> >
> zOeQKB;KBO9WF|DtI+Ym)isg^KtRNur51V}joUmgP$GQ1diiHnwu{`V6IRojEQt
> quX
> >
> zZF#mXp*tsygBG?5s}v{<6*>>4To+de*ZQ3rp_|9bMm{m;4B!x<99l@O*Et@=
> bURoM
> > z&{&Ho;|`1Me}NhH8)OACAto;^XI|Bo&a1pPpyLC@`H$(t<7;ou<}Y-
> Si5+SU@T;dh
> > z%rOmQby{_IZ%+E&=Z&z>w+wbr{TG8b-
> +I~rxJ^NTX^hUZQ_xQHPN@RYRbv=OAaP0<
> >
> z!)K+gHS$Fe*lfbO*C|+bqW4U|T0xD{(Z>%k3p+Kc_9bMkM7eS%=acGlFamrzI
> vYry
> > zy!CUS4MI1%mk{SZtX?ng6^x6BeANh0BRY7-
> lW*C|d@!U{tJ?&fR|s{4iO^7Ls>&a*
> >
> z{lR%NB>eI0($Ie#o3CF0$0n?#{5ID|>sUl_n541g@gI%;D{iRy=?jx!x%11WEn8-K
> >
> z17`}vk;|Fgj;{k?2BB;r<`exSpt>`x>0G_?<Q0nlN?rSH3&JT{B!s`_%yAp?rA@9m
> >
> zJp$cgAZ(6J+lT#|aI%6{HU`5~DOLpAcD?3v&g9UyK5T}S;RxPvAwB|Kpk6jKp|7j>
> >
> zcmodM5g~7gj&}=aeU|zkHpu$9{UBdyFz%8LdY{G)GAV4UGAe1n)jM4U`9vq
> Wd@XHe
> > zvn*f~#Zp|_nC%d-
> |J@ekX6y7s%ZdqaOcP#sZ2A?~^~pHh%=*1;Ol&FTn*PyU`<x-t
> >
> zby0_YlP8BM<ovRA=BFZaw|$vZ8~Sy~B;(mmxYbsH@<^pnZbYkz^_L3<)v8P}
> Vcny<
> > z<Be%4?%IXUd*NDGwV6S_$v&yJMcf1vh!W$!segV_aoH|Nv#z1<=d-
> chHgloBWr|bA
> > zMKPos+7`2YmR-*0?2%Rd{F|r|JY6s!4dfPQz&>Y1%!Z-
> (ytQE}L~vl8pUl{XkJ#~v
> >
> z;sH3X1}Nrh(Y9Hrm~B7jTOA+;D$;{1q)9UMo!X#p>uRu<fUQIus)2!d{R}To#DQ
> Hy
> >
> z>7l3si>V5>pfBw8sdZX#?`q@Ws<Q&;@_30GE*shPuK3Y#b1CVvd2{<XNp+ed
> Ju7Dn
> > z#$NH(cP=x%L()gfl@~U(N7?bH-GZbh^enr@6%pM%$=lWVk)_-
> YI>c&n(Yp>Lyir~@
> > zchZ+(5g+cYwVEu@^U3%4MzZJly-DN}4%m{;HtH&Ur}UQTTiu5LT5eya<{dT-
> <h!%=
> > z*&>EVOnq&ad$05T2-
> 6~99;0)?O8ht^W4XIVWE^+%1QjLTmw9`uGN1TrQYC7Tcf_kK
> > zHG^0n+f9uW<J}r^+=cIy$`USIRdRCe#39P}DT&3^rckugt4hMz7-
> V)~VYWQrveHMi
> > zfN2G(b{o8^p=!#x#k~@yQd$o(uwxv*37^>ZHuzGK?-
> }0}e(EkUQx{gt5Qv2GI}9Ks
> >
> z!FA+PVttK&n5ITNqbQ<${(Ny*IIvO~r$yUR$LHq}YA_20_9&v5cC_pB{rsHv{IN
> ~|
> >
> zB7M#sI}A+1R|XHK8NN|<rtz7W51&2QF_xTNri%(k%^rBHTL^I7o|e2?GrTk&Y
> *YvY
> > z0|VFw6kG%(6tX|SI!<GU(Hk2Vq04gXV*OW-
> `VxgtihK5w!+4bR%e5W4fcRUBut}=3
> > z-
> )H#z{^EH0s&$?+rVFb*_4hmDVBE4f&*f)m{)Z8!2gv<^3>?XepM!W9v<{Ch*&
> MCZ
> >
> zEF7y{JOhdOG5S)Z($t}Bx#?zxJZpFAj{EoC6a<p;gE`5X2g8<Yv^UzpRUb>cxAc&-
> >
> zkPN%U70?8E_}W_g4yR3~ODER0cWV&_yMN)mSf7TZmJYEJJ;(XzaN}1{8?lJ}#(
> sm;
> >
> zW|v15IS#dO9dsVb+`K%|mKLYQ`v7OWY9)1@bdrpTxA4UelW$>kG1mb(AEzc
> E-_;{w
> >
> zVv9Mg8#y&_C1KUXv{3&vsjInK?P9k!Kw6Doi&0<KwSuYmI^c}4epJ1B;?<1w^
> 0R!C
> >
> z&Oz)d>~kXXEBt*YUNYlNg{`OjGDM@t@vB^MR!o!L29CfzJS^M(PJU8iO1MT!
> ho5lF
> >
> z`$pxAzRQqB;CxvAt)ReL=Dy7q0zA~F%vdm%*C2G9QrcWxaZtovH8AUID)+jk!
> +&#`
> >
> zu8PN9zz<AWZJEPEL(vvmuJ>G<&w#XEzPu3k9uOxp3<x~(G2&TkEf5h5j7uVD-
> m$*V
> >
> zr)B9>vPLR=p7%xB++>>JY`3Ym=1cbF{hIeo;_%=veRLANh;W{kPO*~jh9Ym=(j
> pta
> >
> zJ#<5w4$#12>wlMDi?Q+qCH<ciXFhozwX_dV%<X^6cuSRKFZiZnb5q&f#49p+
> &`~cD
> > zL*i=?4^towDW@6ZZvX}XxV_8p+N1b-Y>&-%){*~b)fp8lC7<PovN-
> K0fBZT$@>U5(
> > zw~vYQ9)g+mMNjJZO;ypyUQy?DgnWW;aSj0PJ4OwJ$*tKT?cr-
> }{HlC+M?0#F#>i8(
> > zj(X%<dp4jcBZN}QPI=}G-w-
> x^sR;x8X2?AJ{$d)KpS&IL=DK`u3E$}cEn5fOL1>WV
> > zS`8a^L($nQNdP{rrVC-8TlIiTojFTos2}fBOiFscXsX)|#n5?>gP~&Z3#V=%(_+lQ
> >
> zmQdIJC^%^V$8;U;ldsWo2VbENGMHcf5B@mtFMr&y(|nzbcKOwdz@ZiC4(u
> wJY7J-w
> >
> zx+Ks20(N33@8E+U|KdOToNfZdDa~6%EP<tr$ItnJzE41(lobO@WNAwftrZ?w^
> NQcQ
> >
> zsIteH`BI8wvcZq|2;Kg%_Xax|fz>xP{dZZj_rNL>t_;(&;OH1@qf#edpPOC6I;7a~
> >
> z{GC<Xc<@n|S{X1*Z%k_i_g)CCVK<UvCZ$jIDLrWX(fJ3eSy)h5=q!E*Kp9@!rF9
> om
> >
> zgZ^v74!sE+GXZx<YD9i+E|z!Xp6r~D+C#eYa}(3qJ|8teWa74`Cgb+oViT%>T79Y
> C
> > z<!BcWm*#gI)Q;$>P(-
> ^pt9m>uGwPUJs;%Dmc<IPV&NW3Gs2&<1OJ~FH(z5#$VQ0FW
> > zGH;^fyr(a?>xrm&;uh2hKqp>D-
> AtFAT>ifRM4qagM#_ICS_6ajaSY1HT~q@|ZC7aZ
> > ztaZ-qOOaLm%t6oZ9YOn=E(10@DEhaBQ^B{m;J*XHXO%^W-
> *{A1{Q)=dfP<Z?!Ajpt
> >
> z7o9Sr&Hb+cKp_J}DKZP{|HcjLA$T~e5=zhcHzQ8Rcxy#4_Jut8O5$*1Tc%4Tuha
> 7z
> >
> z8}&Tjh;wZ^t638Hny92PRgSsgD|&`v%!}OsWN8K*Tl~yqWVJVu06$yrS_UX5QJ
> @Ox
> >
> zT;Dpg0?rG2zZ$zEGV%BZg?BCcOw8f0y<7`X6u#1)S6Xkp)M}F2uC?#KSb)e3Erk
> 0l
> > zVjM=Qw37|BK0|)-
> NN#aLCS2l&_`Bh{)byonNa}o`#PAx_!nIovQ*+3JX2{Vfpr&Vj
> > z@@D|n_ZN4O{9DvE7v{&bXg=ZEU10j+T06D%-
> {92vZFC<}cxt{&w}6A$>f^vt-IIUz
> > zX7s$Ye<j&#*8FCALqPsB!R@EE&&4Hrm-nI180{SGtq9({9<16*BMh$-
> 2h|Tdt}MtL
> > zVNPUku78tD_L%o0`Dm5lH$DhZC|4-Rr-
> NH4*=bhL7Tc<AKzmQSP`%KB$^O6dpaf~!
> > zvuweI{|9?$MSHwds_Wa=JMt(BCJm(Zcel=3F}}$`b4q(=5Q*e;uls*dp^};_tE-
> 1A
> > zv1;CZ!z3UqKTUkaP--
> mr9lV{#l6K~@id`k38|cvYSujvU4pug>^T)D3xwFOZ8inw*
> > zJq48N!P2zA_Le>{HRZryvx7sxFBEjO-
> t@Kt=4N+y_aVRwp>sWU)5nch6!_jmvXsEg
> >
> z%$!+V90Bl80U=9#Ui%n}MY*{_G{_A()IK%<m7#6^$^!*?4$aLC%zDi4dd^Kw$
> ^*M}
> >
> zXkHveHJ{5oNB!|41fZtO(8;Czn|qG|^5c>v=I79ux_mW!$AgIV4X~k}<PR#v)E)}
> v
> >
> z|1c%UOZHo1nvp%Et%%VOgL&N@2tA7**#bGJG1O&e;>s5<_*oh?*l0V=|CL
> rZ?;v@B
> > zFX;42CfFR9Kvq~%Gs1tQCKlSdOh=%s4Xwrdnxv)GDjtvS`J`;LJuYdg529t7-
> fZZ_
> >
> zhIJKd7B<@x=&7cQcLS_cUj$bRbNh#&13uJi8UlzLWi74P)^>EXzpkWPp;|BJhb)
> OG
> >
> z#&Ei(8!pvdspXyV=i${Up0hAgi5h^Wb~1?H{9pVD9Y@}gsp&{O?oGe~dN<z~J
> Kn{X
> >
> z+n=&#uw4x}Qr>^82O6n*dqw;mEZ7*Vbz2o;mCVnND<zVT6%M>b;%aU3w1
> pZ%wkIe6
> >
> zemi*WCg>N{vcSU~L|t^<ynjl6ijeCa@?1+_f9hHm6#5GFvlcKXY9&?}RQmNlyY
> -pR
> >
> zAM#^HG4{E=VMIXy1KC6L9~`NHxIL0PG74OqKJLE72EncK6SK2kYcmD23Aq75!
> sSCv
> > zOI0V)+9b%8^ak8NWz6d-
> k<Ld=+<$zDH<z3>{d)@42l)WJ2A>GH8p)7XQ$wW&!*&3(
> > zh6=X0QmwWX9XHj5l1@tYGXVhG)-
> Zn#wNpPQp(Ni*tcC&}=@s_9N9{m^<n3+HQzlwT
> > z8x|ZZV|V(-
> wd4GPaPN;R*6Z=9B^dVhCge(M^jW3+2jd}ku1^OwuyQXhJjp32hHPsf
> >
> z6DIzb?>7aA+He4^nN0%FUx{<W_i6w$0TBn6zAE|u72j|$SDpQk{%&4P$!4gLs
> s8V7
> > z{e3`hv)IR)|6IB5)LOXZbEaOWxBzyK3p*{KL7`B{M5>R9p`js?G!6Gf2r%(qy!2Lj
> > z5_5g=+O$i$k;%-
> 1M>+rpv2FUU;oAEoCod+I4AQd1PxT+aTHr_Q(XcxtT82_3RO5%a
> > z&O<T}qZt5_qWaBg>aO+r&Y@1_u$4#@6Kr5r`tgZ#?TY4KvNy0-
> So=W!Xm2z-qZ)Dr
> >
> z8^m2cGOYXS46uyhP4^P*=m&INK2G2<@A{gSRyt`X3hYM1dK^fTL+}^NLZ^{;
> ENpfA
> > zzk3E?iA)clJzkV-SNG3`oC94dvEie24TnC}fAb4SCty*R|Hd3Fsy^+To{DYevJq=0
> > zd*)2v-
> xNKm?zoMJ$O08k5I%qLA`oC+u2@)UWgnwP<u@P4!UG&PYjVT$)(&kXtIl50
> >
> zJ}1WN3?uNP2F_2WYW;=cZNmD{HLl)RQRz+}Ap(|7PfhWqR;jlEOi+H!az=IbR(F
> Um
> > zF^Qnb=V^aGoVi%p5@5dasXN&yO+sp{#+ONfnrQat?UBs}-
> _g|Ab91$j2ad2jnt+=M
> >
> znjCz(1JsHajoS0|`t>6;eSLj@h^2*Ah*VpG8IY#cF*A8@u>iY<GV}7DfqP)e+A|S
> g
> >
> zqs<C(+dnbs*5yiKfcv&oFm+Cy1BT`6)B@JqG6){~z3feWu%pm_?E(k33Rcw>U
> YQmA
> >
> zI8WBm)>bz$fvDymd&q+x@}sQA2c<f_sGU)JvrR~<9`yD9IW>`G$?|`vCe}M2p
> fHM#
> > zheeBy00C`XV^EG!sQek<Y~eR=4(Q~q@U0Xzgy-
> p^Ljf0`_wKX+3QU^wzXrqcJ5VI=
> > z%LFpiFXepsrY41q`+wT|%BZ&9Z_Ub&wpc0dr34AZ-KB*Pv``$1yL-
> `KrNzBi@nXeF
> >
> z&|(SD;vPIWMN`~bT;|Z3|ID4W?wy&t*8Mo=3o9h&J?FgdexJSfv*iGwMI9ux
> =r;!F
> >
> z96}1HN;3idgO@<TI8b+N1&j@3cs_E)1q!HMtEs*8_iyemeJve+4RqfL4**gcL4t
> xQ
> >
> z&i+6o{$dvafj~~h7y%NkV8YJO3iJNYWD(FK;1&jM(<$%k>I4u<hi6c#`mXjQ+`Y|
> p
> >
> zQ~;Fp`38`OX#rGxcXV{fbKQ0Ta!s_z17iC8Kx&(I`I|M@3zgG$4`qDcNiH1sBtD#e
> > zpR`hDn8<|^g<Bq}B3EN7^j=NLT^ZBIrpJ3>Yp-
> =DEZ9aDLwe&emQpH(ng8O8f|N|b
> >
> zH4zVF=tWGAj{(Yv%El$BwtDY|5NCd~!c%~RNFsPLpIkax{FbE+m2e*mNCEGL
> O-%SX
> > zodxd92WpO^vu+MB(Ot!|X5}KHpF44af6MbrA9T3jq;nSxa^c2UjNKutm-
> Et@op^sZ
> >
> z(PV4)b@KbiS8rjzGw$P?ecXItw)q8{V$j=eyDxYoUV}DLJO6Pn`s?hon36WXmc
> W5K
> >
> zeC?m*zsJ3==oWF0{f=>$@(SQ?X>i}WprY8}^c)nHHkz?39XcE59xU%zt8YcTGe
> s)B
> > zH2YMPwJ!112bA#&L)YnAHDB}U7u<sCu=-SC!gda?Go`T;wm@o-
> 9JRkFbj^Cvi9l63
> >
> z58nGIm}R}|M7|UH&b8_z*ynv1aq7iMqL7x2F~ms(rw~N6Jaf9*{>CnEEbXR8v
> +d4T
> >
> z!H?wY3GK5;*W!A8nSjWZMeQonDZ4tS9!9|d9K7}vWPA=hs>q>No93mL!zR8
> ^`QF}Y
> > zTI!eAjaQV1M2^`)i<P>gsTGz-
> UdJ`7B{!>?&PTBz9N#IZ7Q}*EorQD*yw`m46ew<3
> >
> z87)+@@>(M^Ut`PfHW8}|%i=<N?xc`NrpCaT`}n}e@U*%y8u(k&li4>UCc;%`V
> mt<0
> >
> zY19ko`T>+{%Y{D8hI=E}P4~qK*zJbkX=pXoWB=tV8_9Fq>lL9iVI7j1nu91wBMk
> ^+
> > zElX15@Ap6nw7R-_Pk(=YZSDB>?wr}z4@Df7I=$YkWCI|xaIF4J>Aunc44=-
> Jy}mZu
> > zVB~u_KPu<T66E`2-qm`b$h=GFuMaG{c#}7$jH9k@qZ5QLTHAzL>VpT*x^-
> &~ysjCF
> > zL7?|Z(k1dz6k?tZnBXFxqxH184E^{C=wY>+!4Bu9r<Qu!eNsIjjD1RwMC-
> gE$~l!e
> > zdZ_HM{s(D2$+Aw$$&kBkE&gqbzpoI)JN5kbrU8XeX^-
> Xvwp0G$Ypd!Rc|ZQdfy)>q
> > z?BI#4t8>*l+N0LsLb-u2@`DW+7Ms2E^o~CDw9eY+Dim&9i=t*5M1?<d-
> LF2U(N;ve
> > z`|0v08lJhE-
> 43hj7M93rCRyY)ruFz>1_a7|nX6fl6HUP*{cap@cO}UZ@<goxCFK|T
> >
> z%F4<OvNuafHJI7SS2FDy&)mB0ljbhKwQn(5A^fvxZfqLO{jotLF1~I@2uUg|H|`
> (m
> > zWwd~Q=4lm!YtSf_-qES5MxxWX5+^YjA!%d?VI%<-
> L*AxFh1pz<SsamItVw$U*KSpI
> > z-+A1})>Y$ot=tBi7`EBHM))04PgdG!C3|W9<{kXTRqd-
> l>MDyh5Jwv@sO|fU(KJG;
> >
> zpy8K08Rt3W+MmJfk*P`OaguoF$9nZ?<S{+yeKSKCQ&odEmaRXsI$XZ^H47=_
> Giy|~
> >
> z00Or@+!SI3@2(P}796xp>J0956C(_vOK58T&>4}Bc#K~++)E^5G(maiYeE`Qw>
> 1jO
> >
> zfyrt7iK^I<ox&6{Lnj3c>wEQQ+J*?%=trZk_{Gy$lkm=9OHHy_pQQOeOcoE|eR
> ~#6
> >
> z+q=ps>#7&(I^=|n(|XZdHF|p!RCT&7<C5P&LhoBzV(T4ep+H(aSIa3V@a7~?>
> W;)#
> >
> zTEK|~ccm`7FiosvPELCIOk6XiH$ch>A#g!g%l((Twgs9NcL2xZ?tVVqRX8Bfi7*Bb
> > z$n8i2c(^-
> EOiWof3)PnW_^kmbSk2ZKeVaMRDwzdd{9T7PtDzfPTc?57m_WSGN9%7z
> > zFB+{S5NUxY@NrVg5y?0uv}1zWMw1yumux<qW$;;3PcdRyqF2jy^?_J-
> iap7Ma7+~R
> > zr)wN#;gC`Q+R-
> b8%JY{4`p6?)P1CDtmZvTm7K0LPh4s3mNRsVKv~x!vbuA=Eyo7sn
> > zx@d9YxZQ9&G%`VB#)^`&cT-iR-
> irr8)!tUR=f%wR#a+fmaF+6kzw)!tT!&ux?VwHK
> >
> zuCRQCF<p1?!rDhL8Q~wE#w11J1pzzZljIxUqc@Pkt;oQ;Fmv3ry6<lCEqT4=mpz
> zM
> > zlyIFB3)8W{%ep1;@3Hrb{On=^UXH!1FF6ot6ZH|@2oO-
> 1ug!MMyK4jY4r>~c*wq)=
> >
> z5?4L{`uv*hRA2IQ)4kErSS*9GunX_1cOFTm#^+Qq0S_N8aP5_s1a&;6i#5R*bb
> FS*
> >
> z#Db~drQ;Aa&eVWFqd6psvJd3Dk?KJ}Uknv@r3)=#4fmUbwUKvs`O|A_AKkp
> k-_@X*
> >
> za*eL7?SPMkL3#Mtf*%z1>q~Fm^O(3$n5ulY#_zgm?kq8Si*v}taod)R_f57Xu&
> ~I4
> > zMe~hi*!yt-
> e2@cGqtp;X)4Jnhep@aWVS>r+Rl}i5gWL(xnSd1YyG|l5J|Z@riBWB@
> >
> ziu2548b&%$ig}HP+<|uY=W^UO9}UO{e0b<S<nh4pq&I&%A|NP<V)48n`wn%
> zaMs11
> > zN|%vFr}N@XKRz-
> JK(IvVlAb%GHn!aQy^#%r)@n*RS;GtVOQ&_lYHpyA?IeW&XA7Ak
> > z|BUSqSDI+U&nx*Cp)_JOt)3ZsYS9@f(N_=-
> In{tAe0Yfk<0~_114e<1n;vlOL2uYM
> > z{((;&-
> ix@kelI*^8AameWW5I*s&~SkPy3v1>ZjEO^wg2}iI@`LHGrp5{`?7&l|=iB
> >
> z2WKYg$hz;*A)npLAqFDhW~J$~Et+K@5LzY|*bBC`{GYy`MKz}pP*MOH%`Il^)
> SKDX
> > zFMo0>$uK8=q*ajp^RTu-)zze1#Eo}%IW~w);z&_-S$uXmO*Q>V`-
> jSejso!@e^uJ<
> >
> zH=Hip!+OAv4%1Y9)7<wo)e?T<r%vj&7&qLxT+fxRj~D7w={!vyZ~o0#6|mRjpG
> HTu
> >
> znh9Vx+WVghIM<P%EaW`(cIIH)Ro$XDS99(t+oB@L4IHx_IF)vxY+{Od6l}Q*%Z
> Hd+
> > zMY-
> =jqb9OFw`mb3_o8*Oxi?pBU?8}!{o7@(uN3xlO+=M%`(_VSDZy2Oh8!~w+k&+
> m
> > z%ZWm1z4nMfO?(4A8G8!-
> oa^F)^bC6>Lk+E{^unUcj(<8ok$m<aj%5dlof$?D2+-^I
> > z9ojx%v+LJ=J=z*8Qq7pk7`FaaSmSh2qYT$=%j57^2vNM--7&x{W-
> 7FWTd$s&4e|4?
> >
> ztQSQgM~N$L*jm4yQu8s#{6W$`jxn>E1hV`C6L73}9SzVnxwo=rr_SPGbV#Wtj
> #^0e
> > zhFT#E%_-
> ^{%chJ(LL$H3s~fl9EeV%b1tireNWgxw(yS9Fh10OF`DDS~(@Q#A;E;aO
> > zX{e*o%yIv-
> brwX?Q~YrlE^JeXlDw954>|h&G0jx3Jk`q8wav0M)6c16&UR#e(bI)d
> > z_4)OXSo-JfPgfZ(AGe2R-
> YVZBJ+*!NP5p{*n#PdT$%5CcZufy+LZJXLltOOg{bL)B
> > zN7V9i&*xacc=!0|AknOH#GgKi3x!mF2GoC<(#rX?v$__j<_vqly#hA-
> +T`x7hrGd7
> > zZOWlBGF!2ad1;q&4^YkJS0ZOaAe_m)!p5V|Cb(G-
> tP(~dNEPPRy<$X2&|cAe5A}bI
> >
> z)8Q6FAigLwicp?s`1<U4ug5?_$}BChGF2$hJD>sP<FI@brs&I;V{>Q7Ds))BBpf(C
> >
> zspM*Q`~xVaHDGf15Y#}Cmk@r4dII$}U>*6LAQk~w5Bal&&X}hqBuvN%mM#
> g8_@a_!
> > z=SdD&-
> %dC)aGBKy)I4VY0M$&(C#^RUo{0JFU0~cf5`J}7vtU97C`<ftSwBBo=e006
> >
> zuO?Fsvf#dLyUk)97+Q+_^sF%To)W`5L}Pa8vN%XI;Aw)~K{nJm;aV`gjO=7MR`
> q#N
> >
> zoo}Q$dj|=6MQ5saUfExZ$A^%%8yv4=AnR|fP!@YkmnZ!B+D_k}hi4|v2=ag@
> M4b@Z
> > zXSZvIU4G`V(uwN`H}{O;cDm~aWbK4z)=`ORx_(5zbD-
> D#cJI{S4sKPkL746lL@;AW
> > zDssgPVVyB-*vr3ad5~B-
> )<7A_;U0B@WNTn0Uut!})H;sx$}wL|$6|C8Ma|7~&fwo)
> > zF=J9ad_Vx^JlO*~mkzgt&$$62$Jp`h7H-
> BNMSM32B_HnUIx=z%Fof0ntPF#j9WWX+
> >
> zH+7Nt?b<aSGR#$`+9nirt09+f4aF^$>XsihnQJ&V*!l;8QAqxfz8zG2s?8DdEVT1u
> >
> ziyucuYfTQ5>J=E{m*GXCHry^)3czIoupqq)ussRDb$a>gRm`*@wwiVeuP<I5F>
> LD0
> > z%@OUSu;f1d%Pvpc-
> E1%2R%~!dk=(PjT=s4#aYid~`?u`IC4c|^OBxKKwKG976$T2!
> > zdK(Bjx%p|zQnoY<UWi-
> I&smoWNQ`io<q@N9{k0+>3z3exz33#|upcPPe9pqcjbNki
> >
> zQ}muu_e_p1GW)>}3e~L~cwX>z(@WA_pt;V{V~`YoPVwl{mP+Lx2aXx%>(nu
> P>u{Cu
> > z<sp-
> +I8_iW7;H#;_cxp03XE+kGca0!IuIij%nIU_2TagU4nU!ra*kvc;ONe5!#{AA
> >
> z#jIMcHOv@}@01qsK4h(a%J}?%jzw%?)We`sq;M^5YGBI;^;K<v%>XJrjq<ib+a
> @W=
> > zT2uli3ePmKF@Zi-kJ8f8th|_h>p3z?rYl%oLl>I8!}A*Ib&s}0-
> @yHu=O|^RYZE2p
> >
> zP@V)q<uTi3Zo^ZU5IJKeR#Om|O2xfp7ByE(Q)W)!svJwP8|Y=mr)NweJN*%4
> baP~U
> >
> z;q6G6Fl=JS@+V2SQBf~>$lOn{j$bE%e4D1Vnqye&9&>PX^~&{4Z$q3$3gL(rPS
> ?dZ
> > z<Fk}lbC7lo%G&ikqAEH%XzxeSHk)#rS(<9v;$=m4fA?u>S!3T-
> wQgkxi3VLQjxyVy
> >
> zPWRxPv4aGQ`ceMu?n3>Nbo<|EGi>#Rt`mAkcp;LT;n&fUq)umB_%qb~z}%K
> odUp5h
> > zqp!T4LK?<KJ()xH%)kcP!N1qc-
> swKrJyMhv%}aG9`Wq|8@~Fbcc#V1G$}omy4nrr|
> > z&dkRrl6SI$7h^TFoHo8KET6czwakmLGx`ZscDjD|Xe_F!FlBUge@gE-
> >+H?u5?g$M
> >
> zw}(VhAMOlLkvF&n@<&AF<gvgbyXj!*#Qw;paCw#nY^b7te+dPev+Ujr{>Egw
> GnyO9
> >
> z?n(T@juz&gyr6X_V0JPdSLc6e+@hYuR#uH$>B!E{+!lsUgw*6xrrQ_85yP&`<<
> =QC
> >
> z@~WT(uOBk~4>fgOyqV$gq!A`vHLnZ$pElH+7c4kP;{|<<yAe7t;qxnoUK3QrO
> O2Oi
> > z`}1UT-9ENIh>;zj%$I$?o}3xtpbKBuSn(l5`xhE)%Wnj**d(piT36#KJkz>T1Efcl
> >
> zWOO$#@!Gj<yc|uTGIwpIraMJW{v<7LtgYxC2|i5sGvfMdY<)(>rGM%WO^cRI
> +uw!;
> > zsCmp?gl$-
> ++k3q>;>lh+vL;$63x&F$EUqOkR))%!l_CT248JrU%W89#fZ)YJXI1SL
> >
> z(~1OHjO+(tB;@`>ZL(7N$d>6N$&s0!?2kpdhuW+eXi11grPpdDBN=(cv+_6{GD
> 2)p
> >
> zp_eQ>1WU?;S8^$Gbic@O9Bpj}j&bRXhu{8mq#7OlH19Jm|78IAP+x}FT7Nz$B
> c;i!
> > zSpJkeGG%cnK_ka^_A*n777nKWlM%foj)rab>{Y!zXnqOR3x1RV-
> Hkg6e~c%ayO}6e
> > z-D(9Q7^=TW8tG-
> `!g%&A6k~`(iN#uj@)}Cv)k3>`<Cmp)*4K6cnSx}(sIUtH;wuxf
> >
> zxDH>?hY3#t+@pKiOef^C4x?6d$FSzVi@Zc#FevC1x&+&6?he5vhx>o_#%JJlm
> xyhi
> >
> zuC(RM2YNiE%to+WhL7(sv8&L`d)QQlsH9LFmJZ!9i5Xb!JU3)FVROw7^`1%7QE
> FSC
> > zM^=kZYdDpnpozNsI71UF(<d(f$N+=nS5FP)Z^OCh`CPODz-
> *>o*46xhGpS8Y;XQ*+
> >
> z!_Iu7yerslq0JwT9N0P@pTve{F@V7takLe%xI=h=<3h)hl>g9NN3Ne=DYn&R_;
> $3Q
> > zqTtg4+aH={BK;#0=DiF2z2HIP&v0KU*QlJ8YlKwCUz-+H@cl%p?Z+-
> #KBcq!;rb9d
> >
> zjX2>|o+AZ!N+b0aw`lA^>@hO!H($1|3zh0ou=U$ttzytHD7WvWjS8|cF%<)eP
> qb-|
> > zOx|zYa;20oYTSb^$f*puP6`{=@+R-
> cN@=^fot|}fI?x0u9YeLWNC6h|j&PQWnYsC^
> >
> zO@(4?u&0wGHD>)}f9@4y4H7&5a)v|Cv3J$+EAw7DS8(jeg^846!ROx3Fo_Tsv
> $0gQ
> > z-8ayExc4kxrjbJosHXOA{_mM9azbn^p&#-
> a+SMQ@Tv59b7zfSbF`J@FL3|c(?~Mw6
> >
> zR$qM$LrL*<5Sb{nUA^}cEjQX>PDtTf&H=mIuSal7FJck;&=2WvBrgjF`9M=oItva
> Y
> > z8K^kuUK<iB3^8~SKIH={WK0!3pSGO0MNSe-
> A4`jXw+Z5jRxVtBV%J&vH+QRLKJ}o!
> >
> zI;++vd>{!%+wh5p1TOs1XfaAqQt#N&Wv3)bY3`z?rBl0SNM{UHOCjw>*Bl>Z4Y
> GYg
> > zi-_{4)CLA*f2_EP#Zn-
> |tAcPB?aP)f6z`RaP1`s7(6px=?>v+*2K+HHFEkw+<>InE
> >
> z8rB%F>eeWFb6c2A3<InoH}m;_a`|1Z&730*ABM(?g;!AYhc;pKh8>5{@@DFyZ
> QYoK
> > zk;)5&CWfDIeK5C#KL}riyu6$<6F;Hj)uVPQ-
> ~nOx!(t6Tuj$h6t<9;bWBf+@Ghs!M
> > zk^eY1)OH<SwP6htz7@s#fK>Bj?W!o)Ed)pW*@9L!#y5M5Hw`{-
> p3I!HZ(Q(cX|H6u
> >
> zAzp*GE|tO(`}+1|I^)t(Eihr0bm#1nN1QYAHKzSHBK8>Bv*tVHbuc~cg%^mjSi
> @wl
> > z_;!1XK_$>Z*cweMTnp6<qY3+KbxTcnkT+fHDp0{_(HnuDh~}fk3_-
> `ds;ZHWg<Ato
> > z_!d&4;KL)krKVbM_-
> %V@8o*8l!(tXYkLbeen)6M)u=GxUrs*hJa)e#)$Eprze*gX3
> >
> zR8te}b~!Gxn<Y@VW$^EL4Oe7xFLin@sNv13iO_q!H7&B4<wYVExpowF9eW?
> s&KLw+
> >
> zF61^N^QP+7N$vda`+kb)HKyzBIc4ekv%gt0L*&DMbg}B}7Zv5f)ZsYWQDOhkB
> (~6l
> > z==pSlrsfT~2W{Zj-
> #*>h*M!v6{Qwss+6pidN;yE7Pw|~oQ%Kh<h?4|8l_EmdapUXk
> >
> zHG3jkN@a18f1X%d_j!)So5b&5Pfd;_ngJ&b*>!Hb`++i%!Z~E9^34V7jnN2nvlf1
> (
> > zD_(Z0@z?c85CdF~w<_fOLU^-tS`HPN(z4oj^*3)uRpWxwkd{eJ$-
> Ow%eFF$z!@J+-
> > zb)lh55pDiC=YD9#siX}?f~ltbr3JO$_#`P$8Rkz29uspIAsdbsZ`)|(K$Q?$Pa71R
> > zbT%WycXONGV>}a@^7z9!^L8UoU~omZ_gZr-gWX-
> `hOL3Xr@NJ=ToO<irYaR+Kh}Lr
> >
> zL}!}S<<x5TTzCBHypl10?DRVqP&57kIb%(6$iTYP<T}Xc=oc&lHeJg{s+}>TbG9a2
> >
> zoznr|E<9pplSL!*DqM$d|IjxT$FhaKGxdX5I@O}kE%i^&VZ;ETGf8}yOY)uS?1{a
> Q
> >
> z^|C=#UD#&~KHcMo4|jT%x3qDG?QeHK!bKQ*5&gxty>x}N4j+NCeq3yAs{E?
> nC)ZrQ
> >
> zukzv9qt<qA5T@M3{n|F+N0iE)J4Cy;?+DN)xt!6+;VZxgGq1QF`b1a<RF%~<G$
> 76h
> >
> zl2Xu5>iwSfHdFZ5cFlF?UA7)<^D$|9j5~V>Y3RREk)0#>lp}8S!gr5S_J%L^{XsyW
> >
> z%cqi7sM5pwY*r^oVhY)kF;=^O<bAQ&gp`yikMm&`D=S&=FI#tLamk1U9ZW=
> CWu8yz
> > zH+|jV4`bWI^L8v=4h`>lK|zu`F7-<S)$;uces}9sVW4ul(i+A5r3khI6vHJ(Wc<{)
> > zw7h-
> b*>IJdq19OTW?XY^GD#wCu5m^0(W}*cB5GrMycU7a0+BxUfhsLE;lY1k{$z*$
> > z=zlg}>gO`p-
> 0g^DbUH$Wq8?zqBp20d!a01nkk#WOzBi?!VogblD+8K5blt3RFw7iB
> > z@QO~d@a9xlIID<dEbs0cILm`V=!&ZSx1@>M;g~{S+PHiV_Czbli+U-
> }feE_&!ul@}
> >
> z7OUd1%{55<?q#T$h^q35h!g)o%|{!!_(0Cgos*(W(R+L!>6U(Ex@Wya`yaBv^6
> nc`
> > z(~=5}Hs0)7ICsYU*e?kS5ATh>%Nz76YL45gB{r2q-|Ef-
> lUuhQjhP>4g#j`eZL{aU
> > z*(6I1SaLpb4L0MXg_IC-
> N)H|6qMH^~V?Z}WsHvY74cnlQgSb_aDAyTHsuc;Xs72C@
> > zH8tBwwh-RR$0c_Efy#2fSz+zQo{D)-
> >k`wG?8RMnf$ci2t_9S!ov;!eUr#x|K^JMe
> >
> zR%1_P`JBDqIt(m1YyY*@r(!l>faTk)U+h8V{itX~bTZtXQ;?#taSU&}Ftld=Bmhg2
> >
> z>|LB({lj6F$j5FfPK8T2!pu#@L;JsfGUW3L&0y?XA2eU#PsRmZxV*m`+P?Jb=oL
> g7
> >
> z^^Ed4DW%_oJ)4a?I&&1f(}<v*`)@>*{O3Dq?{d5WtAZuY8HZ{(va@E0%sxF?F
> PSu5
> > z)ab5C!KD#<D`;Z6I{4a^p-
> 05n?xE1H*&$yL=t?P9bCsD?xc>Kqj<G<MkQE|3lDb{2
> >
> z|2u8zMRWbQPW)z#O#Y`dtmH8JGnqdDL`V(T*TkYk$?DKenZVWY1chr{1}#?^
> h{bn+
> > zzMkvwlT&g=><ALW+>U;|>cmIgtDFDIHK+K>m+0Un`K-
> @+a<=!C@tI}k;wK*4uNZt+
> > z8xp=6ry|dbC{6A$XVU^!r|@t*8o<lX&~<QN-
> )p^*Y(4Gdy1chpzMD=e^fghwH@17p
> > z#Z>i*c_p}xH_3JEV-?-opWjuW>T)4rx9r~csvX17GmdD@PJF_IcekWRVg`@-
> 1E7@!
> >
> z;D)|?9z~iC*K#$dSOIsMF!W5eONt*UzWYGI{8rn0KU8a3K1VWl%Rp=H2_fZcv
> UZA3
> > ztewF760qW#RzsGzgh?*giF(Yce!2*s``rfoq>iBwr+)wn_Li;K0NiWo9>7l2Z4J13
> >
> z#!A2h0xjphW+jrIEZ6T=4LsKX8ZI`tEVX@8eL_fxO$e}1^o$}Rl(!s^%~B%p(5wJq
> > z!T3S^`gEnBpn%)7?VlP1pyNj?0J4I}j70u@qq4g{R){-Dw4YLTRiZn)E7tAUy0|Y2
> > zTiy40B|lL^##RaI5JTPyhR}y(&-ORjhI4+Soh!l4X_A{=S&?v;w6d#2KuFfy;J6NH
> > zBKe4`-#wpBt#PlE+D)4q`pEm66?GHj#C&%O^8oUM>^AsyI2SXk7hg-
> 8vb&OJYEp}s
> >
> z5?FcUV_Q}tiqUB2uO~`fyxx5fdccVlVVdokep0y};UJh5NYdTui4x33e6;Q9Uj}Ox
> >
> zx$=?duaoWh=m2bYTj1hp**5u}WOs`IuKdi~>_&uPE%k%0PQ~n1{HH1gyNjv|
> nz{aj
> > zjcb4;eW(OV7+p3-nQ9QG)q;{|l_}}J-
> mXjWCUf5b{Ok~))qO!{n)8Cx9l!tbFdViT
> > zIj6xh4vrXLH5ZoI4$A#3e^WSsk1LPXX5jN5+c4E56A+*Ejs<}+&-
> C_W&g}sGsC&Q*
> >
> z00P0G_7d*x7w0KwB12w*Q4Ic^Cy>Xuzpf#>H$U26Yq#gBBIyR@q=2M2W@
> 1dFnWtdD
> > zNVk1t_y;mT-
> k+?w2;11$`~)`P+7U`h2qDH?O_W`iWXQBqqRSl>4v?GfIM2(@vrq=F
> > zDjf9;-
> DU6BkBSGThZ5h_k2=n{S$o?~nMa)0z^8k&k|^KZtDqxy=L%=>bOA>YLuWqN
> > zwRjfyIWini{Z{Zc#TL&V-
> &#~iq(M{;5Y<dgUa|91t1tW5M^oJ68(+{7_<7q~3GMo0
> >
> zJt@W7jIRPCQ3K_vaG}Julv*h<EK=hnP51$@bBvG}3Z7slrIh%L40}%<r>EM~5p
> h-@
> > z(^?a}xSr;*>~c(AHpQmc=U{t56Q1l?phjxu@0-{&T$IxAANwqg=tL-
> f>WK&)%iKHW
> >
> z6XNLJoRXnQWC*=j%$ic3B$rjID+ov5T%sk7^dXG=e?w#LbVck8!QpNG*Gqg3
> ynKla
> > zzKcV{HtX!!3WKrl`Ohp-
> {h4Jx@4z(yop;e|*+VU%2_1tzA8H+2m&(73<n8hyj}D!B
> >
> z>iO&qe)e6BFmeV&<~6WB4cxX>`F*enMEYLjYC@zlJa{Ric$cPQF7q}UyuO|Pp
> Zw$e
> > zyi{Abf5L=PX*e6JNx=5Lech-G7+dL*zEd`*#$^P>QsI0Y-Bl-8U9|c<1)1Ep{*8c;
> > za+_9!J)*OdO@3=78DOkJ0B-
> !5>uL`nfG7jIq1d5>X^l_27aXSeQ`K%O+;$)&0g%mO
> > zA~JC7t|<SMG*}7GN6Y$7CDiKB?241DGPyxbMto<WjLG!K$w)7I`?=7Bb-n_-
> Hx_2|
> >
> zU>hbJOizZJqNeA7QS(Hn##1)1wk9T5BKY*urFN7I4I!&m);xIa6!D=PWDkmM6
> R4Rr
> >
> zjk*Ep|7mZ0@dks=9kxy=1G<F&o3I;U0`*IVLeTry=H~g+h5(i|asndt{`)5$bC&1
> N
> > zH!gjF^i^g67$K|Y8!NDcvPXqzS95a)S65dnFPVbHU%>zLl}xSx3{<PCs!B>tO-
> xOd
> >
> zQ&7MLPDAVp9`7vz;XYzuR6zh&4P*h1n9H!KBb<=o{4HF%1dojBIVrY8x&|w6
> &u@Wv
> > z0C+zs0E-43%0;hP0k{Nx0oXL49~a>mK+ydQmVvK3-
> U2rX9A=^b2@4!NSpZK69Jd_v
> >
> zzk519ZBG{mS^o<`uG`bzf9T}KGk*a@DJedGk#(YIjs=oHobdep{(k$Py{1!q$f)*
> a
> > z6vm`Vw`uXP)aHTBzwp`dPG&AE7jusY_A05)*wp56-
> 8|HN!VHDt?X!7%VRV8^)xU0D
> > z^|p5FO7zR8^SbZmA6e#3Y|$mRap}3O8;PJ4e-
> h|F2yMD^>eWe)o2zdCq!a(n?9>#f
> >
> z_mJpnIVo?96z`{r+|ow~O&Q1<5%}*1`Zc)=r6dqmrTcR@)^6*+`fyU^B7{~q`ZO
> }F
> >
> z@|O^I*l45&W~^}ozxwrNGC)ytbNe|1WTvmbiWqqu>5E<hy`~yMub)){&hD
> Q#qTm(t
> > zMZ%RUL8!a!Y2p%TzlgulNKCsLuvuq;-
> }$nZN`2;&{?_Co$jHqWP>VWqdb7EZyG(6c
> >
> zAn=dDR?`I{ToFxr)7{2x!zz#L^ECP~G%fw5yn;GNHc|gftzMGi6&B<1lm&H;pRU
> ra
> > zMX}`gm-
> bLL6ThX*#I^k||LNweGq26Dgssj_kteG!&g`TS0nvdcJi;;?sa8x5c4SgU
> >
> zPv!o?g%#~zy2q;fokrFYYW{6JE&k#&M^Bw?T2V`8y}CqUl&>7YZ2;5^L>+mJ9h
> <pq
> >
> zzSrv*D5`8J%{$h0_N4}QTno*82#eCo3>esZgPvcE|APfjRJldrMC~C_RHCFk&eC
> Mb
> >
> zst&>>8N(wmfHNuIl9jAdyHbzbx}4iqi3$&wr+c1cRFQC!kjR(#pa@rW?lSnxedn
> ?G
> >
> z#CBpH21G1wPTSYtt*?Df`5l8URy1hnvsbs}dN*jUE`t;07Qv!0L7o;A<d$TNwm!
> &o
> >
> zcK5Oq7a(;$xaQ!)nc|T!B~f6b$<$5ga7+<v+|zqFTfH8y<MAczXxCz(xFvS=c7se
> m
> > zux6Q0k%bJO#W$~g`Qy#Rl_XsC@By^#e-
> RM%C;1ods}_Dy6=&aE!DH&yZe}Pol_s&^
> > ztt&=Z6-
> Le_iVG=mf=o>N6{nRl)z%TjTdGO5XEg!gcpE~TKj0O!=lWgMdK)w?4?D}1
> >
> zz!nFuvzk^4sZ?@oZQb?%RWcZ1ks@U3ckBOk1O98?yk6vdU1W2PfO@tF&(G
> 6Vm*0jD
> > zb1+gW(1Crf5xLvlJN6T=aDF}M*i5p(IG(nx_*93Y)s&oz<I~K}ODZD1{}F-
> R4|toS
> > z2pydY%10h4Ql|^g&a~-
> aM2MC_k7`svOk&v*Vb>6){v6@o3lbKLF&m<Tw+R|>`XAJs
> >
> z<yCR78;EXviqR8`EdvDj;ziHpDUeSAb!gQ53f1F=m)J#6_{V`5ADc({5w0II=NNL&
> >
> z2S<^)%4bIg@_0z6COo`{<K<0^*RMy_JJ!>PzQ;huUz0U!ok?8$zaaz|J}=D^(A-
> Mf
> > z<-7K<$G6OrXCLF&g-
> X%tW!lHIQa=)4iQy+A==s{za?3yC?9tXhIz^`&_(Vcq)xEpN
> >
> z!T6k7U7T)_AVOdM)zO1p#ERf<gY*4C0o(}cWwEBsFMm$UE_1*)84tZG82H>il
> {Aw9
> >
> zTY(F_%Anj@1LgIazbSM(bgK3>7?H^QlmyUCQ!h+6cu@B;O&mj1O|{R9kS*87
> CC@??
> > zRwRCuFno2oIYB@B%fkLR;t7mtCb34KikGcndJ6ax9xo-
> ^_Ot?JdLg|1aj$ifpl{V^
> > zb)w^n2VVV-t@VtC*A44_3k_Q_rgyv0P65ZZSOIZrkej;(3w{?>C-
> R#Vcu^1XBSkb=
> > zbFl-UrM5pvtq4=7Zq|yyY<{VHDeQ6|c75U}r_o--
> &31)1TQ|Q%EAhuIXZd?<`#dHj
> > zbWs+n5+Ao;k>5(+>7SAh<4hFbi_CSriA&sz0gRop1-
> k2y^JQ>&e<>!r+45@!bqRSD
> > zut3i~-
> =JV7F@E9SGWcBKr{t4+V(4bZ#J`?u(A8aaUjvhsES<<fzMR^li)`7~5HO#=
> > z8@e(3tmNqVWq`wXV!qG<JTY-
> Z2%3t^&^quv$J@hc<<E=4x(WQHVaumK$V3e-e`uBA
> > zTFWrH61TbJi1%fq_Dt7FoGss{v~RQf5Eq-
> a`x7HIXwJ=fQf_ro@BbDbjW+5A=13?M
> > zstD+s|GWbG5A<JC?)~Y8PBY4$_1jS`;wgq-
> mrArVjc*XJ0kT0YL$?T^(tr16{tK`A
> > z|EhKWgPZ>Ur~ls#mVZrM=wpi&py%kb3~~S{6JDBqmo71-
> xIa;QyQ+A+=ch*huDSEC
> > cv#+HZ3T0=(U9vvFOET{$$f`i#(k8+G4Ze(OmjD0&
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git a/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> b/BaseTools/Source/Python/FMMT/Img/NodeTreeFormat.png
> > new file mode 100644
> > index
> 0000000000000000000000000000000000000000..6335653ece1605cd0c53bd2cc2
> bc21d57d213dae
> > GIT binary patch
> > literal 79906
> >
> zcmce8g;$hcxV3?SBO)M!NGTEmGn9l#{pgk!hEC~Jx<nk27LXyOk?w98nn6;!q$
> C9i
> >
> zX_)Vf;=T7T_+~AaOL#r+i6{2+oV_PN>6sM4je9pPT)03WBQ36S;Q}7}g$tKFuU`
> c}
> >
> zxjwDT5B|FNQbkJiLO~DZ3it<}nTUeOg$u=DkQ2iz;NST6(ukKAF5GIy{khm~mt}
> I{
> > z0yaZNTtv-
> PZ+!~CO2PEFeG41g%h9VUP97;8cawlCl`iUPR2Ek>T@=GWx=P?c7MH&Y
> > zSBgmL+qc~&-
> 2%O(OFlj$dbRs>r7wH*JT_;RYP?4%`aSmCho`Ly&8B)!Pm<pM|NThc
> > zHq{J7Fe7>@C#~Hkw`&$vF}E@H7&cTm$`Dlur$M-
> DQkUsiWm_>>F`39z{F@wQiMSjA
> >
> zh8txDpV9oG<xI+~)<Na5UR>aPdQ^ZYeX&uqR`9ZN+CA55q9VU`Dbb^D(rxL}#
> ^-oj
> > zN4Qp*J(-?sO0I5g1&e+|9j2qhes5;fB-
> Z?J6y4G$f#QS`{r!ZWGF$U~MZaye%g)XY
> > zl0(5(6oe)n+Nla$Hm7YDI>K$o%PeeX(Ma2$<K?y!6*jg$Ja*IT&kJ-`eteBzIy>1>
> >
> z<TdHIJ(91@Yv(v0V;t&$gpf@eVSP&B@)47U*_NHA=Px2UY+pe!!bu_`BXy^0
> oOF-(
> > ze(GY+PNz-|cTO$duNND)-
> {Lhy<L$5J7S=q^*Q&lj%B+;q^!6%7aifgV=HG0eNR&%J
> > zFfJ=AE4g9(8&CF^)52;vjN7WzbDtj$Lip^O-
> dx#OD{OQg(eub>QT==~l6(hlr){Y{
> > z0H^)?A-)z<Wo~u&P`|-*1H8&v-*XE&QDPb-
> jJ!<=Q(fs#^SA0tzDPno0oT`LEuzyD
> > z|NEi4N?J7eB336yjj6EnN4iYpWX~u5)0H>hwJL2tX+-
> r`IT%N?Xt3UUT~e3sOW%3^
> >
> zGFpz*Y*Q03r}|H#=4kT#m<|IC5)Z)%m=}!e<j(m4JbFI1Z7V6+_9M5TrppRN4&
> kvG
> >
> zU*NtgxYa@u+o5SvJrdFTZ#d<*)I@OjORH~Lv%jm}OK?&AoUAToQOmkbLOz
> 3dR&s7P
> > z(sv#iy0K^!=uAwMTP>kjbysIL+6(&Aq-
> u|TuRRVZ?sm+jANn`s#n$I(^UTllmapEt
> > z`+a7*-M`#w#C_t+=k#>;@U71okFK3>fcP6f`iF2BCXUNu?nO_+%FJ+kQm-
> &}GKx(<
> >
> zQ6_j6W&A%Ie47d$ztM1PTS)w1`t)!qsX(vZUEZj>ETQQl@%fTFWGY`_qF6=>$
> n-t?
> >
> z!5Rh|k<p8o=vrV>V18&cPs#c8h%a`cq8*odeoniu!Lb#(oN4zK$E^xYiH)NqBJZ9
> *
> >
> z#0UF2kY>>IW+PHjXv=QIRI$Ql;)iYRPoC%xABu)U$LOc~NzPwPxpgy&jK=#Q#
> V4Ni
> >
> zxWr<R!KImiS1F))z_GyvPvZQjwFN(fhtIn2Z~UA|#Q2T^<ETAa&5do*G%~D3o
> Eu^%
> >
> z!&f*(jnmqX85E{Tv);WNoC#6nT_4TRxz~Yz&p~?l=}<|P%|ykx%>w($>HbW?i?
> 4C=
> > zMxIuk&Az1P^T|{0=BzMmerNkNj{7XXiZUnsp;Qeqy)1jcR+-
> DI^9d~!WoYX0A1$X%
> > z1(QEM(YEK)*}W|zBQs{+{+vJZ{LD>!p};4!kAJT%&A7`wA1$|vwwkKpR=-
> ;cGp&30
> > z?`-_vN=Cl4Z9H|xR%n+Dppg*Wa?7EZmSy9Vf%A8X-
> )f2nzV!Q^qU_$m?x3Qsmex3w
> > zfB37Yzs|WK+>%UNSXdx9J>K89E2pn5vmT3J4h}$}r^Ct47j-
> #eg0l|9C)@T=sxzAk
> >
> zlV~Q@&s75%a*qQX8eMk(E$VeyPm*vW#p4&jK0)xYe7R^=)&~y^8>o(Nq&
> &ENK9U!c
> > z$>Hgbcsu8bO1pi#Li$>`e#2z3dOp=LW4-
> eKJY=bwrSyQ;ZQBGptmP=XzcCg2MbnmP
> > zDdg?>-
> mDYVv$d6347N39pc2Xqnl5Q%tI#uWQ13{Jov&$cd9KcFCud&*&uL>aR`2d(
> > zYnUwZ-
> 9O9clq<SvvJ{@LU3pYF7%_Nuw8o~9rIbR&10C^5`{zekM<Yka?XCu|<D<#}
> >
> zVkQuO;27zK(sb8{56>ULE^9V;x>b6gx?_2?Xcuu&Dj*<0+eY5<?K{cycYQD<_t>
> o8
> > zKdS5_ma)#(Dt)1l!(QW>_HT$pt<KI){&xfvKW0Sb(x;q8bma|#i;5lxpRY7V>e-
> W7
> >
> zyh`gaPV63n_Gi3Zg98&2Q?9l3GXjF}bF1`}EAyQBtUys|HNuK}$_51Ef>$d8YKD_
> P
> > zLL$x|O2|$4_>pUK%4O!a-6#4-
> alCdtcx~+{I=l4qiOy*bg225Q!)=A~nShCGZDZIT
> > z`*O5L^inXLpWTzaUm%TSE<U`-
> Wz=##8ilGDY+F9)QwsR|ik3_hIV_0thn3yLbfsp!
> >
> z&QZ+jsW;Nfd9}{B%Yiw}R0|yDsrC!}2!(i_>e61Jc>LgvY4d+0WUHXQT8}X`i8}>{
> > z^lSW|pVzqU{FwTEyxDkMi6Q0+6WqH?a<>ujtwZ(i<ma9TZ7*VK@BjR-
> #Ov6((sC#V
> >
> zYXUamEa^SlX5CJxoV0X|p|R5|^NxRORrCjuWel!e(cP#UT89gy!1HS&pFQpT<
> T@9C
> > zO$PyP14Jb!v3EDOuqMNCPn~kKtL#&-
> x!><Tef5Yx99CZZ^Z}R2`NFoA5OLzRlU4n=
> >
> z!3rDC#xv5>tH7y`)PpFqu^6rITv)dqxHgax#D8`$uM2YTRG9GDGIk}8!|UjkM!m
> Ze
> > zuk|Q9*5!@y$-
> x$@%f=*ybzaX+g4pw;J8{dk82oHIQlNYG({Z6+2^jpF>5$`%tUF8^
> > z1qmagoGc14>`hURl+gq<LX+4}-(z^~5;4(iGtVe;+fp8!N6G-
> <BptWKsIz=W_P31e
> >
> zZNcR8*q+AXvV{RTw%<OBb<=m*>VCc9U;L=51I|rn=f~G6w#Jh=?8JvF5NMV
> 2&++Q{
> >
> zQ2rhamCNMpkM7v{Q+@{7oagzgAoov&OHr>RdTj7*?)w=nc10EZ=X;53yN>S
> vY!Bo}
> >
> z7Ei|YlJWXz@!95E>(Qd7`h&S3R*=x9BZ#fXN?LVYrkwPCw+t!@|2*1VnP;tC=L
> 8P<
> > zV85AA*wyD<1C-
> lp_|@)_>*?>2DGIx~Sq0~BIqI1B7R_QKB(Fsib_qOJ*WMK-ZRAE+
> > z*xt4p*!SU|NhKAQxbwBmrpho5-
> EIvc+h?YgjbdIzt_A`lslG<z*$2F3=(uzj^GK^K
> >
> z>lomNI(<K%k#rdnmo{><s!#kbHH=A~15vEH<6l4Vk6=l9;CgkV$9BTIePYvvnF{
> eg
> > zPGgnRB;6Ws5i?kv;0Hth&wlHxG~K3~@jiwtu+(=V0j$IPULC@4oA-
> UumgF$+yN^{w
> >
> zzFPg(sa~Kn26D<*?5Eo~ur3sQ4GPy<=;2$U9I0`#!p@xZD)3G%C^&+>YsMwtjr
> R{j
> > z?S)TwBe8aV#^9J{@q=?k#TfpYBC(GUF0-
> 9#FB%x&<MXb|Gr!H(s~?YlpM1#}9NXFE
> > zQ<q-BeOLa-
> ^$kBlp<i)cDhP+8l}ryoHs_IIV=0X^NrFQ3gAS6ry9WktK_Tip|7Roj
> > zE!@fJJgnvp+i85N1l+c(aOeh0wUp>Ohpz$RpdB%7X`-
> NqJL%nZt${4%ha;&H5Zv^+
> >
> zM|9?U1ow69Vmn&`NG|jH7MpYuM+^ISGqA_Kdnf<bCF#!UCIRBA1n!G<=G
> )#Yhjbc;
> >
> z3H~4^A(=8u^7?Ulw3OuI+!{!_gNl1wY$XMpdkRUWw|pA+F6m_78++=qIT9n
> _Rx-k$
> > zW;IeUU1%|hC^6~8uImxwJ$}(`kBc5JjGgrUHvse+!-
> _R)o%4NaDc$tF4>RNx6<r!n
> >
> z_u{eq*yhj&u!kv|tusE@pT7&2`%?UPMH~RAaP@i|Q)h4}?TR)U%2D5_+v#};
> @Voub
> >
> ziOT&m&kWh9y49czxoCHv7t?ia1=8WP8{Ln4UnO~N2kd)@Y=PWR6C51O&GX
> #p{~VSr
> >
> zIGh?@^4oXR^th~syA_gzrm&xU(nROiOMCa6?_Z3(i%ZHCiW!PmYd@MyJK(L
> 26z*3T
> > znDTXAA=CMO`tpZNyl$;?_5O^{jMeH`^-
> D9Xi=W|_*B95jIA_{cNB_^^LFA&C%dNUT
> >
> zGM)V_!6P^ouueED`?xFlZ})Fe#YaSx7`MD9`ty7K{Lv?;CNf+9`+L%|yn}=Ju+s@
> s
> >
> zd}36Ej{8c6yn*L(2<l&Uk*y3)wtI_5s34~(bZElBPQ5EBcYd<Z=r#2+sx$C<0mjzZ
> >
> znrn^yQuT!b{x7FEt7fZYOo9Y>GVuaG(D(8+PPgJFmGS>gI?nC@N!KL#oQ*Zwp
> putI
> > ziyxBQO@qOH{~drRzzPW`NdhK_tw6kaeKj#N(Vdy(Zm)Y9-M=Kg-
> y}h%yHH_0Ha8<A
> >
> zmkwYVX0bQP$3Nt2M#_VK@HJQV<D=Qnib)%|N9s?uF#x&DvQfl4{_i6yD0Ps
> >6Mc?h
> >
> z;bk@xJT9H|(M6u=jr8IFgMqQfjdU3Q5DMNsyA=9}&+@Tzfut;Lcx~#_%YV1&
> eTQ%X
> > zvu4rvXYhvsb<~3H>~6&!D%}+1=Sw-
> 1a=?6i_UY+iWj`@Kj3!$>7fN!MO^f*M-G2{M
> >
> znpqC#t)SrAKW3iEJv#<CO2^W2^(jTrQObk!XTqn{i}N%d_jZidIOW!^mte9Q4u
> &Jp
> > zum8=!r+B_~0&G%_%VRj-TC~2mL-
> ot07njmvdGDQXScyh?WMt%s_phdFXEx;vA6W{j
> > z-
> gE{f!7Zkx{|%y7oU!WRv^MON`#gW!E}y>k^kk=(RWVUuVttf%UsB{e&F<yam`
> +(0
> >
> z*8iB%lXD)gb1StPNXH){6N8iA{5PL<nh6(YTs@0RuRihcvBmi?;TKCpIc#M+|K29
> @
> > z6wP@W%D-
> XH@4WsCAk<vAZp}CKY!&2c&<LDM`5*H3`^Ne3q4Co9Cco1On@-tU=bw%s
> >
> zteS4mvB^nnz7P64T8D^S@ov6y+B*%V`v_1Mim*O>=!YMSn(jX@pTotTk8$n{
> YugQ}
> > zM8N()%W_L~2Da%^cIAH-<-
> an}($Ydz@3FsU*SKh3v?dM0aBN+S5z|j9!}DX{v*wES
> > z%n=VDwmtYYdu9Xb08m}lrl+SnIm=VHN@<+$P>H-
> AhOC|1BQKucrND=U^;)joOarT+
> > zpjRywhQB_I`TR%_1;M7)r$@i1N=z{)+Kzlm0GHs(@)s-
> 8ymFk^)c%duzJ;nL)3Nu}
> > z2IY&773=Y1%Wsb~a@4YQo!5oR(jD&qtA{*>O7lJwEdtDQqWx-
> &f`Khm=*XOz?S<B}
> > z%8w-r#pfF@&BNC-
> fGHU+S&NWkbpYk(uHBHSODqH1vPTnkqwK_#+{kTepx?22QC!aZ
> >
> ze1G3lUS(j_E6ppDuP7_wDubDi7Nuy{xfc6iSPlKI5xy9^9tph+kAiDxUPYh~2dDP
> W
> >
> z5ibx>&9gF31Gg`Zz8UWpr6CGx=kqjS%h8@LQgUee`Wuewj=Geo^<pSnwO!
> %U)1gME
> > zXaJ!`N#R-
> _I|I&8Xv!@4n42{d+i9k`NVqy9!d<&Y>qx6jy8@9lnQS!Ah&e{FqH^Jk
> >
> z+G@oQ{%)#6*o#jv2ThyVA4gZ^E@BcXt;nB)EVe(Sp?_HUYYQMQg#y*gXRO
> @ZQJwxv
> > zuocSW`VJeuCUgOvyk>WKaM`4(p;1;@#^;QX41Xj(VUB)G-
> @!x)8v9!cbq!92IM|FT
> >
> z&oVkMM~v>tL8r^|ig8QXnPy<+WU)Og0x)S~%q+?2k5#YCw*&M&l@YBcJ9
> MRe<Cff;
> >
> z#s8EQ`nyHTA(&SvEuo6CA`?xt3cOvjr<9#XQCp}|zE~;0xD}1pZVw@$P}D3aRw{
> P5
> > zKmX|O;)u-
> !R(k8y7ThsStjf~GlU9hKJj7#OfHtwiLVE;v*}tggYejWJLZ=X@X5|6L
> >
> zPm3OqD5xB4mnPee$$U(=ggyz`D7DxYf+B;ToCZLTtYBqtkE7W+wm&QyVPsH
> guoJJp
> >
> zmLC4aDEoRn8Jd)A@`QRL(%tsEkJ*06biGF{$V`WohsFLsGJqR8fm&8xug;38`C^
> AC
> >
> z48OXUbG)RPvu!&aiJy5n9HY|e7>bl(I@>Tq*|)a6fRIuMYcJPteMELfs=^YkT~n
> 1f
> > z_k@T=OGH*xvM-(DineyiHj^h21_Ej>E4GFMBVPAib1X`jr*CZz)aEWxEE+H7-
> rVrF
> > zg3F-R(c*YRq-@%swU!k`8-
> wHF@=BC9nR%AOmAld6S56gbv`5FI^e7+0gW&R(9R2;h
> >
> z+eM4S5TAxR2~vu`Z;r^%s&bt`6WF_EOFQpLKAG571vnnp^O~BhetF9DdighqT
> s08Z
> >
> zsxS0(bVYvBY;srh%x@VvzV{|q^JKr+${DE$*FfBIG4c%{uJAOS%xZC+L_cGO38r
> wY
> > zNP-
> 2+C;q~A7BE?7V_L3aw2A+xz+V@KeC6ZSWYEm2>d5}YJZj@7>zhq4`|+3a%KM
> 75
> > zyIk~CLY`Gt({<ILBWSSFI)Zu(4{zBHC5DE=`9H!+`q<{_<u1!Tw<(o1#W(I~!6zY2
> >
> z;AhipC=V`GDsIAVx<iH@$h!(yR(Gqkqw&I+dH%){lceRSzV?zXv<guoO3IS=#*t
> WG
> >
> zuc7T&i77bNpOXN{oie>K7zdpc3NG^x#^mw^I@Ox2Xz`{D6qj6I(O}0Zv@LcT+
> K9+X
> >
> zHi(~CUo~xNk(7XtFswUo#~|q$)vT3L(CJr6DH=6L;fn}}x^Ouh34@uP+tib`uj|@
> S
> >
> z*|Qa^FD(+(a<_{XEj=(*V4rJ0E5z3TgwgUfp0_uN=Y1XypbMWJGz(%+b~XS&a
> RJpa
> >
> zZ1Ap$g(d!6OY6p{b9up{6NCg`ZR*6taPIZugRu}(x|5qo__`yydgSYN6p|tRF$@D
> s
> >
> zh#!Q*Bv!1e(JH+vovDEYe`XSXSE{wu16t9&AS2*)lUCiKSQsW_5PPxKD9@N;U
> ^rj9
> >
> z7Bp_FO))4p5_~>W&`X^zL4hW16Su`c3n|O<V9TIGsBN8MrMQ*dHB^j!uy7fBI
> 7hE2
> >
> z60eag06*Wp^(w}0d91&4JHRx;Gzi&A%giH*h~aXd7L8P9=83s&n5*}9LjsI;84U
> Qp
> >
> zDWHU5@;ZGVIPUcs`wHPx!NdSQCL?1~Y2mh=9Ci9RK14vy*@6p?ptI4FWc$P
> u^kAGC
> >
> zv1hew6P1N)0Lk)$79`cs{XMKA;WgX6c<m~~P*T_fCe!L>&hC<L=w}b*Z?nhV?
> p&qx
> > zu6PAe_-
> |zhU5!y8VPMz1D%RTO2*DT~m@(AVXvSRNYZg_PdH(zOZ_6g!+VRceWy}o-
> > zDVg;W`B&bT@-
> K>1Zxs4{PLqFR&8l6oUf}+F)lGqGvk~h(lB>bSYybVf{Rz9qYVyY~
> >
> zsz6m%JCv(Y`+IG~gM^CZd7k~wQm;!SgTi*4U5R*xcBSn`#f0rkT=ScM_AQA{II
> V>9
> > zsE<cJl8QUANXMMXD!_@-
> n4ylktVn@bolyQxU*nt3*XxtF_6#`i+ZTo{ps1LlPb{Pq
> > z>&eY;uWHw;6myKDiKEEiyjq%~Vn{+c?~+`s|KF5Hc|mq{>{e8K)eIaC-
> =%ubEfAZ@
> >
> zh+c#;kRNF+Fa0u8Q5l#4O?9isoSe=|g5ivci9YB;i<;QP#0GkLdQ($TQMC0j|9T9^
> >
> zDB7WR#4!=+O__~yZQaVa^iTjHex+9l;>Du5N~9J{E|+GBc(Om%6UC6ysFgKfA
> R5My
> >
> zy8eOl3%Xh?QaLW<dGWv8K^O1P+(vxOwr>>7t0Z}^s)JP^ip?hbg(2+{Ozt5@0
> vadA
> >
> z+1cOX*no_Gc~3?K@x?^qLk{H4JL9eaa(9!rE`%xLzCSW{3*KKnNmzud8T2jrF-
> L~M
> > z)EN7@K2Ev1>KenXFHbZNw2AKYr9v4lrj^h9EuE$B+ozp{A|?GNJ-5EaW-
> e{py@Z9m
> > zJyX7QS$n#oROu&LL6|@xskrYY?L8JR^Rvz#2Ciz;flVezJ(s3X%d<yyZ8lJ5o`#}d
> >
> zn=7pj6^nO+{)Lu3zrdg{I2T9y+?=Icow^QXa5eOvfb6hA_SI9)QMd^TIc2lVyY&G%
> >
> zeWw#;F3H{74`sL>k9ew;Wj|NnRsdIfs$AT}ng0Nlh>C~rE+nV=Hx}kl|8bN6D<{
> y1
> > zSJSa?&I$~=oQ5B~-
> fVK!OKkM#J0X(Ym}Ccrs2frUBm78WH@KQLyM;6%0c!ZfI>pGi
> > z+_V-
> c^T`+LZm(m<H{zK0FYFT!j>3HdAxF3RFoty*NC{rCYtKmT^7&0^Ek`#!&s<+X
> >
> zhX_Q8?o!RR2|rhMQ0@^`zaglxQCVj;Ti@l7tP&VVP{DcDv>mwk97K3}n6(DQP
> j!|*
> >
> z359qmtLnSt`^<4`3z^m{+W&Pm_2WtQ7<2kj92!DVx<&I4QpheQd0$*0d5bZU
> M9o^q
> > zVwTcG)SsFb%)GjI5G~#t4Lu4dnqnal;z}E$%lKo#c=t%j7_}ZLWX`?Gtk6Kbdi-
> *k
> > z%a@1`=J0d~y_Ffes)Bih@d6IfV!U_}q?}*Bgc|z>nzjp&`$zX6?e7B#+-
> =z}?&d5y
> >
> zV^&Zq(0gHR7`hLC2fi~Q&|qh{<fjiG(OTxX?=MAix9N*X+ZE_hmA&6Hw&;t{o}
> Gtq
> >
> z;_>a@t{75O4~h^bto0c&j6jo8?2@m%sBT3&H?<?UI+^~gek_o4r<;^)9+p$pp
> %wS#
> >
> zI<>o`eWH(X${{`PA}so8yC~B4gb+8u1Ovm8IXy_^f1b~aE_WM2<X)YX^(pOgW
> 2iu$
> >
> zlhQnZ^^0fynII*~9a>>#vh+qDHzqY0lcz$@>kH?kXd_t;0XVH=KYXDver6s^P1Z
> ^Q
> >
> zOGBoveQ4;cdl1f&#rq+s2^dT}+qR!B`_E|WB)le!h$C&ywX<5}RiB#J4xzX&?{9I{
> > znJ^Mo(3o~Z5zEmIl}K>B98srfMrmcpfRJ}6XOs)f7{2}<?T}$)9B7)pNPzi-Izn-x
> > z-
> axq_f9i{XmjcRX9ipvQcyFocWRdId4dO}eb{6Sar=%MAnnq?6F5ZJ^hjpbGI{K|b
> > zDr&ttz}21$)LCN8yi=!mD-{_)Q1Q-`GyU~nfNXSEF+{P#(-
> L1pr!QHNl#CA?N`J_d
> >
> zY)qAb1s*Bhq(P&Nq1^K+H5ws?psdkkqUCBRv)+>iW0>a)cp1q4C3oT=ji%L@fi
> GxV
> > zW+Xgk^iMPoaLhyqRlH?kt-
> @DrmFNL8T+gy}8|6f!Ln%q%VF*iYx;2jKrj|BSR49~z
> > z?VV;!_jL_mlUw;2nHl-
> WE^=p;e!6_zHcEdnEvPckAR7KOXrRc?A|A@XZbZ15sS4-%
> >
> zY~q<soc#3rbI2*@x0A=m?Agj)Xp@04Xbwlr=)qS}9|F`#cX9VGpD@c?IZqEtrL+
> UJ
> >
> z4($FMjWpgT+ryTUW;DrME<C5|y?}y23s0O6r%VS=o*aw<wi`El+P;0YlTTh=t(2
> >D
> >
> z(#&m&b5s<7O1UZ{Kju&k*uLgLDfhp{cD_*4DS9bdHTTA8o~r|_*WUcnLvJOo
> {(<dC
> > zWamv=)R?K?)tc34BJvgJy~5|keY}2c$-(&i-
> 6uA&cC&)Ab|gZ=*`o$V^OO+nb!h2%
> >
> z)Lvj$c4+Fkp4W;UOAQP%7{HVCG+GLlf=@o$S@21~T2*kM46g5wCfl{uqx7Ih7
> D~m%
> >
> zL&OE62ALl<;8d_^t@9$q@j?VVubxmtC%B^TJ8PlD8yS+jTOkxvHPATup3=TdU
> wS<o
> >
> z*m`QXLHPG%qqM4w)J1s=6%>`)H~)6)VO{1*X;b<g?WT&#B0pJE$Pl$P*`LruJT
> h8Q
> > zoJ6nV;1DH2O4gK#e-
> q!ByfX^wZjx7$SLSKnKit;;VA6P=7J`wF`FJ!A_KpWcFPMZO
> >
> zMwdZwln+VoRSwe{X2dx%M_3@F!u+JWWKvYaOI=5tOu?XIBdg}gfMX;Q9y-
> ?gmho5+
> > zre<Z%`OrNbF*=rBhm`pNJdO9T6}?Tu%zane-
> R8v5Z3OKYwF7I{995>T{A1a4Im!)_
> > zGw1@^*}x#Rpg*IY^^v7TBI)sKVK5EX7L_U5{-
> D4RV>p@CxRzdtr$ww~ijkk?QwBco
> >
> zq9W3DF=&p%`5r2R@SXTY#i1B2dilS&wqo@(aYisnU!#Cd3luMWa<n88pFd8=
> %Fv%A
> >
> zz+26_sGfDcQ**{L#qCkllgA)SDCLW&_qbw?p>h5^CG6xX<LB5gplXVRRg<MKF
> lZU<
> > zAm1Gc*g8zSF*pR(irR<49t;v#Tc;YO<t$!;d==9#x>*8_cnV$a8<0-
> }=OWCI_3x@9
> >
> zfonPcX(^0_1_rr9nOV)30otU8s_V4e0yCVIF8fuMIDNxY=$A?2%T+fBKXEqAGi
> zhw
> >
> z+7HM?CLI>riaMhdPO};$e#jMQjuV5X`3;Xoq|9y9{ixz)_dikAKfeL_Q^~DFvbA*)
> >
> z+7(1!VSY)hgjm6gru4)De^Yw52>I><vHoa5l!KkMA(JdGh743+SG{;Z%vRfcRiQK
> _
> >
> z1`ul0pMqd7ATVeUei>$+CSBU_0vh$UomIg=+S#D<Lakn%jp5oeXC|ZLXSPaV
> CDNWo
> >
> zRyGWbp+(<{%Zlr)4T+5dkuMkRFr1J`0~&4Wq9Sf<1v$hy8feL_GRVHJ*y?IIJ_$
> T!
> > z6l`UuEj^s;Xx(hgIt8C@!b#6srt<xLo#OsJG_;{tQ>gMS3r~es%y$E~8*<9jl{&_T
> >
> z(Uj`exX93Qk(t$1R<^a(62k_yWj>%~+7cnT8=)Ej+r^lhrRcZOLTa^Ml_wbWM>
> >sB
> >
> zjXcV6i@`H?8wf#BLv!4+`eIB|HgD7#DO7;K=v=4(s)1QgRT^B>4!`?f>lG3*fuYp7
> >
> zH&d6@9Eg0ld>@4Wx1$&*BxDi$V$5i^^C<x}i>COVf509yY6r%vnOI`4V9azQ>
> TQCm
> > znzg-
> `v5}vTBK_@1)4w4$;F7>aQ+~CEh5TX=W=E+N=OP){=?1nDJ>_+FvjI<&6!a0J
> > zIkAk(wATQFU}lxojL8BaMgpS*sZF-
> `Rz4I9V?=%SG)n1&)h9lyptPCw#8D5zuUi=y
> > z3UXNWxzRdhORV)uklZDvvu^KHbri})3lbh_-
> b3uV(fj)ahIFAy;rX!LzT{03ImN8e
> >
> zQIlCu3d0nAh+KR@X%Q7WIDP^g2$bdlE6$*uyqO339a#>ECZ9p9piN9K)yC&n
> >SOcM
> >
> zWdeB>nlFGDF^e&|QV_mgqTVffrR_J04CV))hdqYN!E}TXt1T^UX;A75eUWM
> Z%4x)R
> > z7{p^^M=c-_B5U$HL*E$}gq~JRo2*a>-i&F{v?G5}-
> 7DJqPTCn{7Nz>p0rZlI4~7mz
> >
> zAqwD<MRy`)LziIraCz%HW$b)^O#S!^83O|=fK+lqBxJ9QHC{d&qW}iVmC|@|!
> g`?g
> >
> zwf9v4a<f#FO%g^+yo3ZJ9W(mK$nf|%1FQzoP#jziyz^U0lW6Nz66#N|Xzf)k=J
> Ocr
> >
> zz}AFrY5fnPpAb{kr$WScJMPN|bBSgN_d9*RBB>ZZYrAWkUyrjS>XebURx440z
> bZ!t
> >
> zKu`%v#UjGdP5}RUm$R?5wOo^Xo;CW&BxOJvI1}AxWd{+ll3y*Y_Ml!m+Gf2b
> 3l8e%
> >
> z0p&vHo*1eh>KyZ3<_YhIT}<Cniuesu3IS<@H*?|;5?dJe;Q+e&X|t#g8OojWV!
> O(n
> >
> zqdFZ^zA5xu=|Al^X*Gz3&M*4+8MLzj5Otl7rUATnEyNXXg_^g6O&d%zkly4j+
> Opc>
> >
> zZ{GY!A%)4S=@_Q)Ew`hD;p@;gXSAC2$%|Pn#h3jQa3>hd(9kG!^Ac`reOm_;>
> |3uW
> >
> zT6>qUJERP#@~MF>&}=23m0MYk=9oa6*y&?TQ4e9XBF%5{1an6#q5vwo<2{
> UyAaR~g
> > zku^pl=~dP2`Zfc98X!v015wP-
> Kkh2s!r>s&dc~?9Atl$^DgmNi$1HBXmr*f&_FMdr
> >
> zS}FPBI>Qt#v7|I&f|w7+6T|LMhFR(gPZJR6U%Hng14B5Vae)oy)t!GTm!6jma=
> 0j9
> >
> zLeXHIU`%e3GWSNsoSC&uFy4d|7=plTX=LWNUGikEq@3VR(4k}0e&xs5|L%s
> oGf%c@
> >
> zb=!6sQt#eFoN)yQGNjH1hA_gdAsDf6W7r>;4R40p_8gWYZ7w002U=1Ykr6{62
> 5bew
> > z5lpo{(<Lp0ku8-7S;RN}|5C|8rTI;)H&_lv1*g#hVfpB53$D?j{Z7+e6QD43S`1QG
> >
> zeYXe~R`&ujeXK7^H?s~`otdZ1i7H;9uLUuB0ei+4mQjtgVOv5}H64Eu&GvQ(lFp
> N^
> > zV0UwQgPbN;Guf>yI(-UWG*>!>ekQa#y=-
> Y=I$JBF{x__)9E*zZEmcCFhV9%@A|;C;
> > z0dw89i-
> PlNE_2_}Gun<rGLEe~(h>({RXyoK4>xl)*3Y2nrd=WRmFCp4t!*?=_s%-&
> > z>Q=`%q>K==&;cust-
> ujXyto77S~3Y)B?QSztp>&i0t~H3+tROMXrj^}n_te8uFdLV
> > z{!UtA!mJA!M)R(65XcC`dC$-
> SRNn%x#w=n@4gI+)*k4@w<q6rO`C|qx7vgM{9XLis
> >
> zm+YBYS<9AJ5*N4>4Bmrl0j=T6KE~I2<Pf<0lflQYGkfD+p<KmUCHWwcZtH==P
> 1}jc
> > z8wBnya9kTJod#p*fv_!4uw}9^R1yEvv%5%EP?gNL#Dm!fwk1tx0k-
> w~FY#E${v@rK
> >
> zj^w&CU5M$v1dMhoc=Pe@#}uP^W;rv+ME!R1yFh|zwpy5)b>HS1AB4m=1lE
> p-fr0oM
> > zeqF9y$w4I3?w-
> jOS8B0@AS>Mf*jUHq<!BL_*ZMHe3dQo>vLbpG#ViTBxBFrUFr1!2
> > z^$5CU<_RP!OO5Ai#fe1<_NJHFMp1$x9~#~AU?u|>4=A?i-
> Z&+z>GTbGWFZ3~;mLh?
> > z@1%zfH2gC`HNg+t{hF*VsSxyjohp)o8w97Pi0R5-$^L-
> ^_g0=lFv<t4trhJ6oDrwj
> > zNC@J(cP0PDfl;11<<5z|kq0M)$Sne%U#RVxQ}+e!*o1-
> (p9OWCabzpEq45mFFoK|H
> >
> z0cQWO%Ls(mbz&|w`uOKFOf2+_T2A>7hAN=}5IJ;*0;2dGbY82Yq?NuF7fB+-
> OY}tK
> >
> zSmcBu3Iv_G&;rOIjMniNKn~Fe>SFfdCc0TJj3f?nZyHU3Tne0)n!+8l7CJ7b400)a
> >
> zx`9|8?Qw5=2+#AUJ9%j#hYwLKtokB8*v&^uW~QB0rD>7EFGxZ@t`4HrKFKCa
> +|BJf
> > zG5ZvowT*DLLu~hP#6IJu>dzIn2&d7&2*yq-_zo-
> {zTWc%6}gM|{b`5lyb8()nn?Zf
> >
> zRLRdQ{Bm>p)e&}7RDxB?y?Ih_EGk#ZzoCEIrXn{jcXJGxZV2*(R=jQWcl26#+W
> 9+T
> > z)0vi*_}W40^G-
> Cui4C+Nx!*S~=z4~C5G>Ckoe{5e;jLgxEcepN9V=>!_j|EOid<)u
> > z9IU(IrSFY<sCT%G4pk>5BeswivM+5J%-
> (}mcvBi24si~mkArbb_~r3o|KZf^n7UyE
> >
> z(o~T~E3u+4{evDWDXb=icubh#!78GlSim}^?i9EWPuKJqlKEu%;d)omkmzGEh9
> {$e
> > z+uCw=5W$NDrS@s9bdA7QBFSNkHPhQ~kZW2$_9r)H-
> 8)+593lMa!6m;Ey~fbc;@zbu
> > z{ph_yu&l)xHG{pQ8yE@{2Ou8pKuDR(vH<}D$LK2neawv%e`-g-
> `zSeHh*X@cobg_J
> > zM@X~befnF27hEOr0@@Gnt7WDAmCU4?5q+O2r<H-
> $azMlS<h3_eAd0+EVBViPF*q=w
> >
> zx!KXp7x`dPNxf7&$Bm>O1`Nj}JP>jg%^kPu0I*Z+Q^ik@A~V!Zdv|wt>A}7Jgm
> STw
> > zgv&<tQVpOujR^vp%*I#VnO8|(d$If8^Iq-
> 8Vf(X+!lw%jhd(Ixx7ulH0n?x+l#0K`
> > zs-U`Us6cmOONbTRthS}6)7j>k%S+>*WS|_OpLU2hW4;-
> q=U!pbpr~8VdgFOFb5t^9
> > zt5=6||Fn{8Hyb7dkJn2J6qAH(zkl)F0NjRGjVIed`_v0Qhrg3W{3Zd9X9-
> 6O1aqUt
> >
> zUHVpmHvcr0LkkfrAe>sQH)8PUNWH_fmrGmTUL_<DpCgYVR#W<QAprkaA9
> QDz?mSX5
> >
> z@QUR$on*>PnA0jVpQU#FesLd=ZmPqCjyk*mqh;EOZD+r4v*EZ0cP~@_dsu
> s;lQHSl
> > z9~v;YJ<C<e2xQT#JLm}xzR7@fyWM`-w-
> (N|kzu4PE}n|_xPKp!B{Zs(Dvmz__!FC#
> >
> znpzFfZ}Dxx?bU|8%}m48*95*nudP<HX#!1fOIa^NaEwi#^CjPAgnfkkP|K!Sd*
> sI1
> > zW-W-
> #4TJ>Xbzx$;)+`N2{62xp6K4$_2c*Ypc4i$#O5@oP<|iPa_%Kq{5K!<`In1~H
> > zVI4Rv_ca}hYLuBPPy1QH*XI>qa_^mx1u(+)tGc#Pi-q65skv--
> GI~UA3cBywH@_oz
> >
> z8AQgmHzVP125u5IaGVYtGpcqGrLFVnsZ+v~{1&x|N^uzSYRcr7fR;#OIE>U#)K
> DGp
> >
> zZKwE_66VJN`&HpiDEZ?yT!Y((jH(7lf8cxh!!`1xS70X?$9<V9Zl|Uwm^5Iz%b&(o
> >
> zob^;pobL6bPAi+kriMJYG41TpTH$^o1E2x0$T7h7{P9B$ca}U9b2mV18b^PL=C#
> v9
> >
> zrQ4J2CugM6=O#&SeLSRuC^js6e?98lfw>>S_?S9XT190Jt2__4Z3I9=x^9&rk?s`
> S
> > zIN2`sd^+Q&Keh%;uz0of2*1^wv@oG@dPc_53G{8u5HzY<E-
> y8jBnk?{Kg<Q(rP?aP
> >
> zx$KRDt@$ayUORP>+0&|a%sAfZ6`sm1Y*@X=ZMoq3+CZ3)z%8~r`KeOK4f^
> M#<y@7X
> >
> zu`w}KSvu8@8(l1gyE)e~0c~NpP=B*gu7r@}UJw+%&77Ha_cJ;TTrk3fQ)FXIqt(P
> e
> >
> z1KKm)8`qky$Z0nLH=CiHC_p9AM|E4%urhFYAIx4W6o_W*+k33?;<y62J)UQuf
> }Dot
> > zDSsY+i*OE45D$1N_-K^Ehf2{q>#YI#^Jns!>%G8->T_6733r&)-
> tXUE^B;?g$~2}e
> > zevN-|c)$k`b-%BU6mBN^oVoEjt*T*lZzBZ$OJ1D^v>9X0@cr-
> h5P};PfpB7o>k|p#
> >
> zSSG;G`JF>B<F&6__>}3o<~wxr+c<8k?XwA!6|33f)HuVS_Y3SV!u3mG`C8>U9>
> 5tV
> > zan#wcweJW(9B>ig|5-Muqos9^0RI}|p5`rQDUz-
> o1WNRw7&EKpp!}70%&c^b4h<X*
> > z98Um8K+NwdL0!O`JZ8CGOM$339-FvI=PD2uJOk3~2-
> d=LwZv12NG{0Z$pcQ<GAqMM
> > zma`U)Dl~izf~nUW^Z{I;q8CZ~-|s-=>X!Q-
> 5QmskD?C29B1Pr&(c@s&e+uwi>ijiC
> >
> zTHf9`oz%39WmKfj;e3aP(=smrmwIDab;yFRR?h^s#P{1M?5Y5>?SQ7Ysa<si$G
> z6I
> >
> zZ@S{?o2GF!guqJs7M>vd5prqM+a~3b7+t3FXCZbD4hN0W7hfj<Z(}8Cs^6E`C2
> p^z
> >
> z1*3N@^0k`1MM#4<Br$G4!w9A>;WF)(St(8zr$prlXe;lcqfacV$5Lfn1E4Solj?<3
> > z<50dfE9+W7#lo(K-
> r~Aq>Lw>Edt+0C+0E@XAd?}2bp<y{x|iNGh295OGQWfa(+CCm
> >
> zs<!y&gC8eMT`wpZkw~LIa$OJoq_%891iE~e{G3{jN*MX_^A@83o0vN<pGLs7
> 2*<<s
> > zk(8oIlvEzy;GH%-mbOh@et4f)EfaB-3`EBE5Z>u!2F1knq_6z}-
> rVwE?y%~_n0~M}
> >
> zd*+l<A%;p$y@cv)&X%HfOJ4)NZ;*S75HE_BYu5(wNTQl{tvuRQaKwB>a)D`#m
> &MC4
> > zfo<t;UteuPcwfu66=kH?w`D`0w)-oOw-
> XbcO=+Oopy3H^1Xl<g&HCr(KDkWeTL-MC
> >
> zBsV?s;@@8AB=IJ8Dv_X*4%9UNQVCQLz5C9m@9EQ|!ko!;UlDCK!ogMedMY
> h39ZZ}0
> > zLt^3vj&#lIv1g544<Yb6-
> gDxbt{8bT<5(*ZA|xSxi%3z7ra13&Jm18#R%U0m>cb!L
> > zW925f_0wT6u0<VOb)rYkS5BHM{X$B6x-$OwCm=v-
> s0rJQC*k<wIAScDz1q_$t67V9
> > z>GYw>U{=-
> 7!D~ag(UpVGU`CutKj{I#v)AK;DSe3R7A;YmOQAL_XpHs%Fl6_8M@O5t
> >
> zyRK2YegQnEq`<6R*eVe{t>cH$h%F2th}Qx>9Z!zj5aAtt`CRqfw&+Ux#M1ZTH+
> XNW
> > z@-a3Zt+HTYAvRq1OxF00FM+hnW-sM%U!3-
> Je!ymF9!@&)jg5>?2{8NsyKmZu0v4vt
> > z<;E5+O5b-(PEI}@a+;%_ds50((SI|B`sLm@Ld%W(nkXoAHZNiFaP-
> =VGbTMH6m~9%
> >
> zt>)t8tF9CF^q_1no$nh?RT1ixnPeCEkdRPU43Nn5t*2Y>oSMMJ;1Xog1R`iA?nr
> $4
> > zLC9ci;c>6PJWjEa6uV`(Hk_}QrduIdInVw@ls-
> oKS&kVw270i?>6=6@nEFRC5Es`~
> > zQosn`H6|enuQ$-HDxZAPs!|x_C(+soGWj!Odf7uwlDr>pB1mp%>Ggi%uN*-
> LqTF>U
> > z^KiUZAYXWSxqM(C(C=Zy<<Qa-
> QT_A>V($*jj6IDIBY+Iu?qUCCk?vNg^sTCIB{4rG
> > zv4BaAwGLJ+Y&gnc(JZ>Z*+d9y<$FR)yDhw)vn3ChY<rA}u4s=-
> 4|~9MCtID_85vYp
> > zfQ~<^;wF=BO&RVk-
> REi>Z=z>ur4Qig^YHV0f@f1c3bz(5?@cJ}d5XbN1cf2<6W}hq
> > znLua---+Xz3|)MY_1ZLWIt7;*uS#%V`pE~{RtYo_4<^mM(=#qzlNA>i<-
> JnxxY)Hg
> > z?YX0XeW;3-
> 48A+t6~)rtY8+##sGT23$?7f`oT}rDW9Y^*8d_JzfqnD%(7@%{N!n>i
> >
> z0GC^F5jm_l=>=Xm1qhwZ$9ClsR@?No0tp})1qn$5Qowev&_zMlP~kJzX+ILU
> <pvY2
> >
> zLzt73U0>b~PQ@Y2Z0dr$iO$t3XC@=u>tbv6CF!KiW24aplz3i?0Xl4O<W#Yjb%
> W=j
> >
> zD`82xT*wuA7F`oW>wwI?&MqJ2D7SVhm#VjK@!~x6=Bc>D^TMs&1OR`y)_r
> e%CCQ<r
> >
> z7Jz^%0Mi@^(s|XmZza5!7MM%jVqRMl!k)auK2+Iz0l1GFqsC#2a~zW@5tko1
> #&l`5
> >
> z;aJ3LXKcrNv;H(CLmZn;wkW(?$sLBN+eU7{w7A`hY2=NHK9y1xIziQqq@TOd2?
> |b4
> >
> zeAe6xnN~7OaFBE*_M5sSAwG8lBUw|bJDZv0z3Ri&btVt!*vdcb+HK!wuwPSI
> xE)m#
> >
> zoGdd9^a>}B<@c8A_orXNTuP0l%$ykvC2pyEVK`AzEzQqo5r#lsv9UK{w{%)LEV
> >xj
> >
> zkzz!A)bQ=wH(eY^@_E;J)}16g^T~ZRyY3pc$UN79D1hZ>wYd@se$8xmxj$4g$
> ob|>
> >
> zWma}FW#A;Lw=0@$li^vyauUKZd3270iOIsBsyV(sjmhy>XmNMC$RfzECy(WB
> wX}s$
> > z=mOMGb(OU&;Y-
> sUK0FPr3ZcV=$g@~_(0)|#@lQ@ciBifFg=@OF0YSt&9Kiwm=%XJu
> >
> zs01{U|GUUa9j5(FP3e|o;36_rBFKH>4!FOnOmArskGsLM6`IrGn|5SDmobV<B
> fXFK
> >
> z?gHT90>&^rU}E?36u)(KNHK{2)$;cwWyhkd>q6Td58VhGY?SpM5d~Nb!Gmn8
> 7omSx
> >
> z!Ny9rT5()Lz&Pif*jiwE)8Shq1ekIZat{{zim7L2$PEiJQe8|W_QLR&Dzm*+1}B@v
> > zR7D!uzL`O%{_FH*HjSMGwC=(<sasU1YXERnVnWUMH#-
> 8~w<KRe>5t8O19tXVdlKcX
> > zJ?2W|nr;=p%dirfa(FIqBtz`Yh~{D-
> sj%1B+l0IEeW5+>$MN)Se|>K{L(uvAF>^X|
> > zl+GW;(D(DBX+7F|T#|;el$&uR72%)-`&VnjA^S6u7&l4-
> u#2Ll>9)JJeX5yx&Eg+s
> > zh~hpc9`g0kdWZ~;5CLet+f_(!1)xnEj@rhkH2Gh^Iwl*Xu3PhJtCza-
> 27uAu?{)Oh
> >
> zEjfOW*qcoR8W&qED2Gl<rEZZCypIQ}4iJ%$t5Blw7zbrp*{(eh5=O8ck$If9lTU1
> u
> >
> zt6X2*qOuIfe(yA?<TUN7>WpMOHVZW&ZOmrGRQGI$R&@9%`#vcF@ILOpZl
> lTnbb(?(
> >
> z=Q5+#G8=6PBO@anU0#Y$xJmw4saY+vdd@Fu&q2{7I8k_(#w4fj?>Rt#*%98
> LW5JPe
> > zW*L<-?Y~Gki#3;o*wt;l^J$ZQj-!Cq0^+|L;hAOsURw!c7-
> xUpjh6K$0<~(#MOVTG
> >
> zgOoW{y2q#k0z>>#hTEl5jozo`*7dESJFU}1WJCc*0*78dveH7gD|92)i*2W#x||
> &@
> > z?JS1C^G9h_>0n8V(Lj$?4U{E^X2B-
> qIE_*Sz1%jn=QsXUTC6Gy5F>qZp6=4K#%ySa
> >
> zau~8ijC}&we;;)svo~67>|YDimsMAvmE741t$8o~F~<}!0jMh2htB|qRyj>)W3s
> w(
> > zY^$M(f1CD!4Fn3S@`Lx%c?j-
> wKlXIfw#Z(katl}D`~4b77<3iAOUdPASgXEYn)Vac
> > z8sIyi{T#fwiOa~ss&uv8pd!Q7kGpSI7pUBb!XLGeRracvM8CvUm<@HOrc7-
> Yq$gRd
> > z4v+h#XnyzJ?tBJVwvJA#-)035z<my<1gnCg;>-
> ~!IF8K%Oc)c3a6l@P%0*!Tl67fA
> > z8K_Ar&HHJwu<-S7^&Tz-
> z8H8r=LK5Y{?CRW{h&nrt{&1@MNGZuj+q5w15E3DQ{Qdr
> >
> z1dkeke{IiB4$sJG$9{r<jguLz{Txjqx_2qSm>i{V!CsA%7u^hBcisU6AA<B0Gm)zz
> >
> zb6N_RK%k8JD$Gy!N6JOzbFx);O@Bx7KXJOibi`GC*IDG5RNTTxK!1HX8)M8D=l
> h|`
> > zN#4k4j`m)iY!Be9XXffR3T-
> y^!gA2>?M8|=yg?{C8+*WK2(ZTNr|ONH1b!{W(?Hd>
> >
> zeGe|z<97VBQWr!aOa3!P<U0{@x~B<|fVn>JPviYdxQ8wi2GkiqtP#g%M<piqz
> +p8T
> >
> zP_S!2F?(e8Zs8+fmk)$^<%WoS>Qj=YOm*A19ygAwk%b@AF|r4^?oYXZb=?s
> AiZ`#p
> >
> z9k;Z%GT07&lZlh7e6mO5*In~KXtq71C3Y2XqI}gaL1r<`FM7fZ*ef<GcauVkV9LK
> G
> > zO!{{Gr-
> ga0(rA@s7<<;xfebZKwkBdC4>(z*Oe*5_>~j+sASfwe*n0Su`6h**I?A}N
> >
> z|27eRl`8mX>~GG@VDCmI@Brx>;O#Q8Qrn1%(K>wA1@1AqK301ASk&>J_E
> QFcnaYc^
> > zi0%;wJnTgI%FoFy;6!^?-xX0hHv?OuZlJ2UK7Q=bEHMe-
> {}E&CO6a@=<Y;tXT*nV6
> >
> zsgl&ah!CKNnnQDRr?S~?(HEL_1NqHj5<W4$nxR^jlJ9<UMP!h0duDpN^(g>qC
> #52^
> >
> zhJeM)3WtZlsT2tbf?C3BaeR544mF8@7#~#bbN8N1rM|17B{r9UmnOOWAji(j(
> V7D7
> > z1efxF?e(opWk3()!2(IyS?vAr?O)A=JBv1fNE!M7n%=%AA8b#E`9QjTX_n~5u-
> U{b
> >
> z+Dz;427cmGd%8Dq`dEb4bgm_!z<w4zVIxqmEh#BZm&^)RN`4*BX&Q*#q7N
> ?t^wM9?
> > zpX-
> W=J#={e0#W!aTUBa;=js>W)4GWQZmxtpyOL6K7Zo11<3u}Wi2LE+fVLSFsK25^
> > z@V$KLguZolbd2u(@h4w#l{Cqas;dKpff-
> KV?qk;hG*YGj;r=9yH6R@{hY}#|TtTSt
> > zmTO&HOBPdh?0o^J2`_tqXMW~=N=(?Ji1SRGOwG(!d|-
> EFP&Y*s>3Yf2)ZCTs)~gJ+
> > zB~UY;mi|W@ple_)k3w|ebb!R{rl3z`w!c0$h#ifPHYOJVk!GdE`-
> S;?x;Ac{qB5S{
> > z@Qu$^>2$&0-&8%_;;orBLO!(AEIoU=LTAUKh=0|Gcncm>@iN%!3arr?G-
> PPJ0?Kf3
> >
> z$fz}Ni`sfN<O3jL=%^GKG}&kg5mVxV2~H$I7Mdw0M#r&XTCth#n~rx`ac)J%$
> oQo<
> >
> zc<s9kZH9rWXK&_P$@CZQJ(*B>FA@>sYzf$JH9*;Vn8p?^Dd7ytP*+0lJNIab!o
> UA=
> > zrr`t1v6C<u{*8NxvC$$5eEkA?=f#R(&@@UD-
> X_KaBxie|nwb|o$l{eH#^hvv27<Qn
> > zV*^8C4nV-
> )|89|D7;)EG3Ur0I18CTRMu~E>ksSI{5}X10>tF}i(iv=3MDp@TVUnD@
> > zypH+2>Q@S;0CmQ(uY=n-#T|_s{tX{uhb-
> jA0deid6JYg|I2n3)^nJ|=>sVt%SV(U(
> > z?iIt05<yTcG%33<_M{X8+JR3glCGv05)<LSD?x?md;N~WI?#)30Y#0!i)hs-
> ?j0jQ
> >
> zkM%8Ir+NUqBM^|zWA<m5Arta)>qoB{hHKnzBmy4j4)qBGmppNr`SXVFQ5t$
> %Qo3*6
> >
> zyc?FH@#5NSs;v(P!@qBn2)u){rXAq|x<?guGaEpF){0D1HP51x6m$V1tm8CR5
> m9{p
> >
> z3Au^8*|E0kU3TQZffoJ<{1n|I&m*J?ixUslWnAd_<gr62eDXc42CoxHpgKH?Dk
> Z+Y
> > zlAvR!&IVr%pbZppSY>*V0iXwErA*R(HTzz{0+j-!{yS1SZ%lyv2FH?J5*+QJfCosl
> >
> z1J)w^1k}2x%F*{{Kl6azNJfb2&pvyZo0hu8My<L)#<>U9vH*H&^Y_4AkxAiu>H
> E9&
> > z+g&W`PbrkV$@XHQ+}ptlo(~Rc!M6*Xy_fr-
> bY)T4%ZNoPKw)W&U^_JSvDu#$&>8io
> > zO1O+Y(IvXa8X(e};5=?IT|h=GAiptwxA^1sb-
> OZgaoXUvS83(PBK8FLxH<rd+PcVL
> >
> z0QrzdU0POlJSBhr4aRQau%5n?f+K*Nml7mUT$2;LvQG_A+4sMDrOZa$ZGPr
> @>iU79
> > zi3@!1Ky*X|+M@`?YeY*+^t{V9G_!GU-0H0TBi>hBItQt)a$Iu=LJ-
> >$^U|&6iNl<@
> > zPYb;{C?VR&DurQMel+ok>DLH`c!=e_N!1F$mIQa29j<`>__mbx8=#lxE0B-
> nth*NP
> > z@sNR**swh_BLjY8^%fnDw>sQd!t3+H6XcT(U@yOpoPTX<<ZCTrL$E-
> 0o5+h_<h1r2
> >
> z>yn^dW*&YFz+1f!*(;z@OTJvzWoA4=AfS75t{SM!dG>*5Y~#0Jhr4ORXfP$;z;
> UU^
> >
> zWA77JoG$v0)YnDSbxzRhX!i@7KCWG_1N@VcB9}SkLF8TZ;LQGL1IPQSwo@S
> a#=2pN
> >
> z3JgKVVE^7%$NWi(uI;fK;cI$#HwC9B>RfnjCzr9d_EXLiHj@GbW$B#e#HyiX@}T
> KI
> >
> za@vnd?kxM{;9=JSjwjC>6lcSr={}5&xdD|0Y+vRDP($t)Qo1dKZ{*|_Y}*Eo);0pp
> > z@!8BlB^AGO6$qR)3<`0s*lq==qADl=mbrh-
> `^5g98TqP_j#KdfRYD|0YNGFhOt4#(
> >
> z?NrTi!rP!bJ%ZB@>E%$9^B%u|f&W51iGphn*QSh<G#seqKL3hCmuH(NilEy%
> MXI4g
> >
> zw7gG)yQCNx9JHWyl{N36dq=1J4mj8}%};|vkaFsE?Ol&z4^P`Y3UC+)Xxs|K{BLc
> v
> >
> zkSM;AL&3JN!;M?h05(+d_Fo(>)hN_EO`>#}bSTho^qy{n<bZPhjn#KMl)%lnmX
> A63
> > z`1laM5&D>z1%L`3Y&I>40p%qzLLul5Q^}{yERk2Z8w?!RSuu>$pHb!G<c`S-
> &=LP`
> > zcx^LXH-^>5KDHW$Z3bz(26Vr^cv&-
> acG`8GfY;~Db0kxdMk7y?V;^X`+_6IMtL*zG
> >
> zyV_O*{_M;O@KCG<Qc1~PtmSxd+GF##?MG)HLKSXw3&f+P(q>{9jJyYa?nZJ
> yFXihx
> >
> zP?4nOG~s%QzDZwVK$^rvGWJ3#a!bK%Io|5NZW9Km_00Sl23N4EsH#o@9qg
> ~d{ri!Y
> >
> zC+;9pOnda(UYO#Y@tns3eI!7|l#%Iby7sJtoAY3HduOpXviLWunn_`reL(EigQaL
> {
> >
> z=ALM?KxJI;W8he%tA*wPkT!DyY$ruF;#wfj^Gzg>dD4|=+50s*F3Mt!nKfg+Q
> ~_z)
> >
> ziT=;AFTR&olp5L@zu;OXE<1NvKP@)4M^|@`HblrofO_blkp%W}YUkyI=5L^gZi
> x|!
> >
> z)^Q9F9&bY9T~+h};#wQ5%U<yQ?I<NRZ4*gFUpcn=Z}I8Z*=P_&2EH0j$|<5(G
> ;*KA
> > z?QA^y7}=q$I?D<Rqnh0KV5AQ>F$u|gzDGc686)u0=k#|p(0;a-
> 2i*w9Y1kWggcEAz
> > z*_}71r;fRY0@Z9y8m2k$Wum@43=^2cKKrHgz-
> Yc~Qsu2kWQ?O0sIz*2Ug$6lF7j$V
> >
> zgm;^o^3FX@qVSHI#7qv6shU8Feb7fbZXAEid}sMVkq16IuRQ1;ysKUL9AD?7S
> NbAk
> >
> ze_<uRa(Wvpetog*;{qsZlFl~q!e+j#|HPgDAy?MgW;4lMoRl5Q@6kqFR#wJ^`;
> Hc@
> > zi|8mSqO-MoaYaqA_#}w?c-
> >nZVF_01+Vz#hk|Gxaw5A+%m8RsRw?ytFei_w|G65>`
> > zdQ*no?vCJ2DOCJhtdJLw&dfnJlbW9w>ivXgdw%!5b~1xcog-
> (Rz@ruT7zBf!)UIW~
> >
> z+}{InZ@Gtmb3yRH7$>BqUHbvP0^(Xl0CmQ1(9GIzcx8Ia%I$IVqzg{eoUO8`A4
> T`E
> > zd3zjfS`K5JePOxJW(T^dd)`SAlgTxp3aqyGynT-|fWvQjkXT&apwI6eMf}u^-
> ^WD%
> > zT;@j#c74fBK8Y9hm;0O7Qo^e_{qUuZ`d?=-
> ^|Sjnt<66f)zl>i|M`KuK_0#(;dKUf
> > zTyu*%V(L_|%5}>KD68-
> 34MzXKecOQ#quRyRa$}zf)sk)&P_s|_JkH80Dsvcr!PJy2
> >
> zBhMF&Z+~w<)_&?`uVCFZDV!jguEcgWTS1B2X8a>zH#Qw0Pd&mQ_TiBwOm
> r^+)zfc4
> > z^GpqT0=SDUtSU2xOaO&hZ+I5d`GHm<&~@#-
> Uk>=DjJl057_mpgxax|_Z7^eE*fBXa
> > z5_DRyRueL^-
> #{qF_C_l)FloB<Zb#Gypzv=pf5WNAp#gBPqO=k5+sY55eIVdJk;E;(
> >
> z<B080fuqcjjMvAS0<9)+*RrSXip!bG;MUItWEt$v{+sty|Bt4#j%(_D|NqAVVFC
> g&
> >
> zq?H(mn;?yp(lC$^WrTEhC=wzP6G<f;9U~+J90LgnrG?Ro3<*g|r9<*}AK%{}f9iu
> B
> > z&d#~-`-<1=c^R&VuM&WIbtk>!Z2O-
> fB?hE{^eE<t_1~*V{pegfKncx{Pj+X>?3&}h
> > z32!E$+=MZ91HfdyI-J-
> l;<x_oo{rxq3iDqM<k|yVxpjLq)#2F}=E3XFz@FNE_T%Z$
> > zd`8fM-3port=p~3R?cXIgSVn_*SYG3-
> ETQb^?+RJ3slcP8(QdcG(Bjq`$P#4Lh~m@
> > z7tPMl@iqfxzh@Lj$xc-Z{m@G-
> GeWnQjy54wnd$P)o_C+gN2%ORIn)>Esp6M`Pnn4<
> > zB((K8n`$!Hg3i<5vVS>b?uym}0);{}e~Ya4L}2MA@OU-
> |1x}%Ug?w2J9*_~UVX)q(
> > zY@k$KooG1vIZ{m$`ZTs~?8|yM8A|70H^1WS#chlb-
> qV@_uT2r9>Pn}r5o@L|EY*YV
> > z0`B%7x?w2<&7x>az-
> wv&LHgaWhjI>DXsm&5fQ9YO_OSWp@u<bMcIZvH&d1m0yoPLQ
> > zb5oIcpb+-&O)0Z7Qqdje6bbgsmJ#!)P~nO`J~{|6?{YX!snrY(k_RFC$-
> Th|V9j=y
> >
> z49ou0s`$7YG%{PTxoXgtTHnHeze25J;ZfmzrKU6cD%1;X*foA{)^He9VLu=ee5
> WmG
> >
> zeC0Q>{G%|qM<p`WMndMnIX&OgGq;~OOzwXN^{icRvo+upKCwTrst2oT;^0
> =jsD@ZJ
> > z<;$3_`cXbtBjmRA_4R$A1eD8_Du>OjCU|#}8KM+KltfW8-
> >7#rH>p$^Y|^sG289!|
> > zHdRms8wY{w?8%>#euLL@+*5Y8jQn>WLEWw0N~ywysV0f{5)U3iJIh-
> cbbiR*r7a77
> >
> zVS)P!i+KrSpl1)>!o2Q4^BmjLp~uobjI|@}OC?|zyP)wQ+B(JHBFD;E3iMTocXVG
> -
> > z-
> 09mwmTH~lR)m%GB@+7cC;RyHm1FzRFjqI%bUO^SFxY(VYH4a3v&|xirlZN(e
> WrXO
> >
> zkOskP_Dj%&r0MEHxoR6{P1*XhnSFXFXI||KOY7g9j5eoi*bk$8zBOE4zQp+N{l
> CTI
> > zK2h)d?BKT~bo>b1DKMH0o+hO=yggY_XQ%=M7x(zk-
> v)o<J5KbA=o=@`(r5hoYxMi^
> > z_+m_QYicYYDAC%SyExC8-vE_jPh<`{VsG!H*2~T8K2d6|asi2}-
> 6X%T!<A&<1R66N
> >
> z)|hyyfz+tFFkx6RqP_&YSG&(rp=?#=pgkbscgtTHuAsy6le(*8Vgm~aL2BkS2vrg
> O
> > zFQbL>J7nv_F|mtz_7SZ(YX$}e_)4Ra>1*8qo8kYtn@kh#-
> IZ<w4%qoDyYF%VJC8ue
> > z<zImLO#7Zb4&|KzgRo({X0Y9Z%MvchyURze_c<M9)n|fpVumXId*n-
> wj*c)&TK0t?
> > zt#dHZub|<Yaq{lSI!aYgXlMIL4fz5vkm-
> qZN8h5^4~gb?2RM&WN9!S3XoVSzPE~z!
> > z!m3X;G*v}Y?r$-#&~5>rG)MnW%jrZ8hL9i1Qqg^hz!^Ov@!-
> wBgQsaQyi_$56MWm-
> > z)Xk07E<R(IDbU&HL`KWPqqHC=GLoV!IHg6~SXXbzc1G-
> Td^1>N*IfU42cc<s92W=k
> > zCuYy}Ot$z6fplOYYneGAy56v*u1NR(Ur?<-b`G#QPT>@vYV?-
> nog7X%sk_s<Y+v*t
> > z=AO)dv1*O&5?C24L0TI9YxyGJ;hVUo-
> `!T#veFI(LY3b+09J4hoP~d<ck1$AOIk5F
> > zbCM2u?}yBTP-|YUP+qtE+N-
> $^DD4ERh834`U{Wl(32+F!&GG*w*(b^I+4z#dc83OR
> >
> zCn7>l4fL_x?9*;jy)|*G#qLh(qH~}RH7?H(upMNOHE1^|Hi+1@IDqm9JoS<_Zc
> |ej
> > z3Z8&CV3V_CDkk}*`v0DKjMyd}Id{-
> f#RBwOY*f1eI#tq`!Fj{@m;NBCNlE8a>eU~Y
> >
> z8<t{ltvMAUA|h2B4p~&4Mo9E^)0#C}wgR+L3*XHJjpFQ(#ym;0zYV@PBTc_tK
> 5mBp
> > z(Gk3F*A%@zOR1A-
> {J{xiomtp|OAG<zb5m?Pn50Qd*bsob#O_XVOgLyDi&K-6r9Of1
> >
> z_qY)Ky1znDPA(&@AmQI<rvg2LzkPqeoz{1t;Fjz>c^*awC{m}V*sC;c0{E%mna
> BH*
> > zI-v5#cXLVORw{Zeno}<I#(JGg^itRhO{<H}Yidq3&xE0(sp*-M%1br`Uc`NX-
> uT&S
> >
> z^X4p_NyF%6J#3+EA~(b3N6*b<EI$A5Bv&&egmw#*zovgJD!S+KK6nWF{g&0
> BZ5=er
> > zCqTxwwTBmc!ZyUkW438cqKo6~3A$L{9`WHdPWH>JhzPw!ob-
> 6zlU+5lkdX0csNof`
> > z=Hs3R{$%c!jWY-
> L(1iNki2w*wl^LVM1bse77APm~fd=d*_?_t&Y;KcLqe(a$=)XP`
> > z>Ec6%UCl#6T@hddYYHGJIVAJG2=rLYPoj8c^4nJ_bRG2N-dC*`F|#5-
> S;UtJ>e0bt
> > zlnR+ZB=thb?WfT~!j<x<0-
> aA2Alf+o0*tL;??B*EPsz2Ws$pdWHO@;xOk1k3&u|vh
> >
> zp}c_Cu%2@0gnQ@1wfn`1yRGISGZFlmlSh(mImgW03{uR$NJ;J_u$fE+*=Xbq7
> ;J|z
> > z-koe7xF)8|F!M13<k<Tg@GCrOv3Y)z6l`e}_^a`k+j-
> Y7Z#SLCl|8KUqDi;w?7O0&
> > z_3jO5;_U<B)w-
> HFcg#aeR!O(+fVJQK7b9MtMMs2%g|PtM%BDgU?;zlGwD&NYbY!ry
> > zaz}XD&-G@E#(;cK;SBE}XW*7zV@*tT;fcyq-+GV(Errrw(OUXZQ}3d;`I)RHI-
> UiX
> > zDR+am_y);LZvn!no>FLCRUN2vCZs_|Hx7cMBdEv*^2-
> <QnUzm@<!39peL;+MBzl|M
> >
> z5u_zkX$71U3+l3kS*fWX9U)W+DCPZ2^c8}ROC@eFhrdvpzC91gvmmIL0*p7_
> EO7gN
> >
> zS#Xevrax3@yB*_qS{5YGC%I^DEU^JJFg&LEH{$l<EEd~|SLIH{$_D*CFY~{Q#h6
> $i
> >
> zL%tUMKq%G1_i(+#(MoQpJuew5@ZD9{)*j!05CNdTrw?Q#dz?Q;<7Z=H!SZDy
> Xn{Of
> > z4XP9-
> f|$A))K*H%*QMInSR$Bd1_uWvpn?EY{~RoPDAQPT<Yt+Kh~UZq4f9_R@dv8E
> >
> zzB7F91J&kMo0yfLB51y13s|pEY4#cfrvYJOmSDCr@0#!FF>KiZD4A|5H1igeGj@
> YK
> > zxQV&i9p!i-x|PO<=kH%2E%_FEo4(SjjoR?77RyBFkB>Kx4KzR{We-
> #w4(vmfn?Vru
> > z5M(YsY;?cn8G_u928FNF6oMLqB-D8yE%XOFPb$M2G{8zJRR#6-
> 4f(+RJub`mui!Dw
> > zM_#(tjGZa&f32SGcn`#&lCD3*PNH9@f3L9D(Hu6~HIWwMWl-
> }yeK=rbpE2k2XKXQx
> > zKK|>C+F6FO;GY<=2(F+mj2$6NoqGlZkUpT<KPTs#B?*Kar_`9*)qp;s%H-
> 3th7&!6
> > zbP-
> Tin2M3T)85811YuU?3ILJenB}UpBd8^o0aQvo<<B)$rD?rfAS3JnKJeV22kLjN
> > z_}`vBN39#^Y3m@xOZ(VX?FwoxGCIl3Kf-
> y^iZn3c@baZ{@GX$an^4lQ&IToF+yzyt
> >
> z*z3lX0?e^8|GEZuaKZ~DlimYRfAc+YC9<!^gthYQXI^LkN$VI?4Hi}MY6dSVJ9=S
> d
> >
> z?^V^TtuXHm&zbrSsPxx&q4S#7G?#bx&3ekLO;tr@Ud=qrJ`h`(*Ik{x;?HSQ+$a
> ?S
> > zH9-u3TX+SuMGox4XV1DlfVepmp{tle)r7qvF;Iz1Di-
> #FqXjnSNMO_Y*e|TkzT6wL
> >
> z1$AvJl)O$4F#}*A`u83e8!H8U+=8b+0KrgXs%rKoOL^u1y`Yr&m_gvx1<c1sj*{N
> L
> > zw4lb#4#?g=g7f*l&x+0kn&8%(h>dUww=qnEuvh<m!-
> s9+9*KOCp;tUhBW(x32DqHX
> >
> z5kFqIUxF#;UcGbQ{H3~qRp0!Rk@o1=!}ue&nkkAKtc*w(`|JA6A`PGf4>gV=gx
> o+(
> > zHz~JAR2gCp*}SK(FF^}5jS6U9nZT2y-
> Tw$NHRhbR4jJb6*q`NqddweCz1`?z=)7wX
> >
> z_~T}l`?bFRfv1yejU;70+jl(4)h3eq@k$TD&B0|RdK!3y7zS^FByLnSmVGhnTKq%
> K
> >
> zr)zf_Yf!|*&DeVN1&XC{#=BBYP_Y(t+GPH9Zl3Kg)>Bd%$3tDXLfc;;&t8Il5uuel
> >
> z35CC;*e9R~9Q9K9T4TK&=$L3oLOTR#`uzYcVhC#rB7`CplXeZeMV$KxlLOd@j#
> +q&
> >
> zT)!3SmFeOYpL*7jpzdPJgO6w~zghYdm$;R+W|$D+@j9!_cjHFBI_DHXPT_z8t)
> MFP
> > z2e~I-K~cSXx8EG)lzE+7@73IePhx-
> ;@UJ{nm{8KnY%SAHLOCV#1~fD8iyKp>%aL#F
> >
> zmsIpl%SnBU4?lB*m{#?7V{UXC)CTwMV{Gy@5)ifj3jHgWZjEuDG%Ft$h+)3R|
> 5~|o
> >
> z!Y|X#hP3zmtfFkylmZ|bY#*Pj{t5b~@c`e_5O{OKu>+&?%+{O}sh{`KEt_~J>Bd
> 9f
> >
> zjk+JP>l%0^)CQN!yZvp)f{eFpg~;}^RzSL0>&I%@+1CUgIfD}u`UoPFLs2y%HO(x
> f
> >
> zx|#^>GiHz`b90wZ<AKIVX8g8o2IT7pZ>!h9g8LMV_+>(uWlbA=dmrEmumLe)
> AfA<3
> >
> zAy53~u#IcTRdgEwsrv6Mxp*edfR&qN!Pk)m{~Fx;pwv<7RGjvBK@Mt<g35~H
> wFM4a
> >
> zV98RX`YFku@hJWumT!PR+zIT4kb>D%%+BQ7ZzEb|anesQ(b2}hx*$X+K2<KD
> >YZ7`
> >
> zt<|Py@a@dFGoH{JRRzlE{ZN1Y0;o67^`sdxy#!K;AA3CjRO?HMon3>FYmZmRd
> W<i*
> > z88&09x<3LiRKp7euZ2wirE51>mytBm1a8WOcu0C9)UXu~U5Q-
> dnOip*0`sN2Ta~yG
> > zTk<8?uMuE?%w`OwAB{cVw_R>P37RCGQF-%Oz^B9r;`B&#;(g~co|yXk-
> (q@MTF-Nx
> >
> zo1vvwLtP!yTk;!1(!RPQeHk3_H<@F8`yl<6TJH*RQ+AEA2msuY3>3)&;e>FZnd4
> {`
> >
> zO7boYRp6<sLVG%pwXp<1j{Z@F9&|QAoj`E5aIQ9Sq1vPixhbd4l1f0^V%hS?R
> aOZX
> > zj4#Px-;5Xhrn1%eHrN<P>ww@n=u%fOtBB3{QSpto(r}doW-
> kGO+`xCf>(h{Mcc%|2
> >
> zt$Un$fWncalexpQqitoi<!V`y&UD=K{^SVI1m|eqez_|3lh_C(x{#E_X{^Sx3`ouE
> >
> zDUIY)(n7BRmq^X}pJYIh%m+o+W3`+WI+@r+!TXV34U&h}0$zn1Mvar`mzpD
> V-5^$B
> > zPbdR=b%2-
> pupOK81urupl9sj(A%g8wR$wx*gtJ4jquf!&S+gD=?y9Sk$BORpzt0L?
> > z;X+pf{84kj8YP;3RRBmmQW`-l>E+(AjXN0-2-
> pNELfG(uNbq{doFM5MP7xlb)Rgq<
> >
> zDqwePWfp#E+y>RB{I_p`gy6G`KX>@6_9vS_Em}Mtyc60P1vI*;yFW!pM(nb2
> NDpUF
> >
> zefOzq!39EXNeJ@@L=F%TN{&8GO22y}5i7(U^sDQQGn@7~zvgQvZNxZGJo6q
> %wi~ga
> > z(y=M|fUJtH+A6QC?*Fza1!GP!g~tV6bNagj)DB)P;dHxwQk~KK-r%dW-
> 3aN5iiL|`
> >
> zNGvfJ7Wo9&gKi*IIyT}@DR*goUypIZZ<+I6ACF5+to#c#D|~ztPNuJ_f%DRjE|x
> $z
> > zdsmsa%oI?gEjOlp(5KMzv$Hn4pha-N^@c$;w+-
> lbp!I4w9ZnT_6aMT~=LLkg!$Rl#
> > zmJz2Er@uc2NnY>si{>y<RRM|Po@Rl8t@LWX3AP&wVyw?V=wqs=c-
> lmKVwD3GSE9z(
> > z?&71G3=Y<y9V)nx8T%i<CL;ZPGj*TZ5#n}P-
> Je0;b~k7jhtN|Kp)IJ?`ipTj&G2HE
> >
> zC#plA`Eijr;Y^1rsMi++s>yZ#WU^`NQ5m!XMnI$|DS7w3iHM}8po?F(;&vMsjtw
> bk
> >
> z>`>U+dX9!dRL4QMsVU)lYGzM`aOiO{7PiBJvqnDhGUQ*}YwJC~IuGz~%;=Am
> oa9>Y
> >
> zplhI#NN1F|kBi%SY`pqTkt2&*gan$Rtrp_SfNVS5`SP&%cKz!WpBUS};GCR;%E(
> #R
> >
> z^_YjN5Z^6e4F;o=QC6NloxnI|>OCXd;)S(!rx8dqfrHKp8PeaM>_sbRO|D(Ka`R
> @K
> >
> zW@I?Bh&^2{duvaIqzODnLrh~Y^{voFGEA4>A=yyxP!*`|?A;F+s=CW{;eE61zN
> 9N?
> >
> z9e_LVMk1B;D*E^0Ed96vYh)hut5+pl$dg%d>){_7?K2+3&42tdxiLHWa`rh9Cxi
> wK
> > zdildOB}k13;#BI@N5b9u5s-
> {=$;2+xtLvKQIGYm??8G)+0c8Xr*{JN_Gg0Qfv8KGp
> > z29qSa9Qa*1_;62C=7pCyPN$VEQ!2ynSBj}H+_-
> G^`3j|E#&2Ze@Uf$#4HX(7!w64j
> >
> znP3ef7_a7y40F^gld>w|rbk(G4`D%ez@J<&cYGp3uh_?c$Z}veo@gHAijdR7d>
> |sB
> > zPEJGY%z79f4~X+<cGE41ulj`J(pzH`tAXsT6p}L<QeDzX{u~5!)wP~E`>!?c{C;#r
> > zI;QxWdy(wIcwMz2J)4g2b6?=g@SvGJb(yZxAmci>XYd@Y0c{E4&`x^POE{KL-
> $Tm>
> >
> zVH#O|+itm~LrFoE#$3*NE*7;zOL2sf|3EOE)h1<rzoy^mNt{EFM&Ss438QD#_1
> 3i$
> >
> z`a{h>ZF8m>(7smICD=?hF}k@Tv4@34v%WvPGO#B%hPW8mE}xi_|Na7k;`P2
> kG5`&V
> > zbTCwbgX`hWk6KUt+7e|3#)u$*z3Gd&e6v{rZ9NK<3FEc%nI!Soo!)Ng--
> HdhvEgEU
> >
> z{Cs?_fbjgm1avNfaP3u~kSODWs2J|uuqg&!kLlCeRlbpZ#Iv}Yv*qm6c267f`Jn?4
> > zVwPI@B*m}KbjVZ<Y!3gp$K+Yac&Za#EP)YJRH0ym8Cb4R>HL5hC;R$-
> Q%t!bC$cv!
> >
> z)wvOkEziqKiJ&`{RWPK1Eh}eL5H8q;U_W)7aFGlg`uBse5wBoKeoXSkk<q@ZO)
> Br-
> > z%&)-4_CY5jfFx)|e<Uw|up$aMCK@Z(C-
> 8zA=mOsJWWA+#z!u@xV`Kd|iJ|JXZ9x`@
> >
> z2EzH*bf(*)&fXR!eFG_Y9i9B%XIB7yRdBW@nFk%sfz99+Xx0)(%!GP=7ELhGN
> BHp}
> > zg^U)eKgXYOGp#tybn58q*RK!LBwYW~{EselBvk=uUU&J#h#3zP%~r-
> 2YOPxyr*b}>
> >
> z3q<WPJiX#j>0gd5rbgfktM*1WO0f}dL{W9CR?V{%%L#u+iY6DF@FQQfU^+y{
> ADU;X
> >
> zR#66CvJO+QQ$cDnIm(oXoc6?P_uA_^|KUL?)II@?Tpft{H}Ye=w*#ZT|3LTa4v
> @bS
> > zXQ2k-8Hx)pi#iY88~?Tg=2DXLmANI^t^N&Vs#GuBFpzaroBNE|-
> W+1H2CZtdmOT(s
> >
> zZgSeNY}nRALcorDLGo)3=Q{^a`?RW;+wdJLIIKxGg7X#P&P}*@R$6Iq0@^M8#
> Jzwr
> >
> ztn1xPW8#lmI4)e5<&H{glYvjaNobUWZTAXm3pVDVPGSFL3rkAIV#%E?+l2M$
> ?Zisq
> > z#XHy5OmJDK!zaEyTPjnZRI-ATP)KJ-iy}L{#b;~6y>upU0{S#bGsn-
> 7nGsJXyLNjo
> >
> zLMY+!R>Z(9b1I@BP9A8$*lyIXDei)#T6Np)4zK~eo3RrHLZF8gm{?x|38CV}aNlp
> <
> >
> z=*2zyA;4%aEYmavnOk+s`5w*R;;8ce`I15vW!_)qOoHaJzJoe+*lv?tJId7OK7{V~
> > zpqOIVa8Y}i0qPTM*RBa&UPi9$H6;zM7<?J*R6L<BmQB``x-
> |BgIJfi=ju7@WZg-yi
> >
> z^{U*ymKv?HW9YA=B*DsKW>foBG5?DW93fh`XK}4diew0|H4|=@R!XDw6lW
> N<+%Xc6
> >
> z*uX5b0+ieK?S0pJGUZ0)_9jDtBFPKHA~%{7Tyb45m0><9tlfY9r}e+5AW_k~A9
> vGh
> > zR{hELkfDs*>EDkDkK&3Iwm-ghxRdaZvqnp9`X$ep-
> 0s*6L=4RuZ>k3UeD`pkpd=K6
> >
> zt|+>vIMR_m?sjh8n}VgWM|Z2%&hhe>OT22N`C9bFVYn<~H~%HwuPavk;h_
> 8a1HxFs
> >
> zC?pr&o7B*EYiO|&qC?+ij3dJ<8sj3)B2*XRnu4Mt=mkB#n<V!ySmF0)1W3UaEY
> yJ6
> >
> z_T2M^oYkT|i>>8fDjDM1&tE6j*>hB|2KgnUJ((X9*XKRu8xjC6zY<gs%77?5IFR
> *&
> > z-
> =>}9(>;$TKuZm5if=KT1okgw>fCo)?GagTlnO1R=F`3F3yNUOH@5orE$~k$(dLkf
> >
> z(TCYGCp9AK9dap#cOY{0_7f8Xu(f?2_h_M+u(8su<|<fvozKmm?hyh!Bsr&dtk
> JGf
> > z2s#zs8w8oACvZErtPjc?i05oJf~VW(I}_{;K{C-
> m=TI!deWV<@u@B+g9zOd!H<h76
> > zUZ2rG^O9_g;LQnV5ScX*xy&jLvX?@rQb;I+H-
> !7w?@Nm!4fF|H&)>RG9@xH#VA%Kj
> >
> zR!#_exji6up2L0WFt>PC2xii(&!l(~<BS4m7=0xswvkn3Sk{@KuRNjr@3KHv*?M
> 3@
> > zc-IFib>qNlwOUiVS#85^UE4-1;P8ixKP)l8w=H4t-fTR8ySt1J61D!MiEH|v0C_=x
> > zFz6F-
> O~8k5r=B6+gEI=%B7x=U*u4~`0Q7Pzh320ccRxp#s@Kx0Fp!iR4>!=m#rLm2
> > z`KG6~&Y4#$-
> >{TibCEs*RuYpN$0HfTgB&xUILCA~201p?3&^n9&SN#@fN24eOKIXO
> >
> z`HDY`2rUn&$u@lHwMG<BRDWlB<~TJC&l7o^`goA=`o%l;iW0N^7G<i@k3{9L
> NUGvT
> >
> z3oUo}&W%<Rqo{P&SgJ$YY^WHou4L<z6ko;8gP|kjr8gXUz8`P5QH(xsu*Y|(Gr
> |%C
> >
> z#_9)im5A^xI<45i1Q0l;cSeKsaw2eRK<y83C2g@{ZL7gBhk!R2EvrmmEQ&3#+S$
> ~q
> > zCbUK%D$<j<%U>20BGqhaC*47FA#LP-xV#Y5n2+6#wi@&R8o-
> IzYg)#61qGsUJ@X>V
> > z%Z`Xr4cmzOVtfkYirC*aIQ5$;O}zWyIx9G&(KO^@lgaB(PA%01QThY-
> L2ha3l(|OP
> > zN3)h$K0wx7GuYqklQI@IVNK=L`Rp8Q^vX^-vNGz+4g_?6=-
> neefemATL|%SeTj7KM
> >
> zi(z?;D<*`VPv8M{hL3f?hBMA$pWfugEju@N`KF`iJFMpOY`2ateJY#xi}@UiJNwc
> e
> >
> zN`jJ8ZE*e1jZka^BWnn8D@>l*Af%sd#^cl2pj4vJy1mIl=N%Oa>!#&VHzPYs5$u
> L7
> > z!mV(@!YY)C1EI1tx4-
> 6jp{UDZBXZpNJIH99hEwb_7a=nWr0)3mf5T1uR&$m76x$AP
> > zwpSBL-
> W6Lwhwu?1YL_c10oCGV`&6p0Vms8N;2YKq5lqOAT=$FUzlFDc=mVduyMC6_
> > zOF$m<BQ-
> 2MRC?2nH@L3<uqlt%cG2a|VZRbxEu^_2@iKz*=f?^EeXkX}HhsnI<T&4!
> > z(0IW3+)M3IHUkF8hDg(5QL>*skU~v7UeRp~-
> ^iTXueIx8byvHT>hu$|i_OeooSftn
> > z{-aKe$k>EeF;)|Zy=(6Lm8Urn7(VItisl2Fj=M9R`?y|s)lT|raELd%d6_~m?1IV?
> > zle{9X1hz5Lfw7lDzTFlTZ})&K#0N^0t2e1ce>~O5)k-R;1MiINT!C7PF0A2-K#Z-1
> > zwwT<M{q%Ec3WOPj2{GU#FqTGVxwht$)88IN^NX>3%%-
> W88*^zKTEx>j2)~V9UTQ`*
> > zG1u8&xQI)LIXEU+7qGK_E?eT`pS#V--
> kjb0g10PTQA2cnH1VYt8=sJ5D~h+0OaL57
> > ze?~SykK7UD-
> {WpSh~4E{RhoEJFSJ<RbWjP<#(&1V`?jl|&IG!w+T)b;99tN;{R`6V
> >
> z^mH!8UCg8wEgEfC<Qsems%d{g_&f@PM2k+tWxva6rm5e*0*!RJIZy$Iq&jlL)
> $Zo2
> > za$ipL@2iXRNSZ-
> $C;|qoT=NbVUj|EnU%Bdsok*%vHNYbA8@R*bE^?L#N8J9Ie~kMH
> >
> zFw9B6K#Bd`Ym31tFdAsHI3MEdyN7=SA=G5nDjuow=WD^M<&la4Xt=;IsR$?!
> %!FY6
> > zxAF@Lz79vbF8@7lW-!|iy%`)oRCg-!<ylV2K-
> s2WN^ui3C{($wPhZa^$pzWR^Hl3F
> >
> zc&ZBV%{(tm$ITGq8=@?JF8>KKAp1gwkb_o;?#<7*ys^Xq<@i!nYdjT0T|z%Pg
> w4<G
> > ztoIV)^@o0gVvol4b7`H?AK+CcM`O)WH$B^#*Gt-
> M7|}+UXRU7h?~TB=)5(t0^!(%P
> > z-
> F=oR0cB96%iSgM{^=dV&3B<K_UD=CwM6=butJYy@vJs@%j>J66Ylk^Qk3Uc)
> h3ea
> > z6-
> G*5paN4otm|)75~9_6q*Q3NIMMfE3AM;i0o~2>Hxh<jYPEH)e(&65`Eu~;WNv
> tc
> > z%y^8n89vQ=&D<T|96|-tW{qUO%sIK15k4XQv>-eDn;KkDiQjl{qN(-
> i9_yFw*OB-A
> >
> zBiBEN7whASWF7GIH|kpS{7R@`fG;kNl<k?Nh^6Z+@n_&PFmPIH>Z1|SS*pe
> VvU`(H
> >
> zaVYw!qen0Z@!cKcSGpB73A=8RvN0!Cur4ax*~&|ezF6b%^)M#?hFI3eZ_Uh
> WE37a#
> > zBFk<U{P+`~5|)OfkSFcW>v-I(?KlV%`3;97o-
> gou2?WYbb69sCMC}^w$$jzUo!Y&!
> >
> zs?&}rL=%;BSkRvYMCav_{~j?vquV$*Jiz$AzRDnGI_&Fid(8Q<VE4+f2I?^reP<Z
> m
> >
> z7azEtztN{Iv(5ELHe12}O*6^l>mGf+rJ4EqtF4Uwg3cW}IO`W;W}25q)jeCqV18z#
> > zq-
> Bw=kIs$twh$*a%{xZNiYFJUuI7q7&x(kkL5P!8aqanHrPfxtAF%}qBYJm0$sYVL
> > zJP}y5v#0lQ&o)1+{dt-t@Zz-
> J=`&jA2_>QNR)`A@(X5LpLB}VHq~<;q7SZwF!x$;|
> >
> z#R0Eytal1kOnUP@MjvHMs~HLyDPCaRhCB2Zerq`U6XmD325HpHsW>9XI{iO(
> 9zDJE
> >
> z{~l4!Uz2cN!HjlkCj+UAXff?Xr3X(h=doBAEK(8PJ7R(~h}J#Vw81R+Qod4npec+p
> > zKS?@9gC>?~`QG~vYx33_7id<K`zM2p-
> ii%2_jS>tN+RZbziy$Ijs9cmJuO+ahuQ)I
> > z7j>4GjsZ~bM5RU9=eGqhs`Qaj5{uZ_Ud6-
> fqr2rZ=VYP@rHCOq9pf8B0xw@Y0Q|UG
> >
> zM!?Zk<hgJPe|8guxevy{rYmeZ3XZT(CR?aoLi~3H<!Oq#|LH!{2|9C&%aHixljCX
> Y
> >
> zK5}5_1g)5_t=h{UxNNJO=i}()%IpHFp4*FsI$6|J&iNV(owzH=B&%B59xumi^o#
> -G
> > zl4CZhmtE_!o>B9S|7m$0I^cymdvG7&?O_?`#7_N(S-
> csF2$3|xVaVFSs$oR?)X!we
> > zeMt|VhMvKpX6;A)H#I){1i6s9%DAJ26co_X3)-
> H!*m0eZZ!QVFvyXV^=j}!Z?!plq
> >
> zDY91FFY*NplC{bSpJZin2&Vas`SsX`X8>&k{NzyAY3jc1P4G^=Q0zC^2=3<uQ|6
> h3
> >
> zJ?a{X2<1ZzRJQRk(QPA<;g%<l1vxNY;H4_&x>2=eA5s%=p7dnlO;Z?5VO|OM4
> 30oJ
> > zI(_U{Z0qELvqlo1zMy(-
> joNCk?D!9EA9veQl0tLN@$+697R7ISA{Oj9DQM!muOqI+
> >
> z1=Bgs)uV?6T4LOq;iW4s#1Tay8pL^4qa6HT7!@@Rr>i&E1MsQ=SsF1QnUH$+V
> XJD)
> > z-
> q8)8gNQeo`#0Z7Jza*>ERi5<^v6N(%;z%&RMDX=u`GthWVgqebN*;CA@l5yVY
> Y0B
> >
> zM#+iz0TlZETa!j2;R4p_#Z#QaXE)T=$0BRX2r5Q4t#09>^6uv3f&M4abAd3EhC!
> P|
> > z4%5A{^Hxm%&5>&TpO2L9NHgR5dlZr@E)-x&mF|r-
> *H*VR4`LaS<<C1W7hg&~pO+K-
> >
> zBGo{Y@aPv4Ea9}4gEHHGNdLE_B?jDJz1`pT=H(py7Ng`bivvR+Wqhpw8tYpsM
> *ANN
> > zUz%6;oPCB&&k^}WT*2fbT-
> rDFvy`mC$)TI2Nk1)Ikk#s3pnRcLwjM%Tw8%J{?)(t{
> >
> zq396Jp$smKz^GYiNqjNEWssfjivJNdhnO1H7@}a55~Iz3qOL=t!QDgUBUhGkI6
> z4P
> > z{MfuNHeOI7d~NQbki>Wa*r?}Ta-
> }c1`Fp+#WtVnfNe=$kV|Z$iSMH~w=I;erMwnR7
> > zw|sDfC*TaJFq5#HAL{Kb8A3bLIN<&-
> v;f&Nu^nHE+8UqQ6i8*Q|L?I#SV*4Ae0`%z
> > zt4a)1#BM<3QKNZf82X|^<jA=GHwMyzq+W|6V^1H-
> K&kxx^&?So<C{4I6S7?YO|w1&
> > zLg3%pOQjI?Y`G!u^u~Y!0L=Ck1mikTVrbhz5Ih-
> 2{<n)!I+;AHbRo*RPPJ<gUm%2u
> >
> za5S}B6+!!&Ng(mtH8YRUXJvCYVRDX`2TJ*uWP%A}VGnN?PQFyp(oJ`BwDxOP
> d~+Gh
> > z11ab?54FD8tT;pt#a&0b(2(v5{`c``k_#uVAtX<=pj=V}jL?jiM`j#Ib#UAp!sxj-
> > z=hwr=Wu+*@dTi<*?5p?Rvns=~`QgUEF?-
> BXUNalABrN}l?3DDjuoNkTNq%YT73F~h
> > zEU9qnc}*FZ+<hrGgH;DLhye%eWK9fl3P`c9Gf@qV-
> S%|a7B=tS!rdlDQnw_~vRNG+
> >
> z0F&fV(JKNIWL&t`bheKJF36Bm&a%)nElwP|UYAbbp{}dbEmv%#l~W;aV=3A
> WITI9~
> > z80}SbU~>FO|9I4K$=-
> QbieMMly`ua`72+%KRdJb=5lfysMX#bhAlGBNU<hPQ@JW;6
> > zYV;a0O%l14Y*9<q;68nd(IlP!4FIHiRnKw25^A=-
> TSOTON|2ebg0xls`JM}%@O`gK
> > zmH+=v*cCg)>)6&*G74T9ntba~IB-
> 18Gfz;WMB^neWL%=F6kixs3>vAmMHr<#a{F%5
> > zSV4%6rVjJ{9oXWh7>e;x_5=7-
> ig|jpSD}@WGmAamQ&27hL?Yh5&;K{Az^2>@Cxn#6
> > zzfJ#Gsp175xffi<>k)w<7Fn=7Zz86*>n?UC|H;{y8wZ#L#ygKG-
> ke|AX!c_CIepD4
> > z!jPQ@A+Wb%GhI-
> D?bG#nj@J*3uxNfyiMeHj>21xLUv>Py=MkD{x#(ays&Q*avQoVl
> > zpg?U5sxJ^-
> s_X5pS;xuct}1cBNZRsM;C1Q>jlfkS4cPm+6cweCmQ2X>*vM$GDUu2u
> >
> zrfP1oY$eRO!g>r+1gwnimAE|l$MTGy>m?joS%%YRa>5Df5UX{zACOD1{BvRz
> HY16t
> > zLx0%NJ(|W#Mwl0yY1o;LJPJnEKBM09erE1AZv4dMtuK?w;E4l-
> Fr_U^mpQywF7_%T
> >
> z8z9&|c<+j$K?1t6WOy$cdaokTE_CD`#p)wGob|89EI52O93E)Q{K$ZJ9lbN2{ami%
> > z3WLpyNKP8CAgc&@A(`}Bq1ivs$JfWbO0b+fTE-
> q1jNZ1iQgnD$U>`mLw>B3j#@z5(
> > ze<0^A{$CJLLB91m<D4C)rnY7zCoS>|xEJAm%G@|mlPu=Np$qd)CI{Byi-
> XyKLbhKa
> >
> zbm_vregABHB(ocN==Nhk`LW3P>i`=<{zk1DIb7;m&+Ab29lq={<Tv3}id~}hPil3
> p
> >
> zxc~1)=${q^{v@_+;IV8Ms3^28&cY;vbd1T^P==GQD6a)fYP+^ngHK~6L2eTcBM
> ti-
> >
> zmk}MRW6!9~7*x60swGmQwgxUcS`NlU#^l5ISq7fW7{N&QrNUGGL!nbun!*
> K9fOo`p
> > zoDYA)K^cV*4vEOWFJ^2LrNw%4F#I+xUC(W_5t!oOcgGs-
> ui){uM_Y;pwOERO_?nhh
> >
> zCN+^j*eU|(H}@1|DulXQO5%eTuO^dyTfO4288)&1e|1FEFrt)@TOSwP@avg
> p!5R#S
> > z;(Or2(uI2$O)nW3{}@x%qW#F3lm<r_6>%p!PN^Q4k*MIfPn}J<Q-
> UO22MYfNY*&sB
> >
> zDxGA?Ob!k=V{1Vo_58kh)#krYA;F+Xg;(uT)f#UCe@8A#FqlpPd{JC9j0)vznO5
> O1
> >
> zbCL1e;H2#lmE&>{?pCIFbEX32jw!tI&I(V|qNPc=^A~B*obFWHxk1Fv=_jDrms
> N1K
> > zfJ`e~-pb3FaAgQ-;P3F{-`tx{h7xfu=MjtAzGmk8RNyMgl*Q-
> D2p;#e8CCpYYhflt
> >
> zI>`}(23b2x={^bAkgx&<@Jcge$e9L23T@|C6&|K3l@{*|5%HK1McZyCn8_TGr
> |TU+
> >
> zF~5LUg%1V%8%0BV*|~kh%Dut%HC71EzyXNZ4;Qd^PF~!HyUjWo^B$Dv1@}
> qgr0T7w
> > z<XUd9YdH`MV%gjTsUwYem-
> CF0d9B`ABCaQ2E}$11V!4Of61KbmH>NOgVE2#7kIj!)
> >
> zk;#F$gI_*X5(qx&LYuNo5B%I80hsrroF9vlFiH0ninvj3>2O=#52$M68oXT*Rb5*
> D
> >
> z<wTAo2eWP(u{WaeatrTT^XL;awIB+c01RE~V_bt+=VY;1w8PV>J%lB&vO<Fx<
> D`^2
> > z{8-1a!*faH>RaFfTUNUi2qCgc=rd7!Bi{M)r@?}!GWRRaP#&>6-
> 0h5~^qID()!>0O
> >
> zXjOi@8lZPgi3_oBOHlc95ALJPVsFWOY2TUf=8qUG(3X=Z_JOcWht~V{6FSp*+
> w)9*
> > z7#~-y&DBS!<Rl@4bGT$|3F%=IqC&=%b565*fp@;@AcP9L$d>pgoz-
> xEr*zAK9<N?Y
> >
> z*f=%7UE{!{l|H1Fjj#kVC@=oC8Nb1|M?~RgTHh+7{|~FK_mV%_#jkp>8RzR{!
> F&Xs
> >
> z2OH*N8^aA&PGW+RcU0BM1qy^<mx){DR`uF5>m(XM`@+)}j%P;i&R47VY7h
> xqkyHve
> >
> z9D%(s3F|y|mc$MlzO~<TXodG&_zlOomz&VY<P_#W0~mRqlg(c1n`*i*em3v
> pE(bW+
> >
> zaxDLeSjw0apb8aLoQ0v;3(wYcG;h3k40nrP{JDn1=F_b_&q<s4g4a=f3_}M&!9(I
> I
> > z7z+Y;fSWe;Sc)>2@__0&Q&^1I5X990P$dj^^YI~)rIw^9T?&zVTi-
> ^Z?jgng+Js*a
> >
> z|9b&ZY?It?5l(|UIdrnLr@@_B|8_zTYtW9ZRJXZ#^UlwdTqHB*mNCXnWUyI0K
> 127i
> >
> zWZ4_!;*wMCcdxhkL@ebgXmgC$cIeXZ?$w5;J|@C3R$#STG3T#uS!A=$$dEe
> WR1yd=
> > zOy+GS3N+k-
> ;^Rm&4u1x<YeK$d$k^F*C+LEp5SczdWzLLLhbxC8#LkmGI#iM*X8KHw
> >
> zjeHe|F6#e{I0+B7voGoVb!|`!HkwzQDD4AI+nw^ppfKB9>_d@A4DT(%J8*jZ
> MwuHG
> >
> z7F%{w(cCew1__ovrMAOaI_u`M=VqS7U?VT!E|h;*MuJfgs~Yk_MS#v9N_7#
> TNTye@
> > zhT<S1SBH^rR|lg>YD$rd^bWWLQ2BW<c7M+-
> 8Mp5YQRWhyS@`gIr&htF@U=BD#r6X7
> >
> zPHn%Ux2^UqN@h~+!u^)JVumKk28YdHc*w9BF7T#aTi#3uP7R=7K`8!$;M5Bp
> i=M9v
> >
> zloJv6mNZ9}N8k~3fZQ&GJZBBqLx~RZUlPnB?v8!IRhnA*eQjnq=Ockv4E=39YP
> 9f4
> > zx0}1EUE~rVM(wn<Qq*ODx^lj`OAG0bqJcBvIyIx=d(57w7>lh&Tst&Gc$&f-
> C*U}T
> >
> z7Si!|5a3@|0&MPZ@!esgnrqWV?&zpYvYJA%%UvSj?AjSv0?Ue<2te?aR$~N>
> 2T=@i
> >
> zk;WK=@?1|3T)rZRs9V&eL^;vna<HF^jX<WlN)m)?+ZcEoAQ(0;g5457n@r*9a_
> &ip
> >
> z$~1WN)69}m29|3!yZ2zu+k8F*1AJ_Llq~_P8b6BEa(GlhK;k1+a&+Rc5du{jjbED
> M
> >
> zxe=ww<nycYmE+CH705)_{**!+H8xxhAq@(!)eW)@wna!{Fr5Wo!H$o{5jv@#
> FYa5e
> > zoqbY{wWZvbeW`6=E>_jA6)!I!+hCu>=;mMBB-
> hjIr6^ba%1jIlO{0DzrRDO70A?N>
> >
> zHB5kj>%Jk9$rkL$#ANd1DT;=B$(N>NLZAy>S*!dV2wVQ?XWa5^hv6q+XHK?n
> --MxQ
> > zG1h%OC9O9yC%If5t*4BIdz)$gh>-
> Z<h^nHAFV1lb9ljN<3xI$NhxpHjPI%2wK_qMQ
> >
> zpnE74osaU=9m@It_0)?O@qs5V9r?>b63mk#v%VR$Z0vstV5%b4Ff~@nLFDV
> SbVYbX
> > zpi3#KXDI_-
> <!pP%Y*hGd@&)d<G1}yt0#B82(H+~naxm+|Fl?#W$lIhw3=9Rf`%WvX
> > zWqQ~fjyaT;zy3NjJSsllcUt6I^Vbja$ftTtRA0}&Scx4+{UHcXb^7n4kqqWF(zfBS
> > zG8P34#!ML$P@MDi=TApfjl@2bofNRe+fyVMyS(d-
> XA~5}VSN6cplAA%P=_p4Yqn~a
> >
> zwEe*&`EnJ%Rb7FVX9mM@?&{b)0leLYBAdTt;`hN0{a)_%aBBIgpZQ*|O63;Q
> %9};T
> >
> zn`igV;AX&|r@oRSNiq82K?Q+CMT$<Yzif%Grbw}#@^2QY97bt{Wx834gst*w#
> X`^h
> >
> zkW#1DVX$qsEf8L%&p5&ekmJXuPWVM3ovFo?&org2Li<;RE$_4#`n<<$hI0tj_
> }Ln=
> > zRe8>7)Vn>Hp+sxMmJ4@o6F`sujm%Rw-
> J{yCA}t$O?2Gbro_S0%@6bE|NUO73JAX4o
> >
> zzC%6Llj`Lr3V|Cr(`1i+0+ZzV2~LvYFi*F&#G_|0wAMn_&Aw)@GnxGrV|g_yM-
> 0<2
> >
> zy1O7o<hUzEDWxC}hKYH^g1jozbmjF%%$yNv2)BgGfmfaS9t+L8x*54$Y`W)nT
> D9y$
> > zp>qxUd2lC97TU5jN8}IB`Ag3sxl`T{Of4-
> pLa1nPSITX#OBNv|rTcQ^sn%oqV(uYJ
> > zkz%kv_Lgdw_WyuuP~=!6#a;*YD~9T&b`vi_fl!XAZ^kW-
> 8FRu~9(wk+ock12GT_Ja
> > zM^?ezBrqptKLHwLt1X-
> 1wZ`Mj#=hMa`?~<7O+}ta8yDtnyjj%r2f=TWOz{2DoX0#5
> >
> zBUu(L;a9s>;Z>oZhQZ91Pxr_<9A4ler=NF4Qp0^199?RAz20GCe?Bn+b9QPxa8
> 2+`
> > zJ5v`+v>2-^Q{~Gw<wT+>Ypt21CHi6NJ5O4gY7g4=zH~z|ySjF-
> GVJ3Or!j$S_H;Jw
> > z%v62aUg?du*uKmjcxF|2AAS@ymb_uqT2)dK(`QRRRk5H-x(Fl1Nd=L|!-
> _c(_oRc|
> > zD#k3PDk7ITbtXoZ5)iK$vZUO53H_nr^4AlP22LKwD}-
> ($0ZmQkxzN+R9ka~NXuma=
> >
> zy(lnzTW%5rD4mM3!MC~wzcoudHjVZh6qZDxTpdAkK@y;BzJZ~#T^v9k4Ygh
> WKn#~-
> >
> zFw~d`jVUez@;FFJDdRog+aP%DTEup~nBfe?o8EOvlbWmfQBsUN3;`Hxv%zN
> OXKo0`
> >
> zymnf#ub?u{JO^5d+F%A(!)DkfcJqa|z*EjQpm8tr3CNSDL8ra?Dj417x?yLcYC?f
> &
> > zp8J`PD$&7_mHiYFm{7=Z<WD1CD|rQ=v-
> Jx;eXa^9l*S+^%gJBl^zfnlNh1)bkM3;(
> > zEu4XqR^?OoDa4yjI)r#-^cA0Vqt+g7MvT@+(UG<f4)K9y-
> BrsYiU;W<x<Ea;>dpU@
> > zmR>$-PfosIWz(r5(5<wxPbjmo;#-
> XOOI!CTRs5D_|2EQR{o)J3dsSY)0_f4&su0hE
> > zuqrLH0@@HpjE$MUkBwTlf$r97bmgf@T4rXivK$k;7B0{N-
> z3e*X4)s#1kO^g=a{~c
> > zv1YS_l9RD`FsL4~xenL+c@N{2D0cxFvIf$i1A>M-q_Fh@-fIs)2l9cYB3gpk+fTrl
> > z)W<<5N7esulR#)QKLOZ_yMPT)2lP-
> )(2&}?&!a(E{XC(M^JVebM5P=yNoukF84}qZ
> >
> zR0K_d26Y_RR97K9)9?pp!(G6tsReL|T8O#>x^K0>5n2Z<;CuG3H+#XDTnT7O*1
> vI2
> >
> zVA^V1Aiy2`0Xo=6&}29;F}@r?DN@lI8dL06fg+L&Pw}&k_4`+p72Ft%js1<1OUP
> |K
> >
> zcK~H%3<&RkL)OcG<U~kxaddpJ>IUYmx&hak8&H5Avs`L^|2OdX2oOsD;cFq
> @+3pvf
> >
> zS2X|~^&OIEqz$gw(@W;PH!5VeRs=Uyr?F<F?5L2X0s~;Fhd?Ix5J)w~As`B*mf
> hc7
> > zU4=wyP@_L^!ey*x-
> F&zLbdCN&P=UZTAj=RM#d`q0w{eI|=LTAq!vsquL%{u5lWtAe
> >
> z?H(2t4~%{`)yK^m|Ek)>UcVCb?fw7;=@US7@&x96PvAv=3>oYIQfRI5WKB*$
> w2^;3
> > z&~ayF#0`*e+`x#+iQS@uKXrXjkNlr&-
> EU)dialphdi2!2fv#;W#&=*3tizw4<|e7(
> > zjLuPCB72T`cKDfh@9+Fx2A#lJz-ifkpGInFYs-
> j|k|gNJZ70eA<}HU#BT%R$jr844
> >
> z_^<=dtZ^ExTevN)kTL$ZSsY9~d@Qb$cH`p$_dixGkm(H71<xX`yz{W`YV8Q4Vj
> PoM
> >
> zt)DTja#<97Q1XTOHjYl~g9lI7S0u_Ll5>T#X|^c|cg|oU9SF@Pm=D1l_yfEHJ^zH+
> >
> zXNc{<^H9%bh){%BxQ2B;u4=X^M<*w)_@(IlGqUt=7H;!BK*3C`k27VS{29{96j
> >aq
> > zd*Z$e%^e0qFF%5@-Fx<*r>vVp`y>(D0RRA}UAFNT%p-
> ?4X5LIO8OnL6lhYB0`;L2G
> > zM9$fNK`EpoyB_urv=A=&^i`+e(@$0#E`azr5%vQ#B>y-8FXGAp8F9cu-
> hUH$waRbE
> > z<^`B0A)ZO=*&-cUKnBt}+!IeuaVG=Z-
> 3ROfnZ_PG{$NnMAK%X%Z_g<^eQe}K6mTGS
> >
> z<<~YHbP+2cO*=HN42<g}ZLsy6xzk25Bo9`?BVg=s+KUj#nDIMpGQ!=|!sz6~Ft
> zw=
> >
> z8WK$DbOdZIOlfDTp4J%w3&eI9Olx$zA{FjH?g+aah^b7|7cMu5v5i0q{qP*r;ID;
> @
> > zY0#{<G>b2eTG4>MZ2t!uklMlSt+nUBQ-rnEb-
> Ku^g*?Jj%`fBlw2V!m#&|0;qk(ix
> > z7nh)TAx3t0%o}K+1?TBaPAS+(e+RD+1G7F-
> ?Au{0G5tdd)TPX1hakJ3TvR90rM<^Y
> >
> z+#BZZ%KR3C__(aao&#^=SckY7{A8~MeG|zb9z$~vO(vS+@!8o1yAX^?^J&qa
> @~k)f
> >
> zOIv1m&s1ejnu|q;`|{G#eh(poDQMO&YIEAmeO+(4^M>v|7m`T|NM>t;vpZ*
> mL4-Kc
> > zqsaY=gDd%ER@*_kCK7QoNyz-qE2~+(^>wi61TZ-Qmdc2u!gX|x!-
> _hOdW0;F-OTOp
> >
> zHDC;2!@S)At1IAsPD&Dk3IiGmkb2AabM^FW6hLKog1B}?Qw|JY<+anh+b7{!=
> X+}$
> > zFuvZ~++1ipISzO)2)RT}D;-
> aF#h&&LVPerTeMCI$`Fid9>&<+@g+1;reZCWo1qv7=
> >
> z3(_wxUF}>;K8}l#fx&d9J*MH=X@kDAED3@Ja4`KZEZ;3%O~IsQaX_T{i^X(^Eq
> 7GW
> >
> zVGdnWiBZMj0QC(V0d$w;%tX}=M(i=SFoiY==^gQ$f>x@7%TZ1+L7xy2$8t%n
> UePA~
> > z_hxdvS8-
> a6)<v#R5ssy#;kT<KY+2yl5r8Q1=uZSm?I|`fe*#+WiiH0$|MrBtaaQ*E
> > z_f9&Bj#Bl`UV~tRY)q1{x?CzQIcY(|vTo_hvB9C7V+!elvbkj-
> QgjuQpS8QXz{p&e
> > zOV5>148VMNFi4W@_CEZ#<j7q;G}=qm5+-
> @Hx#0H|P?NxL@E^iOnte<`wY(-C#Ha|I
> > z=C2Ea@CE*LYY3?FwL2-
> o7w4kPn93LgoLgo;Ga<Xlj=#TgG8v4ak1&49lH*5a$dnbe
> >
> z&U&MLi3d9_ut4tlY7*dTjv;@%OQbX3dNxhPB=hp0T{&VwWsaW2bXbrrrk?A
> W=XSe-
> > zu8ysIXto_N*2b4<F2X2)`dxgdVz}*|Zn1wChW9|MJlZa;3z7z=y^i)-At+~E2-
> =Ns
> > zM-
> {9q@{JmR%9_<EUy|uGgbR74yk*6Z%vUXDUOn8l)41|HH(Um+fyWEpH)Vs45
> 6yTg
> > z9G)tE5Q5Y{ZXsama_6};iU6%|v*qgF@jt(KgTP?9R%0g0tRL-
> 62S1{LY+8Uo@`UXC
> > z+kN1Bicu7QhJmIwI1Hl$rm)P!O7EbH{W32z_#q3T{lFs_-
> =gt@_z#8g{&FBl60M8q
> >
> z=jZ!QxW^d73Pc;jWas>Xa37s6W0xXy%cAtwDBkO;K!XpFn$e$5ZtLRx;<}Z``Ydl
> <
> >
> z7lF1;us<(h<HwNLXPdM^jB0KbEype0uAZJVCPGA0Ra&n6V{3Bz23Rz&K8l=#s
> +<`F
> >
> zQ`K?a4vlk8w9nbAxN%8HnHzO0BJKg7G3^gZ49)!b<}XUpH6YtiUVE%Yh>De{v
> |da*
> > zjd+5kK{DBy(^5L(%$4w%u0nYr+b9F4w_9gC-
> !c6wZ64KV4{+qqvrkXa4qYz3afv?e
> >
> zv!MNA8W@rI(1nM^S?AX792oexy`xn<+;^98<>Ke>(Ozo~PO9&t#392Mo2Xr
> MP?$BB
> > zOd-J<xYW8H1RRa|E>kVw-
> `TR<hqx#}<=Q@$(A!`+%%E9&^w7QC`0kX&m#dakHuGSr
> >
> zGR>AiGBiOs(VFWhbAjIaeU`kO3(dR8OeM9=jcZ!EbgW_mzlzWAzIcef^>|5n)7
> z)P
> > z?`N}!JgBPO#-G`?Nlh)kA;XEn5I%o!7zhyxG(l#d{FgjD$eMp1@1(i|qi}ZBP>;r#
> >
> z2Q#2DZZ1%w`Dmlr6R)G9K+M6$B=gNC9LR6$Km?HB?T|8ei#C$|l3Ue&xr(Uvl
> bN}<
> > zqLB8`-
> ^A{1e!kwo*YW167B3HSxyyY3WS?<5jjRBX45I!39@CeC0iABDv)@gHrXu{1
> >
> zWi;}ax7vNDBlw$X1}3T&uI&fo{q4`ARrj|R8IvS0q(D=*V;>LtXgRF;At=>%qLwm
> Z
> > zfzKyxWG8v<;kpatkprjh4IrS3%v3`;6+f|vt&X04yA18muj~%3hJ^)FR+9S(sjelq
> >
> zCkx@*E+9CsQrKU}^}KhgN>VIx`?|lwng+HQWOB;mP9s_ou9dDasTup*%kwo
> X)z(Tp
> > z@8a17M&3E$s6ceT;Wox+1F%T38h2zQN_gyc&y2|UuRhYz(s~5JD-
> jHBwcr%20bUM~
> >
> zh$cT}^9$NmD{MUl^XZ=LEN;KLQ;zi#ftdjtuoYcyFm=1rY_8&ItIx95vHBNaA{qm
> n
> > z=r7WhP0hFla8gOf&e89V(6sn;9X)PYGlwFmm8TXRj>&WCw5f-
> bCjEDTbbkioa3AvU
> > zTgs{woXY3O-
> Ns#)ve@9NMY;oo)@TE;@*Kw{bOZiQjK_TpSCkL>hiH|vnHS*twFPeX
> > zX7=;$<R#plX5atXoL6yZXi2hnd36LCKh^FwL-
> Z~vbV*7~RKAZfiSoxryi||<$Peh;
> >
> z{LDO=8=aZ!vrE7`_zV402>#~hF<btRio0^#29f~&bMmtDkHd=qU{Us<E&U)i|G
> 86v
> >
> zoVxbdt@j_x=4EH*npm=H>2Kc#=g!H=PKDkoBoGmj8Z?wfME9i#b;%s>uHm
> euJvQk4
> >
> zrD$#eSZV|6lkKX*pA;b5>xpHS1FU6buU0vq^^pO<oT&Dmzk3qT8?XtMUM+
> Ant>wSc
> > zyzqFMc8Y3Z3y^#}T)iton^>0s@Wzu?@7X)?)~m>HUlce4|Af-
> Xuf0lKfuTpKFA041
> >
> zQx4+PwhHUFw(Eop5aMNtf!5V|U>nZxc8Jdxq0~JV`ZV_yIGG(;W=~~z41xdY8
> I;hr
> >
> z0xwRigX4%7;JFoUOkV*vA~aP>^QpWwKysIeqY^7h2fnPJFq@#l*0rRB62iCn+
> wHXl
> > zz&1Drp|7~EN?!zH5pKw!JvbXK-
> ir2&;dAjelE~?bIwR>mA^QX@3@_RN#@q{(BC!KO
> >
> z^Kw41z{`{jeOz*@MO~nbPa1NC9aM$lQN0x<jbN^VxS!|w7Z+Hjf$y*T+<`c{U
> gB$R
> > zx6k>}-
> ^KH7O}X^Oz;Z1W{tHv=b$jNUE6_g6Kq&whi}d9N|7~jbS0lX)V2Ez*`f;dg
> >
> zt<&wmwS@>hFdJSzio$66vA+DsAh!4|7@aYwAmWu>IN1O~cIj{jgHjDYkQsY
> D;>-$c
> >
> zI>%fC5si|#q%nyfy=QDYHlD2(wlilMG_?Og8uL6|fFm)J4*pIZ8}?{VT9<T32czM}
> >
> zz<`sNU+}&Q_;9IkO#HXRP*(ezDNfx|WAXdJ92EYtZv^y0HWyUT43rYRrhQdCO
> P{<K
> >
> zAUrl?x9!C*;&T6uk&i#;>va4OU>~<^g<!Jay%8h)aOp^7EBEyZ@b~|?3}j?MytB
> G7
> > zoN_;)H2CRa0I9iEx4zIJrIUFA$l?B~Dbb!g;w-D*(Co$gzWarr&T|GZxrY2eFJJln
> > z1)e03ffoC@ZN$1A7G@+T*W`djc^vmzNgS}P)I{B7-
> kO_`Up!D&o+Zeo37N~wiT81j
> > zNr?f%PSo}VlHLS;Y#<=*USqyLGhA{<C={sTdUGY9e-
> +C(B!Y<Aj46`65i%71cYGD{
> > znN=A!NCDe^oqvH%28f2Uyd7%uaZkVr^2Ys>xC>dAvB)UQZXPhaXJ!4z0F;-
> TI~;EW
> > zjLg3{<^1=OSURc4o)1tq$F3IO3|7@U%5rc605jnM*u=Z9p4*%YI$Gl<b+Rv9-
> n}xK
> >
> z502DtLEG_6$;oyhKVny{@h$9M1&!>+y+|lC#yg#?z?k4Q);(Iz;dre(IM&i&ZOf{I
> >
> z{(hbv3c&=Ro{mc+WSK$e`q_E5PJo(N*<dPRfmXs9kZ(2)$owc@W=TyVuG}HQ
> dnlbj
> >
> zoFToH!G~jO$+R*$0{EKZ5dJ7no}c+>=3e|`+*c{`%}7ofE`3kpqecCbA@qY3z=j0
> 5
> >
> z{pEQ*=2eG|vbR174ZndiXxF^fhH2k&kM!f1uy%A0eDB%Y!0(=zChh$;$S<y>J>
> j-Y
> >
> zZ^<2ncA4q&`4w=0et;bQ=H)gYpgAOZDHa`|7<ToQbS+BZd)Y%1CfSiN{sjonIe$
> ^7
> > zf783)S~m*lr&qzajrWI!D5FyQzD#h;_?2=jV=~UmG>a60SLXOSu0-
> O=A5+6B7bE#7
> >
> zhYO%G@1@I%seHtnhBB?`=Xm^0&$Q&{POQHR{_6<=Y#9$FGe=&cVnE16lCJ
> !$pK^xF
> > z+O2|3$2~`t*ayjjH-7by{2u8n5IPbEaSGtjv;*ifi4!LD1M6_2cdvA~_ksx;xntn>
> >
> z5mc4jz)=MLf|WIB$O4E$w|(lDU(nWp>gutdj%?qpW#npSx{XkkMK149>|g1Lf
> ma;W
> >
> zz@ZBMjKA*<h%ml&pyfEP6IQM&^Pqp$rx!{TKk0Ygb<zHRJY8i#R9)9K0BM1d
> ?ixTr
> > zx}-
> xSh6V|xTS);WM5GiHl<rnaQBtH^N+gw%lvbou>f2YJ_w%RBoO|cobI;yq?X}ms
> > z+wPkcVoF*v=aByM1g84rO5BRPpi)C#*G`rKqu?D-
> ^e94<`cGBaYaA!4zd=KEsJneJ
> > zd%}Zl026m#*+6#l9yFz!8d8<-
> XE)%+T)#g)iud?Uh@n=OKpmpN6Y|(vh9+~Af66i}
> >
> zC+}u&X?R4bW#^;u>A}>#7rrn1W?tfP_ukq83z>r=ol=z4oz==&;+`xn3L3HYa}{q
> +
> > zD#6R=4Z52d(S5iva$jQAz=xFyN-
> q~znxvNDf!zoAXOEXXdSb+g8BzmYzXab`Bop~(
> > zyz-&-#QEpff|Dz;D-}LFciJf(C3eq)rhsCsm3VhG(yrhi5{-gQu}8eT{~lcs$-Mpe
> > z!2+1otlTU#oN18nbcW@9kNZQhm4AjPe*an_%=;HO&gPurv)AyG-
> UmfNcjAaLEpl$S
> >
> z9RpDikaN9IHWlq&X$S)F!OwSGKxcz3n{uLsvi$CFkH2TMF3?=hLzHb5@v!q{C7
> m#Z
> > z1f>)aDLDPf#(_xvLI-
> F>Z}w!CMd+OmAeVD<cXi@B^1W;KS31OnKI=5ohAoM#gXhRr
> >
> zyohoSxQ&Nj(RtmWA#w6fz6IuF(=3F07BS^9lV;=44vB(I?CQ{$y8ckpizR83h{1>f
> > zT08_N1kq#=B|gvHKTa?!R<m(?01&U!I2Da-
> d{&70ArUQjSu>%=MWtVgeZ=P_<Ne~e
> >
> zjiP(A?OpJFZU3jaT!gt7Z5FceHs`S@4QvKA4(ZX+Ki)~jrhc^fOwq2(K>M_ar+=*S
> >
> znQ*VJeRcjMWmG>X0@{h5Za0hd(?%_QoeyPwvHs>P+ahRNNY+XWl))8MZ)
> p2%fV|*A
> >
> zkt(#|ggnw6k>TmD7Iw+bxp<54E*ZDLqtoLDfQwYLv}F|_`U)&bu30Cm(4M~S{
> F+?=
> >
> zz^z`&dZKtALe)!mk|3ngTeZK~F^ifjN3c2?;X4p^$!MbUbw>pD0B74Xi&B)&(?}
> D0
> > zIugZZoN&hDJvgzTn^^1-
> d0xP8g)D2Y39)HEmFBx*n9LC+$6Enne6hXR(7}X&!_XuR
> >
> zwji**y!RiCR7RSsz}X0&@)sywkm=jg9n2$e;{D%a^9?Lv!HBwyyM6AwG7h@y
> wh4&L
> > zyBwD(5{qU4{Ieig%`C*N9im!11;!?(r{9!cBXPt%l-
> +5W5EJWN40wt&=oX#4jZ$9v
> > z{*m|Amm*N%kQRb9$CCA7v$u~=Gi{8u2vjN`&fId$;!qJPa2{<-
> APOr43BM{y?@d>R
> > z54%cepV!9qbxYaL_3$VxwsjpQYsDA)_|(dO-
> x&lC0KfJO|C8kgnlMCC`W~^izTp?z
> >
> zq@||d&(_INs@5efLx?qm_ja(T09^D5?Ys=4d~$k^IZ6mzw7Q%f7QEv`ul3K8rr
> $)4
> >
> z9RBQNDiJioKM1BM<L&P(7)e1~+dvYa2K+F#%bS2pCVa0{yd@JSifmg>*bHZY
> ZjNU_
> >
> zKFLUvobQH+c7G&flpaThp}*!aO=p=<5jeR7x!1UaAU}UU(skINr_8o7R|VMP?
> LwJy
> > z#n16?gy`wr2f=vZKv}lf^K}HCru1h4S?wP^h=RYU6q$Ey&miVo+kAcBx+1o-
> D+MC?
> >
> zdh#|>85E{?7W+5}$Zz)l_yk9(d~ZA1K7%WO+S{h*g*>?dWzmVU*hPmlJ6Fk#
> R@B3p
> > zS5M{2#~%)9sHhknz)rDWB+CNsEh;lkgf93*+SB|-
> dpiIGuQZ&)3%pWP8|}U%p;pe#
> >
> z>HsfgKRv)ITV?@@V}KCPz~Oo{Uex%q_cOz`0X5}73kX>6A#r_3Aq8^CfY*Jv^c
> gGu
> > z<x;1&YdE7!dLGg3LR#-
> vmmdCBjk`SW)WF$<h_2pH(5Fp#l*No+s}sNTw+S4d4HxN>
> > z?aBHQe~(b-l2-
> _R1*rBPB6kVLrx_>jHRLYSlA)2x6A>oA63J8vYgp`QoAHRSCj45%
> >
> zFVI2lgreX>Yz+W;;HLbQC*N|(J{EfqY34Z{RMXnOWdSCwO|sbIIgpQR?;a;iXOh}
> R
> > zv0N8>X&n57s}J8$=?=l<bk$t68l-
> p>oeD9TH8n`mv!#sp0u=YY=D@kJ(;Z`<2*8!;
> > z2QH)1Ib<u_Pr$`H_r}5*;$Z!H1Tm3rrnYm<61+uw{yuom0E_Prj>=oK^I;`-
> <Skpc
> >
> zElSiRzg#gDllQ<r@!UIG5Fh#36m;QGrVi^9bisFv3w_t=rY$h11y77CAFbMnPxBI
> (
> > zkoIi}NEVla`Y#J%03LZcl9t&H5=8j~o@eTyndafltb>9I&Xq=uT)Y(|MxV}+UBck>
> >
> zT^ej#s_4_grqGvcdEap2bIOsxRQ0>!J0P0PiB0C%hFhS}QVHA4flL+Fr$m0MR1=
> O7
> >
> zlV8E`m7C6=Ympoc`2)xwm_Y8m&;4^XA{L%;PHjA+*8p!*ORy}m>c^;rx0S9`I)lJ
> Q
> >
> z>Yj&UU<mI+Xka5Y+Ydb1u9b&hXeOBxH*F#C%~^VJR1CY$qvjVl*RAgON0}c$
> &S(O@
> > za|hh8o9G32-h-Z-AwNW*NAs%Ok2QP2*64Ox9)PSQY`C8T`t5l-z$8~{-
> gM3Y^aD&p
> >
> zl;~^w@!x;!kv?=Ra(Rl?3ozSf%6b`YIaA+9H^I1NVW#Ejq09%Y&i|YPk}yQ~bS*C
> 9
> >
> zH`Ia9*4M~uk4Ij_N~?${@%p|ZzdekkLK4Evj2Nf~KnaA4Y|0Ff9b$SrH;CceyhP
> wR
> >
> z^h+EJt||>1en#AMJ@x<xs(l#!3mogdh?loT_tL&IuQtv(ZTbL$Q|mgfX%$+?mA
> Ms?
> >
> zkvb6aL82Hn5hWQPxRz$B$AF6S;qLDfO&&S<7(3cmzvF2p?cw}7UL^^d9Dn6l;E
> F=S
> > zx7~>-e--
> gm)shl0(3GlsgAmejhGC#BBI>?5ZaM1_Eo#}c?FDa%=OBqW^ykl&Emifo
> >
> zV(U~P=_ItAZ~9x}C4;7~8?kyx@k8Oz{2$(HkhJW;f74vn1@Yik@2{=2{Ky>BS2`d
> P
> > z75)y9nTUi^rB>ORx0b|5#+1aw{XN8h@3fUn2zCQ^cw(=-
> P0RWsv57^A{E*(nxRVQs
> > z4MYp=@oYFek9&$~Q@(INh%!es_n@9+WNxL;C1f4Y(%SU^w#Iejj=&6{8e-
> eJ(bu7W
> >
> z7w;{TV)#CXjaPSRBs!+<Xbn68{d1rneH8>AHcwx>59Vn;=#@S!^j#@wC$0>eY
> Yjt9
> >
> zAPqk0UO(`P==eL1(v)qDUhFDyd;Ns4b9V<?1lLYmn>Ii@vIaaKrezjM%rua`!;fy
> W
> >
> zN^8AtCrC5<<U#zw_%#xwEQf@|kM$DyUS@jlZzpXn4Z*L|D4qY#B!XISm;%
> MM>h@k1
> > zpXYqySjjo}X1f<jGEBIuMi_gjD-IvRsjzm-
> 4K}7pe~$d41@G9?JVE=j9^arESLcp^
> > zDw=eJdgLX}{+b!rZ}(36{Cel#mi816-l==gLX=4>aldfS_fQb*ch+b+ysufdhRPc7
> > z_a|P1mGIWF@Mp*qZr72GyYjv1QpmG^@@p5imtH$<QAA^pZS|oW2-
> Z~r3V4w4#M}^k
> > z*sj14;|gG&Z*P5kFM&v3b|T4P^Y@ez)00H27jC;b-?TRmppN6!(7-
> #MPr;?r3h8kN
> >
> zoY(pgHQ~c^)OwIEvQz#ficg*l#qP~Ps#%?{wfc&8tl;d{(8CDzq`b=Ky!9jROlpRF
> > ze@vBF-
> ADj4uHQo&NIvX;*f<UvkCO+K<tmNcUY4JdooV0N$tzHZalcF+0!@%p4&oPZ
> >
> zg^<|=zn+!lvL!_G?1WA<<*yHjQTd&3cN+AaQhm8Ef}~#Ytl&Pt^qz<{9a<pJI0V
> W1
> > zUSNOO+PoE*&!cG@G<3rT5WLlJ!5-IbuhBtqk71Js-
> YBZ0Dx|q=e&coqf={1P?*5gM
> > z-dO<=pUw9Hu!6VH-
> $5kc$7z^(l86&cou0^dL+lSn85gh#q>s0CPdPw0Sv0Ysd{^P$
> > zEQeQaw9y`amUk_l7>l~Wuq>tjqb-v6aAw_F@Mu2VZ~nkt(zE#_-
> Snz)c?Y7D?W@}5
> > zALQE7xQ6{<R!q~=DOH)?r8O{*{L3*_S!NZ$Aa%4|-
> HV!HNe?g<7s!)8&&Xyxc8_Vr
> > zQn_>Ijll%T9KE4fFPJG}da^_nVCG_-
> cnLHyICv;33^$*4$)O!7p5{sYR*wW?_&GUu
> >
> zWmgmr?$5<5Chy_>jgZt7gNn%cy4F)Wl7nyNLP0#Onb=y3fHhrsPxCC}DM;M
> %7_V&j
> >
> zP`t;wRsXO`RJ*O}Y|nE)NIuga{6;i|YEN<e(`nb>aCxDEUliqggU$_WvHx2ZGePQ`
> >
> z_z%!Hyan$tO9S<a`G1px;4H^#@~*)geEaeZqT?f5tzjvTk!tUi*$e&&c}uldX`Uc
> G
> > z--mu$ZE#I*Q8<#GJ~-
> LS0aHw~ZGR5KT#dA!aCWFP%z%Bav8uqjGkP*%Bh%ts5J#$S
> > zOYadBT72WA!GC3=tD@j$Ba)2p2xry$cSJHzu7$XrX!SP^eob+%?tI&b`-
> h@bk9O3s
> > zjuA$(co6G3v*#KKcgE>Al>%ExH&Rw72d06<V)N$$#P*Iyf3_?%MJJv%1S-
> y+h<?#Y
> > zk-Qk=flDo-
> RlkNspn2$&YL9a(SdJi*(vXb096x>?O9?>d<EaB)bl+%a*t1lm*)wKu
> > z+C9W1IPvuo^Z|-
> GFe(WvK&Ai0GvZdYN5S5d7xc6rPvKFZjT1deN~)19(Y@BDJwVT0
> > zbxupzVOFT?-&W{fd{xxG8AXNk%7Pm94u~>&-wMCy-
> t?t~fVXzqFG>P(y1EoKnx2hb
> >
> z@+&uw79B2$lEJyKdaqniuztG&tYA;|i(SjW6s+UZpK#d7dUzzY3C0B2Tm@B<b
> |+mG
> >
> zIxBSp)dg=kbAkxVn)>Z^p)^`N=Ob@Fj7RWWLBp#pb2OT|Ntb4C6aB$zyH07+
> D!#34
> > z-*FDsO~mox-
> k$&1G_Iz3UxuZN&)({9;W#USIHlK+idW6zT?IGU`r_MRDmw93-5v$t
> >
> zr>|QZQHiRjK9}P$%aaL@7!*;{h6rJ5!==#&Ph{6K!b0E&oP=J>1V2dUvuK+0fw
> OCE
> >
> zFS>{MgqHhV_c))pq*2T1g<<?Z=5!FAo!i2xC)X|zWn^LY#|$T^;rWX9|JWIdp3Z
> (Y
> > z)aDR~xD1dzXmhus5Q??fihY8I-
> ?c3W(w?W|x3%hfV>F7NoPhb*v0Y%`fH#_Zr1QMq
> >
> zoxVl$2jlqyGo*@i&mU`=kE>!UkPQFUwe3n?pXg;yCVi4n+qeFLo$Vp>IkTf>n
> @H~~
> > zO34EEbW0F@>jx)KIesBh*b$Kt`dS=(O9jPIZxS*OAm-GaaE{BaK4Re4CT-
> h%26ZX#
> > z7~{-@v;G{8Lxo0@cHdz4T{-
> P(*hu<BwK3IkyMUBUj|Gw=?{l;2Xu6;$B{tD%Dur+Z
> > zXu9U%EAe6spoQ<;`1tH(k++PNdQ%ljDGo<UxA`+?OF9U`xY`5_V+nO6(p6-
> Xr9nR6
> > zUOI24&qF2&J^gHpB;Pll0SAnRvA*geS$zit-
> X7nvR?6z`88tI1O>qbo+nQS%&Mfw^
> > zZ3$IK{RGVZe9g9-
> KhwUi{&~5`XmT~NvEyMGDI48$`@}|EmgHF*YwM#$x@>ulqu_{W
> > zTj#6IYv<7-
> Uh*BmLm=ffEyZsa9rWR+@6XjDym0Orb#pr9!RFL99pOKzt{N+k7(7AD
> > z{ZzN7#^JAPYu-X7Y-
> 03kZ#hrx0^_#A5wW<#y`+spJ%W;l*5G$@vWBC131ePM{uPf9
> >
> zty0i8dQ6vXWVc@yWWxqY&sGHu_OZ78lFB^OBJ(k8zQ=5t{hp~5w_A2#n9b#
> f4A>iW
> > zmneu(RC2$=*qOP%l({AU1d-
> R!*0ha6cEaR!vS<S{zi+2$Qs4c~1*M$7R;>FZB|d&(
> >
> zM<%mKuCj!INbP{7>M%j3tG)<2icbxinu$DwxS8>O4Ec>;(h)D=t<f}p{M!KBCA
> ?l#
> >
> zJ(vY!tu6mQG%Hs@<~kp@co?<B&bA$m3zs2tX4<pagCD@)FqRk_I|s(|m<StZ
> __~%;
> >
> zlikIb58TfQ1Za}R{w{zIFd@CC4neH7!NEVn{6^u{a#L@gPhzSVUO1NUSv`X2KiM
> #a
> >
> zLW_Yy=n797!4EruIG+=;=n5oQt58suzw?@(TDo90yPfy%g?ME5>*#_VG&7
> DvAn@
> > zgFgaw{JUI?+%X3J>0KLZl}j7jX<g7sdF!JOihiY&QBe;ct2S)$i=+eb4<bnvRrp^0
> > zigZBJ+|7M1j$2mJP}iBX##!u7Pk(XaGgtulI2B6c5*bbN1(cj1HH&{c#1SZ3ovf{l
> >
> zBA1+WomJ(!CPlz`XlEIh``iMfF~Ay>!+!X)g!Iz(Lb2P}9lSfJUdmAoA!O%sEUH1~
> > zb{z;<VWwP&qGSyS#MX5w#%H^(78-x(O6eZ)lTV*_-
> EP9=wZkWSqwPf`a`R&_k|@1@
> > zXh8B2JK;2|sv=_0{$G4L@&UK3!-
> U{zu@OAN_~(y%e%EL!x>_|woELo^J37Gj((|{)
> > z(F90=o!*u5jdVph%_{!%VWp599<;O6JZ5J3t%c^RWX@#axc%Y0^CiyH$-
> (zx$a^1S
> > zX!<JR+joeIbZEYtIBvgBnl#LV4-
> NjNKUGnquo0{sQ}?yToJfw3*h&uvhQG6PN*%g|
> >
> z59#5yBIJLyDJM+gu(IE)=xtc9@+z{EpvDk?Mgy+456}IHtptMRUAA9ZlJVGk`L7F
> p
> > zH~c^dv#eL<i0ks@YEx_JW!k*8I#RIItlZiG)l2G19bGgZXNpuL9^rjzJOlG$Rz)~b
> > z)rN(Gm7KRI{ll!BcI=`k-ip{^=o8CZeyB1twe|JtxH6AD&P9gq5TCM;)g?KPkcsg%
> > z%bMZLDlmkuO|#z(!6WQC6x?ex*9oUTo4E92;jz-
> khs!4b#@5QjP>U9%zLiUFG~av?
> > zeUJ9-Dv~3N$B!appHtL@3-
> IW3={m5KK<MDKpwWJ+zHaz&)EhFiibHqDd$t*q46kGa
> >
> zf=iP*`e>AWiFnbRq`w<>@&ItLppgBY#5CsjAVJycTu|rbik=BdG@rdZeR|{c_$*
> yE
> >
> zHUIa#%>!W6413iHE<KfFw*Xngx;+tc8q9t7N&eBU7yNRH3Im|ZsQt;^4Z>Gm
> ppAB<
> > zZ)mY(gqv-5i{TwbtIzAs=BWgF!%q^L*AMkFZ6}+atWj+Lv<PI-+bPBp-
> SQU=O?+)7
> >
> z(AQQ_^zTLT>Hm69Gh&`4jCVb@5x8N4uyxEnmzgi0!6!s>fosh|oV6}_WA(lJ44
> vbV
> > zcYzXTDySKcMWR|0H12i;aeQ80YD%Y{wq)ADT-
> 57V;K;+syy?R+C30w{q70#TZ1(Ev
> > zJPdTtN2ChL+b91B_KC&23wNNX5L%jZxMN}9m>BOTf$-e7axH8W5dnJ-
> 9=V@y@+N~R
> > zS%{uzSs`rlZWV8Sjor|@$P;6|-
> CjI=oMAobz@<E5I`XLAjJt|k&I37bKd?Eey?74I
> >
> zm&lfL&dzMVYV^fNL}_|Wtcaf@rg)||8zfmy%}@p0{Bz7$r!RgP0nAf3A0zk4?k
> <>s
> > z504mry9n!$&LXL_h-
> aJ?L6Rn4UzYN0He^xW(b$*k2H<cB>X19VtydPArk;;nmJG+U
> >
> zk`CI}z(W5j(E4&TMZ{vtdXdU8)yE5bdsy7^Sj`eS?TE>2N2*At7w(zm=V!8c?%|U
> S
> >
> zoovPi`hU#(Ep@QAl?>9DG#vupyZ56lW`%kHRW6w>NC%_Zb>J~=`2U!mmK>
> QHH0-&U
> > zF8f<Lti9^fLDK+L{n2lt(--c-q2D{6l%&__73fGf6(&E0je?Auu~=8NZ+$L$%iRAn
> > znb<|K;rnYh8iTPjt|uL?t|ztl$K);fcGdTMRQ{nf+E&oOo&@Qi`-+l3fo4V!+YvQt
> >
> zlIX6B7;mNRZ&RWU&&VxHmqm+xpEf&vtt)sf`HHG)YPamIJROn5>1Vcu+_<T9
> _?krc
> > zgN3yl59`+tQ1!%a4C{8y<kUyfi#HeCBk!6ntjYTRS;HYMic^uI%{#39`(h6!=ZOF%
> >
> zcLzZOR#Gizw}aSWF*fP832cFQ8Ip(7#2b&QpRc)r<;g)Ssd?bv$8l+v`ZKv>s%Z(|
> >
> z%q7J*sD2G2>U}4g+;R$x%(QvS@tM2YDy7>t1uw8rsAeJJk8aiD|5DEn+^2WW
> p_`g?
> > zQGeV=sOsh;Zt}Sa3T^_EZp;4;9!*!6Q}~ckV6`unv2H!4ff$b=z3Y!C(Z`S{S0W9^
> > zN|zA(6y$S0q9ar#gj^lzZ*}u}{NEI?Q5njE3X<$~3$4RIKsiJtx=KYtzf(Tjibof}
> > z|JIgYCTiTYgD3F-tL~w=sT6P@QWXTb3nuNcbzg;thttblIZYsmX9ji9gp?<?Su^-
> -
> >
> zXx*n5Jk?gb+BYfhE0^&5w9~$uuFe6tt|qXuEdHo0ZOfA2AAVCZxkXv6|4#(H%
> `x`m
> > z!Uro~!$T;;d3|AFH}rbu1zdxTkTq5{Ewxi^VJIY=0G{(35HvQu4K@xA-
> cq+Wq%`jv
> > zfA$w!wD=F5sJZsF2hr;}hOgoi>6@o%7n{pD<<MxsIi6{;PcuGq^$8o;i-
> +%|*Ny&A
> >
> z4}6+}Q&aHD%2(?F6Q0BsVc~DztJMQTo<xF|Hk;W#11=0PUlMM4O9rf7XdEA
> &6k{Fd
> > zW(iB&TPd>0os(2O9UK@Cd#OPHA0yWQEz)ryU?L!%#Zx}oSEAf<>5-
> JAQI7W$CZ<;`
> >
> zf9c>+_}8sltM&1IU5PAR0ItTm|2;f>bR0NORD9o0U5n5wt{cph3u=7O^iq_Y$S
> OsN
> >
> zHbWCZN%MgE>`W(q@AW^NG*I`CSr>qihfz+ILA5n{lG)Gl0M4&*d>A<X9I)kk
> jmz-w
> >
> z7jmvPV`0OsbjXZKjOcxvWr1H#_&E}emiqu_Uf)}t5PxcW>oT9#*#`;*IyvK@=X
> R7~
> >
> z8fXrH$js&R?+S2XOzz1BB72FzpAaj1#f3Vedt|Y1FG9kMaF>xkG$9JvV8%B*wx
> 3D{
> >
> zg6^bY230(RP+I!$;>wzuiv&|PlbqO7tcX3v$B(sG=Wj)e+#L#cU%Eo@`BUHvm3
> SUN
> > zl6K4ju+GMO7r83Itxx@$bKM!Btcl&<-;WKLqS|ys{;-
> XXcn}h4PYWxnsEmq(kHsmu
> >
> zG6~c$L)`73v45duhb!N$(**LRloM_w<c)Cz!t)jSwWRp<TVMkqf_OIgW0N@m;
> Nu2W
> >
> z%V|k`pVQ}j^|2>D2u@fe8~9kqhc;n~$5EGt$QTOs&clBzTTD?PAIW#W#K^^Jk
> V!}}
> > zz+g-
> u4POKg2i=6gn$pjGyjfvExvjAz^Sxk{nfzBms0F>@+xZuav$Mu2LbzjAkqV5y
> > z^6Q<oDX74|ofpI5RF&+$7lJSbisV_sQox*WrSoqMLE511^yCn!A@~BsC-
> xL=Y(GRx
> > zv?THE5DXNx*)?S`KoEum-<3gl6J+5Pf0(L#PKCqDIC5ciurEPuJ(ctyc)dbN`4l^Q
> >
> zK`=SF5~X}+w3OX!SIIcr;y~GO0x2<pCf~YQh~mJong5p_(*Er^$(84TaNky^I&Tii
> >
> zz<a1MLDArE?ZgHs3?DVYtr@AEAf|(heI9B;LILEYQFM(&J$DgFv%OYzmbXyfz
> MXGy
> >
> zt4lykJNWm;eFtilIUaypz|u2#D?d$Cpg)MCob`Rx0!<N_3X2^$lOe>bR0S)Z1FBT
> c
> >
> zd!7JRPe6)(WWX9F0Qzec=cjC~bR>j?v|nY~tRhm|4P;@Ll9LZ(%%$q0pjfsc3_Q
> VM
> >
> z5I|FzgC>bj{V!YFUb)yCX5))yG;GY7vAn(Uk^xK$0vIm$gHV2<A1J_1fZOCTj4yk
> U
> >
> zoMvmxOOlQzK3}It;CWsJnUUy(2WqjeH@+6?W6N$p%)EPd5%&;EdWb)!$f#E
> ;iUxRR
> >
> zQIUF|M}EDp(a@A;4YjqqKifI@rfo7`F{1)u+rmrYe^8`+k4B<tKgOIf<O$o)z7}(v
> >
> zkIoZE25eF5!0d4+F0q;Ehg#xKZv><R&y+v#`7y9zG=Z1!{+Qu7HBwA$FV)r$iBe!
> s
> > zl)>9gfyjo`23LBZ9N_gO8k$&5QwF?gFI@c^Qb!slO%AvWg(R4woV<-
> rUD)H9&Sf@E
> >
> zN$ZzgivaUPhg*}lS=K4+AtJ<U#$?p7oE|!eO!$s&7+t&>8yem7u|!M&3X&Wxn
> >#iM
> >
> zCb^F;lM49mIvRj~g!FUgO{726TJ(nD0#a*k@KDyEk+|=;FHi6EMdHD586<C}j5
> wX%
> >
> zz=vgCB>5ttTiYM1kvAIA`v=^YzWeJ(#~@{+1jqsU+hz*;Tou{T&C(J;s;<kcj4q1@
> >
> zy7CM01uE(1={riSJ|;IaWdrCDEZ;0?4ly{mN38y#&(RcU88Z9L!&P7;sNuV`Sc_PP
> >
> z5bQXroyB2&rvIT3VUGSSK(i}@#+05}`MMH|5C6d?s7CLM1BL#`fI~ch#}Q298}0
> gs
> >
> zDdH)V%Kl2OUu2LRL5kp@K=nzyyjkZH6v5+c5f6vE`WAD1Z+MTSB`^B0LMvM-
> rJhB%
> > z3#7(Zhr~nQjon-9`4V!?co^SKsnfd`T4-u=)Dr#_X_eC2oWgpZr_27sB6FT}-
> q63k
> > zPBTLqcmk>G0PwmJ^W#xC-
> O5{4sh)oh4iRrit%xnJ{DwQc$57&V`Jz(x1UYQm67AvC
> >
> zvp^ESLpZF9eROJWE|=gL?9R*pkXVH{Q74dgYQ%~j*72f^EpsrXK2X6S+iC6)M=
> ;?!
> > zUa^-
> ~FA~XpwPIPB1sm1Biok#Q4>u4a)Sj%f@rDkG!%Wb)@C&iEYf$ZU2D#*%J?t7L
> >
> zePZN$v@;gl%~~;Asr;aak9h4#KVRJepJGL8nP<jmu>SmJERlM?{&@FR1@5f;#
> DK(~
> >
> zlG!jYkgf(6?>=xsJ_D@Vd^mTpqE#nv*En7u`Y29+r{Ptq+Z?u?+BNgP<g)JIAk)rL
> > zagSCF!cjqyCx>NgC)?)=Q4*<gT~@azi!)Lo>q-
> ^3T9`SOY49BS`8}=Iajk54^6<oD
> > z*w1fD++$^@e$D7^UGJgf-
> rz)o4yhXFA(G2ESv?9D{nOc!k{JEosH_eCaAiqWAE3<D
> > z>w61?egm>^5554QB+EaCB_1LA7iKZ4=hXF6%HuNM54xg~L?`K0d@4p-
> @)*^N(5Ei!
> > z7@+Ss#o%>CJz^!v)qOiM0JaT7eX4_Dgb$-
> P?4iCDOG;rSwt)!$|5|d;6?lDoLuYu~
> > z?j?iN(OdG8$LBBl&x&`(I_5sN4&Es;C`uP-
> wj@j!4#6iMbDW)MruAkHCb1NqxwNM{
> >
> z@bUD|FW%D<mTV%9&muinFztd%DjnniwoeHm<}S~!mnTVjms$n6SWO7p
> b;P_l#tb4g
> >
> z9h=}!k)XI*`h<`4ePbpEvx%}w2I7JHiDm2|Xc8vkx|EjGiy>by&b<x~d8f!wkv32P
> > zE6g$VLK4}BkTMeaP_gEMZ_)6o-I*mh57-
> ^*tCzH+>d*z@3AV|%h%!1NOg+zH>^N55
> >
> zndZA%RmeQn&0f|&dL7<0+QaSTS+lB8G*Th{+|@N^Is4G4$CZP9pX#B18@1
> hE5}(1<
> >
> zY;318=%V^kx5T3>5LYsvd;WLN4d@kuZ&FaTPk9cT6lNXdw$%1hz=PNg+(jm+t
> @BwZ
> >
> zL+pz_mVvehg<RCvlvcv;<W?Enb_==oT`>uWJ2OV>A0yVPCY3pOV})ulPIam(*
> #tag
> > z#{*HK>Ya~%jP{k&#i)>)fH!sv4NFiS{`s_4t)B-*P;RS@Z(;G7zHk!?=T0K^ziXrZ
> > zUY3kuDClG><Fs<h|8&B?JJc`0k)qVt@%D05FM;RfJ{Cbi_dz58y$l>NPztA-
> S)#DE
> > zIt=A%p`D+5lKdwF>G<G1!?{auyoSJig;{3m<kWL)Ph}1BV27+iTFe-
> +OTZJW>x%Vy
> > z;m4A?M)+c0g~Jf!fSmq$ocsW`-
> ^k64xa*HfN`Yx;mDU~=`V9d;%3J@E7w~}!Pz!Q?
> >
> zL88?K3cUb=)VMSp4>97EeC*DUnL@g?gtsHYzV7RtjTxAS{;z>H3r6P1pLutS1c
> WVJ
> > zb+H0B&jVwwptORM&u7~n;h7EfznWaiB~F-L+eYd^tjxO<)#v-
> OhuXF&2LmRT@L_3c
> >
> zPj5rpLmZR?wWu4V`GAmt7^E<K^}`g{YUwv`Uk8%pcz2TEF)67p{^$kB7_5knoq
> w?L
> >
> zeXGQ4z;UA6g`eit0&<uxZzJsTQZ3ZEE+?VWp#=xOYwbMNV`7;j*VXG8$vRw-
> G<~n&
> >
> zIQ{)n?35@%(NbkTE#1JhT{VVz_|d(y8#%g(WS}qUOE|RdKI&k8x?Z}MQxGniU
> C{22
> > zX-
> I=gmowNQpLB#ygiO!yd>n74F?PBZbXHxCGhtc3*2`@V(6~cZ*4<!m&g`;Kw4d
> D%
> > z<YEj;4*V+0;|M-
> rrQW;e&dE?^k5LT>#68x!tTXa8gY1^~)(Sm5wQT6|$UMsbAes#~
> > zqZrF<mFWvzkmFGC{3-
> LOb(Ih3wFV83{7iTAg=IpUFc#~_hVm3=3tn07na6kn?dG1&
> > z^^|5kQSr|rezHIRAXcF-
> BS+{T?ay3zO8q8+F>k>U_<IEEcY%rb10kcrU&)b<Lr9v;
> > ziH;qvJqf^A*l$Tbi<Y*bSfvIkUv3NAWZRl_jBzeJqfqM9p}N};r}tKC*8aR?E)hIA
> > z+R}UgjZYh;q7$!&%*9ikjK7uIsIA!;uFzcLu(q}?ezCf(q*d%jWm=%a4!Y}N{;{n+
> >
> z`%vwt%ljnaER)E0o&0pqf0*pj%Fw$M8C6TWzQ77dQVW@NPBizFv?7hfmMd
> ppY;|*f
> > zdVc@~A9~wr5$E1you*)8n4i?F--
> }{8m50E4mwC~;%j6|j6&yjC{Y%+Q_m=K?l&wBh
> >
> zSI%Y1q?=~m^Ko}>d_;BBGI<581w|N$#%R1bQ4=3rhget*I<Aw9{3TLt(2?{8%o
> wnE
> >
> zb+TqV(p`0JZ5RFk9l<P#O5*Hk8kDZ$h0DidSKg)U#VTML==_g1oB{DU2@U(r54
> +~m
> >
> ztd9}HTe*6VE|AINMm@c4XKX>Ef>z3q_B(2i4xIx?*cG9nTwIpHxFqv+&;F7v!!
> RZ>
> > z2$)#DvCaNsc3BR8?<dl&g?J<}ij%59Z-
> WU~Py7m*zW(Oj%ZaSo<(l&sCAH?+B&MMf
> >
> z?ymnv&w?m|Kj)2E)B8$(XjTD8Agzv==f@O@_3mdSTvH)1RhwJT8no`Z4rhH)|
> 2aiA
> >
> zWZy*Wbbc+_=$^$<$Au><yzM<@UOgQAYrhOyN8Mja?IvoxXJOL+?&2=qqF
> 8~=75zos
> > z<Hhu$n)=q!=}R#aGs|ShXWawSuZ2c^vqc4Y?hd>T8*pKrE=RR!eAja--^g-
> QOrn%{
> >
> zaxauQ^(PUXSRbR@S;SQDJM^?xwLf&ydET5h*jBy(y<i464Y91r5Z&6stdQI?D$
> Wvx
> > zHz{q5K1*57NBbKmxcCBi{EvCHGS8$_Y9{G?lQe`U&Y;_?NZoojm+4-
> QLcYX=3PQ5^
> >
> zc<0;YQ@6NkBm_m}rKNT#%Ey0V8oWGsD>p^`_^2qz9LLzMxzO#+vcjNME(Q
> AJ(0a~#
> >
> zkP*vI*;CV#&yW4er?y~cR%^*H69v1B2S}4L!XWtID*`(!^^Jmzh|jWvCxp=>?6
> DO*
> > z5S9v5&xVJgI1o4Ck|%tb(l5@E)x0iU-
> U82oYM>ZQF?N2%E?Wf;q$rh+83ThDN#0-*
> > z`8m8qy(o3QuX@2Qin7Ls-
> *V^6^;52SzBwIH<$)ftMQ?Jgn^smE^>{H&zvcQCDNuPv
> > z8A&gM+yWoI3+p-
> Kj<L4J2>RJ%+a7bEng~y5RdsNE*7sftxV=esQ1!sw4d(==jqmRd
> >
> z!#W}nhX7W1B51;0`&^a0G+&&CTNl9u+sS?~H{w>USBcD<f={rePY{WYH$Dki
> No!Ys
> >
> zBRD0vRJfswbn+&cJz9Qw=cin?OpcKVMGNMFAfM&O8L8!vm6eq*2sI%=JK<
> S(B7X}h
> > zVR;Et%eD@V5-
> g(*0@b7r^fZ>O9al$Q;v?y$%pjfj3V4qwfwQ&9tUetOZytiF2~3#N
> > zMhB7&uM=e$=l)X9NIVfawxls{z7llFuIqs`9}nNgTK`0_EUpnvY=Is>`x^s!qrtZx
> > z-w}-X7P!UBG<Rx7THbo2$2HV1iXI9Wk+>?zlTG0_*AaDsn}-
> 8k0{FELICbyZM7wlN
> > zHgWxV%B~vg3Kg%{-@*F@zI^eKA{-
> JV+L{VqEn?WINlMzaPP}6rzQBIHhBOktbiKo8
> > z-
> ^T=&;KD<FSc4^Kh)OJ)oc5Mmn1;QHQ7w!7Jv2QERPn1{?+J~RJH!l!g<QqGKVh
> w$
> >
> z+RL<ZHbfnZ;b!ur$i@I&V}XOd?u|iZ6vt+nI&b27ME>1up1Tr*61ghqa5=6m=6t
> z=
> > zivdwgYOLA=A_u8nkGWY;Gr*o$zaim$FrQ#{8)}~GHHLSGkMp@6#K(-
> dcR2oeMux8;
> >
> z8#BRnAIL24;hZUVX5|*DVb5}En&DxMgLqyC;&2Y%r<Q(LDFJwyk;0a`LE>Cp*;
> =YK
> > zjl$=}dcQ-
> TclI$!kmX6JJ_Glv8#q+9X>=HPd?eoIc&{e%%(NGC98ZdSn(NkO0$*tr
> >
> zj1yG4d^}WbkWRE46^~6ITd)!F{XB{eB#wQ$k}pNiz?Oz##q3)}CT&C)goUZgG|
> Ljc
> >
> z`gTD*_OS15M#EuB7&nnf`&X~QFs2obvK{pn&Q4}pE06{_>EO5+OCR;u26_lcY
> 3VqP
> >
> ztvy`MJ|o+EDjaEZ^?!a|@t=z!=z4+VIYT6Scg|&7e+gT1%U%YD9R~j+w~zOK8^
> b4_
> >
> zf*pC~cjuZfQ1lM>6dKV>A)wR_66l|d^)$KH$?goz#BeD}uSZ|so1_T0S`eJ&J1{}
> k
> >
> ztM0nPbV%aUzR5=0YJb@0mFT*G{d3`zG+|`AW3tZo0g|*Z3}E5p{|bL{0o#boC
> 6Q_?
> >
> zJ(u1|o=@wYLw2lnVHnw^E|qj)izg}%5+9SH&oR<t_U}dJG(E?5a@`p5`u26K)xil
> {
> > zcVybwMfeLd`3`u0BhCKnb}Vkp?u$TY_k@-cYoaK>!Ov_lpGNxogd`;-
> zV}=Ffb;y0
> > z9ZLyNP?CoW5I?@cS8JHm?Pnue-
> 5xI;X87CbW}!5bddY^J%4HD$I8uSwf~cRJV9?w%
> >
> zG?boBEIik00OG_nwFt*~unKmgH1Qy{xnWJZY3fEoc?H>u*i#4G@Aaa+&6u9g
> $`2Z9
> >
> z+y{IlIas|V=iMZdaS}_c@R@Ee(G0X)`dtw$cYu|InpLm4=f~mNJXQ5ssHc2%yK
> MQo
> >
> zu9fa8MPV$Kwojk|juDMnawUc7wRN#3#aM14RlQ13n!AW9&Z=8!Lu~&96V$
> #|)V;RX
> >
> zy()ibQIpP$4%A@T)rt@L*v&0q3O?rVgL&LoLxGH9a6`4)r1v&zBD_O{v}6%?@
> Ox5H
> > z(ybnl^bZz3Xm!6(bXg!~#b@1^<xD-
> VQLyD+lkS|z;JLAPyFb5uzH(MgF&C5c1BO{#
> >
> ze^&A<%R{|w5J~BpH_&6EI_V_uh`3EJT6<v7k%+f4FDomlNEW<jn*&GQ{l&cv
> <E={9
> >
> zhH#!cjx>mDSgH{1t|kWBrVxvIidrOx{1T;CPv<L9x$4wK#NlM^V9xn$7>CEyUu
> a{h
> > z1c&pk*C&s-u!f*^mD<d?d91-
> {0H}AU$m@ZA<J_Np{R9(2Nw@SA`kOiwFGD!{71|@f
> > zqyCdPYA>=Yf_ZfXdKIQ7K-
> BxMdz0Pe@#(mGkjYiUG5<mUL14Z`cdF`rT%in$KS=*8
> > zEzngQd0#zadN7iuH;3qUV+H<}R$Zq#W$W5eoD5ndHwjz--
> =+yEpn0V;dyO#f3quY*
> >
> z3?>kn>Vi)>JhEr$6_Gc<o%68q>Dh+hiBX|7E=LA2o>ZNDE#~&;jOauQ3BSycM
> Nn#x
> >
> zT*EfyUfFujUlP@;#^Dqw{UC*}*;4vW;(ba}Hf4@ATiCi!eqjl7>NDX+N(i!&otS7)
> > z^NNrXGDkM=us)*52#FZ<&b^mg``(Q`vcE&I*oIXp!||tb-o=z*{Caxp-
> >DBbJFmh~
> >
> zC&kb79A!d^^#HX$G5^M4i8;6`x+AAAkVEK|H=vNM>Ib*E38cr3SZw;t>h<RsE
> c359
> > z=o42)r#pYdfcU)y<kuzan$Ad2K%j(N<G}-<)<|628d+rLJIM{R3ka1-
> bd#|(RxFrP
> >
> z7oC{H#>Kr9jMo)`=ty)(Ue<Yy`zw^}W_a^_6)Wud&eNB^oL}b9Ez}$vZ7hj8>^4
> 2R
> >
> z8HKN2{FrjbtM2HXS;J%m0IxgH(;$(SZ8|B<m`>{W18=33pp;{u&hhqc8+p2UTR-
> }t
> > zaL0S5=U6RTs><s)nH9cv>(LtVI87-%xlC$S>0I_(e`>ip2AJ}rD7B<pI+;&*w}Iqc
> > zUDk8$a~-gZ(&cF6^1b)~6WMFJz*q^C>M8-7E-
> c!f2kMR<>)RwV=hmWjbJxmBOGSp>
> > z=zoS%q90`C_3r-1I|(vxy$L|<-
> ~Y7EfYmHdgT5<*ljzmFfRWBdcOcpKr@m}C53#E3
> > zez?fWI!-qRxJhVp*vt8x0_kqK2VAflQ)7I0V$gwR7F-uEorX*~30!R-Ic!Il5+a%o
> > z^tr8{#p0PHZFCUv1V}^OcI%aFIh@A%Q*+t$VQGcZzAm-
> eR5re6n!d6@_6hyx(I78k
> > zK;UiB0LRe@#QoRvPw2NW&OBNm`+FiZp<m-
> wWe6|P1iF^JJFS9F<Cn>F4afYWssf9!
> > zN2zMr)_yOt7`nX)8)P8--
> tmUX{?jlKrsl3vS8tX&yD1HpSH9o8odxl=QN?(iDZ9ZQ
> >
> zyO&QomwWOpf3PiC4H{QtlXOqFMiCRG(tTpdY(fV#4g*)T?wT#8n^=0^e2C<P
> -%+f<
> > zJ-6^iFrz@vQpI+-LxmGl#el{p*vzh9<C;m36H(-
> zUL5ct(LASN#vjIQSj<E%G5&G`
> >
> zoq1c%NFuDMDfg~=M#_+D_9LX1kR#*a072xSHz!4s<@gk*1vS)BhD8!rlp1PC
> dj+el
> > zEkxc;8(2Oj-
> Ah8RUUz>+$y*=CEnVHJ^+u6etFX((dn#Glui6(pPU@H*0yxMe{G%>t
> > zFZe1N(-
> Z;#N@dG(KLJ|u;*VuZ&D=A2hOrzEt&(5XNVC&{{)UH?&$cVV@zp@%Il^r=
> > zz60g?JX+m9?|5%jbW4yUa81IDoH^Fw31Y}7nBLXh-
> P(9ByC7p(0M!&woUWlg6d?0S
> > zZ!o>QVuB%Dbd=tj&-
> _T`OyKD!hYZX!DRC1EA`2E})lK@`i|XOa8R+Uak#d`<%c>}u
> >
> zluRXVCM|is^Bl(kxm>BHgZ#O`F<1qmn>_&``@91Pc~zrjb~SK9UlUSR%6xtXml
> h+5
> >
> ziyK;;^&8H9c5Oz0a5WBF=7y;g*vNQdHa{xg=6uy0{{G|gQ*aT@Dc_O;%HPC?V
> bfpO
> > zZ>10BP`pt4JBHrFwawsI8M|4qZy@X~$%w$6$8j1fcZ-#aigr3BUZ}&W-
> !~C&zci|?
> >
> z%tkT(e5v)Z+lp_l*@|>YJs>6Nl*C5TuV>w5n61JO3HFlGoG?|IQE7s9J#@W<DT
> h?j
> >
> zvWOgvU8>uYmO*yde#hIZ_H<a}<5~BNZEmq$l{CP!b>;mtIcX68LqhJtmB2LQ4
> 8K^U
> >
> z=o;?GIQang%^L1x!n!p}S>PV$WL^gqazvSc{BG6r)kaWWEZLT13sWjnZRrJgu)+
> 9a
> > zdd~d6ooc=sHa<y|-
> u7tmYE(4yQKc9fQ?evr=diw`^|PrhHW{N)C3f}(IQ`W>IM-Wn
> > z9YL6MHz1*R`Ebg>i(85{!WP-
> zs6w5xDv+y~l^pg({47V8Y_>(}r=7tMSTDm5a?M$<
> > z+Y;_nb+@OJmAkU51rffCLI+;|jKNav7|4vzNDvHE^4)S-!6ziv6r8a3`J%{VBg~<?
> >
> zTiOtjAgnRkSwGVn{aCU1iJ|6eQ(#Xo1BCKo%jdg6zLrIblf3d`p2ri)+OxS5>W=qk
> > zjcnO0FC<-
> zz3dhk!F)B%mm+28yOO0E(6lB<Z_v%G%h<#5@uPShICItsx1MeaPc8Q1
> > z>8<aHYtJ``M!kq=@76^J=2^>e*+-
> ?i^0Jse3<~4Ercs`NIK?TzdG(`KwPL3%B>uNS
> > z9O!gMa<;zpIPCD!-
> j&r`_fN+xQ%22+BKS(0*a;%S+Z27$!zP|KUhe%$fhP7@vb-KY
> >
> zbj`P6wA+`MfunXW6;QNEU#;RNm6RLlt%qc5>ee@b_U)Zgrx|5J3Y{WLszXe@
> ){}ye
> >
> zL4|6`_XS=s<XC&V9;nSmeYO^>w12@SBZ8G9E>&n_+D5Q*Aw}2!M8=_Po7H
> X$b5|#j
> > zIW@eDS!G*#FZ_aSzM6Whi+MFQk8+Nk!eqN5C7Ee-
> d!ko~1?$I;0XQ0Lcy}V_TM9HH
> > zb4vOyC5CU3^%O80(UfpbF<%Kpy?ccz$FJ{i&5i95D5M-
> xe{E>sl9(>CA<_JNmMixd
> > zgZ09rG|8v<#R2^cb_Q9&O?0>H@|fZ>^&^g`yP-
> t~(*7E<kqy26Hww<ma171sv!t#Q
> > z{xDU1oVX)9MCJ5(<MNNHoeHjd$F+_>Oh47d$X-
> XGl*%Q0ElH2aXP)|ASi9~aI8)Vn
> >
> zNXI}^yA`QVd*Ix<6~QEJ!$pU`andLlnaOpQSAd(Z0|7YYiRNjps7o$I&tr#X;&99s
> > zoTGKSc8dgS8e43P_6{Lv#+DrXczsc!YYh_{R($sR@E6L}dAWF;-
> *c4|rL<x*=v#r8
> >
> zZi@JMomr2LTMFQSGYSkEOyY~nA?n37ji!HozhEPf@azC{=YTSKqRfEG=)Ue<^
> $AaI
> >
> zrVq#GP<a7^7;E)ueR*#s6I~&uvfxadJe5?X=p4CrR3L|SV4q7mN>wAdV?gUo`
> M-hX
> >
> z+4vKEX5<>%BK7vI13ip2HVXJPg!6CZNd4p<40*`<L{Fe!DdLj;kpSmJR(!_&*w<x
> B
> >
> zf;{O=*hVxSA<QAkV{U<Z)@fL#G_TiZJ)5TDymS9I?%C9At5B8Q>!r!WmW~H+
> xkdv8
> >
> zYtFMXdWlTm4a`t<&@F5lJ~xH`({Z^~E*C3@(FyZ3Ih)9c<~F5~h>1F55^h`n)ku
> HZ
> > zEo}_x0p>=EYVv<GA<ssV`fSkq{1icIR}8tvFM}jLakcB~f(}mE-`l-(O?!6yG1jVm
> > z>>-{a--
> W&ghu!f;H9a+yEq=Dij1l1<ZzX|5ozNr*vUMF!b>{snZleF@7?<A!ld5Hv
> > znAko2I^ryw^Y;QmX^s|53Z`4idEUG81YOG45t)g-
> dTo#iWkSVwCW1XNNk>DTgaD;g
> >
> zD`bem(%+|V42`{asZ@whK8N=4f71|3@_3n<_Tw$}g1*boZ@N1s$8=_TxMaF
> WS_L$5
> > zG=<aTddXG|=%WRgaapwPY?g$1s?>a~wZEY%8?utBrjGUTk-
> &zLAxDgQMl#h~l)AM;
> > z-
> %Sl<J;0(+WC*NcPRA{XjgocQ`j)HrQ>j!?gRjIQPl}70WP{Ms;*9D=pFnC4N{jSK
> > zkq<%}cHY=lvg^SjCEK4k)PnAz0;TMOm-
> $hEIpj?<LiYD}ov|o=<+m77@%`dhAH~ua
> >
> zfhE|kx1v<ax*q1$6D+F8h?=nff%k|?Sbg7$Q1l(&v9r&VV$IF5f(7C5&Zykam~is
> 5
> >
> zMBQ=+^nX4DpIxQToyCObl?wfDX#BpYz_0uKxn7PqvqTfhxrsU@w4FWnw%
> Nf}$y^xf
> >
> z%lnq&wtt!x9WIPgV;Nr+&^{sM#l4ey7r#^p*V>Vf6!%ZtC2I$*^ypz}*1z`(Xyf|
> y
> > z@#FSJLX_=`0$h$|M*-arFk=3l?B85Q7bn!cY=W_`1%DO!AQ~aUBOH~qk-
> N;TTN~tt
> > zCG>(XDrX})>@iM86gSa1TWbfBP`pwh9j+~v|0Z`Acg()tIXjNil%xQ^EfVI|iYg-
> o
> > zQ-15yS^!}n-
> @U|TXVfUMwRE?zl*_eVy@5+O#6oE<J{{Wu4sRUF!p`&$=iY#)MY69Y
> > ztMK2DgyDFjD;8tk{8P$qR0N)^qvDQl8bq~A-
> Rih9xWf6KdR0%$1u!qOps1C2Q#ANP
> >
> z*c0W<LpR^Gs2e2jKWs?euPsw=NW#76A=KYY&Z_P0@ZYdHFYc<RU>p^%_u
> !Dqgb3Ca
> > zwZ6y<4qiE1inH!5)^X{6;`c*!EVGK_+!UWAPC-1Y#y8n`?mD$bR92G86-
> gbBvpzXR
> >
> z=4cOJ8e)q6Z^<f#D4``8(}mpdx$lWA>~rSRcCH4P;nLm}!0wn1v#a?wk&_s<Nf}
> 5T
> > z>&z`g+U+&wQCJYn<=7X%4srCIlNl<*F97oUOj-
> hIrr3a)n*V>r6m=eJo=M3#L3_&Y
> >
> zi&|44<0`bj6vbFuZHvV5v*Tl}Y6wYL(zvj+oMpUJFa7P(Za0pA*;4gpG2kiPYH1E7
> > z%kHS*0B_EQwIl?iLRNt?r?UFu*P{!%ZuQJ3*bEo%s$XUu_2Uby>k4)`{|H5-
> 9)^=n
> >
> zbt8pAG%9K%504kW`h8@H+=5afvn;8#!)+&){MNODhwu^{o$g^olPf`adTE;Fz
> ZIJm
> > z{P+_kTH_9?=_3<E<ohCLHs2fSgIcHw89qgIJr^A52Udf+xt-
> `znzlp+K6)3`*U@k9
> >
> z<SwAk@iQjbCRH+=6Us>PNi<GQl!%MQ`**+cXHx{ma;^%~cZ#+WSAA9#C5s
> zg5f7(M
> > zld;FU)~fe8wj)+V+gAR{O_5W_BRp46;r@B7saVATOcImYtB8V(ux>)*FFpKG-
> kUG*
> >
> zbj?;tk4&h8ks=aI#b&BATBEIZubxaINavi$G|Yo9Uu&v;^UHwU%+51S&)n6q1n
> oOj
> > zMPo?OrRqOZ$l`tiC|oNf%}?6Rq!z@)U^bi6l)-
> 2TC_XY^XyU+7`Q)it$=yI_HeO$|
> > zusUqBuynNX;DC4#>e%{hj6oNs@~R}7@6#vT@|duD;fh}-
> n<&rw6V{rKB|$OgGoBpL
> > zIT~w+S|^qu1tXgO2F<^h>+l@UUB2Y7FJg`|raEdxf-
> ;e_A#;c07yl@emICdlfx6?S
> > zXwrIe)tA^McA>|jZCSZ$>Rz^yadM4MxQP~atWXTJ35o0D|1H)~soVgEEW9-
> WPr4Do
> > zbv#2m9cmSieCuoioKY&r`!OHR6Fb>(2{O9}bQ3;0RZ3ou6B~&o9L0x-
> OHJh=>^%$z
> >
> zr(v~WRH@LUkjY(^m{+xUr~eBGBUc@%3I^@A0J{#A3ap4N$I=&#UXpv7K#Rf
> R=j_i)
> > zvlD1Rp9-K-yt~~EQly0^ELAHo*pJNaq%7IXKmO^Ca`NmP$o$oBj+)}oy-pwb-
> >N#*
> >
> zYTk}>cvf(Eio_RtLRn1vCX6aS{o@uYfKX%$8`FtN4l~F3jd8G1&21(_*`VLSbHiO_
> > zLs>gSMg&%IxgXVsk+G<1aLQyI;+-
> (x_K(boa<pRlH~I+n>pOd*Jc8fmX)TMgV%p4d
> >
> z(US%&$&uu(VUmwX9e?UB>(!SQ#5p{6hzMH=zo<T(L@dO9CAPQEC%*7ft<a
> O?%3UXP
> > zmxkemLOe-bD%O81OOdPv56yFNIJswr)-
> r?Bn#M{;G<u}Jqt)T)Hi{a*zyrVcL$tRn
> > zU(grHG-+H(%V#QFN~Lz1QQkoS96gsvl;%6W!=ezfTVw6G&ENk-
> bjd3)EC1i~W5H`Q
> >
> zGcOA(cO<1}5GkNlakQ{fg~WZMH%T=`CyEAbOg~Fm(xiAm)|Q7QrekwV`Ze=)
> @EPJJ
> > z!!F00iIqj9<FImx<-
> TCZG5;+vtU1X+rNJQh(Z*U&T5L;8_ToaxQw!Y(UdWtVDBwuZ
> > zA@6GBn_*`<fZu;fKyYcdsVz-
> LjU3lLmY?1#n};Vy#On}i^zzYZ0>&UQ@PEmHVrbJP
> >
> zQe9b%lCpy*p)_BAzok`~)E?YU!gC4r#oRefnWc4$aY)4Ljf5Ik(p7%;yAoq*at@S
> D
> >
> z__aa+baa$;DP~4J#*rf~6|%Qe3w!b3Z)elu=zX%FrfX5poZT~l_GImpz@>2;>%
> o&q
> > zxj*LqEY-ZnACrceN-
> ~V`x=vCl`91axJ2^za`yQzUWnpBgooE3ASOi!r*r>A?1M573
> > zN&n5k9DfdGDn-n*utQW4V{X-
> IYdoR6Nzvw4=n$n+fAy4rM^z$ODY+t%uZ}HIPMq2Z
> > zzW}2RRYOynm&x|upI7lGNnweu4`hzNF9^F|R9;Q~Z`4-
> Y(zEt0m3<zZQzZOBUzlhe
> >
> z?)<(!sWY%0>+oTjC?=ftlv03%n1AAK_FdvVtXf4rMX8Ba9I0>2z9HNZD9nT8rR~i!
> >
> zhxD)y*ONxd(B~Mio(S3g8(A@`9rH`w&c`gw@Rc*$2KJUJw3^vod+rkYJMb)L(v
> =5E
> >
> zZ7J*B=C4k&@mP%m=~*ruDFkvyaA0ER;jAzq)TtQXc8p#vIhuSM^7h}%`Zj$*2
> U3cy
> > zJ+BRLW^=?5@2A+9kwqEZDD*q$6{{6SAC$$*qf(QCPK-
> }p4>2#(NT7_EYJdblL%@Pb
> >
> zEgmO;uvUpvD#_kw3=)o5;s3Vo`^_Qfu^j1XKlV+05mA}suMuqZkrsVD!Q!m*
> WT~0Y
> >
> zO%ysu!_Wfw9c(PPtxsz6!b<Vm^pAM4yk7`docZ(Gq1+*DnHOclVeQ}{7&Rfk
> &f3EE
> >
> z@15nNNgk<;B7RRfUwdOhx%oUbKb2tgs{dP+9MYPLN!0C$>lDnK?NT<$c)Dt<
> {8Z-8
> > zek(ksJ4c?ERGlm>9F-HWhC9#UHBWNsjs;8Q&9;AoDt2j42n`B-
> jr~cF^8<VGoEm16
> >
> z9`Ax<c_$|mYgmk{G5&L@^NgXo>K;Ec>9;NqiVd=&MW(yDM}#3a645pu_^fD
> 4LVb1o
> >
> z3NA_i5P8ryCA7db0rh{6i;XAsM^tt9XFlmOEYgwQO$!=u)7Z4@X6og)oSdUae
> @x0z
> >
> z5KK~e@G`%hb~*L$l)N^ixbOr<_N%m;O;C8u(=lM^$f6eHD=y7u?J%9g%uDun
> n~4&d
> >
> zu3N8P*3{*xXa3QpfR@CHrD3?*m1HX7wyFL&OxLYsueg50v#~tdw^sl~>moA
> uG$}Tz
> > z#IEmCFn7df^>D7-H--ADnz)!4ImOJ-
> Gi2|AgzNv_G0P0ow|yfN@qVhn^L^d+@=?WW
> > zmAH(FJOd6vD3{|N#S5xK_9owlg+7%xDe}$UhaLBF*oZr>7RlF4I-
> )fwRt3qD8qt({
> > z<P<KF=}PJ1#r#`jS-C-
> BLurm(iegM((pQP<>WUPp#7DNn@Z43$EZ%H0`$R6^s|a(X
> > zlw{~&GB5Lc8s=uO&^TGv0J+SVmAik|XS^mt0kB-
> $@AJqDd(YoB@ZYfK6vP54O=^o2
> >
> z6PdpGrmMi@5~S3;K#!R`a(d%L){l+SAG_9Ill>ge_D%SXdTxul<rGs{PGLbo*ua
> Ng
> > zj7-W>ZIBF}i5K6kPkSNUM4m7I?Fw!I6i-
> tbWL%ohD+Ci5t6O&DIkU|??ctA=h~(;P
> > zV+-
> mX(dzW5hXf;&^sICs^~c10!MG&Fr{^&cDSI!Rqlu*wn3RiGvP120c4^ojUjDmu
> >
> z6}$5tlC83L(lz#5@YwMZ*Xx%2*qezt1~rrT)Y)!5Ci)Oc@A0j%@ZRIFp<amLQnF
> {3
> > zwPHdUsL_Emi-
> |sooN3M0iJ3Tm+O~_sUU1w<e3tm{jR?h0taf|$r2X7ZA4_fIKtxtn
> > zbrc)1<0dX~X#twYtTp`&I-
> K)Da>wNqCz?Afi2)fnw63HkT`4aFOl(*>RG(Ww1UuZn
> >
> zLnts|%Muf09`oNBq?MtCi~rrWS7%|HsA7H=ZRgEF2M83}Vtrqy%0F$t#uHSG5
> +#Xc
> > zcWv?`wo)a$jOSP`u$)dQF@V7mPEM*$S@M!!j|+dTpUbQMFa!1znyw?%-
> xVeiqO1Hf
> >
> z$va6h%q6r>fx6QR<>Y+bGN8%s)}YRyAu3&v#ihWRMPb?<l|*g*>7irxHrA}Fc
> U<cW
> >
> zrc9XLrdI~)y6T_RtvmX9;<zJjsUOkX{LAh`{oQKtF8GhnUH{=)1S^4zvef=b%F>c-
> > zJDKs^v)a7UWm}XqHC7z%+z)+u4)j6X96h<ZM_g7Jo+(X3(o*pC$6=+6T?-
> up`F97_
> >
> zo+0Z?@mXMsB>DjszoKQp;3><X5&VAAERSE(C^<r%UmK1j8vz>Z|3}kR2Q>A
> )ePVQj
> >
> z(j5Z?q(^s1gP;=9DJ3Y~UD6$+L>;22lnO|fbc=v=BhpC6d#>N#`>%6jyZ7AZJm>j
> T
> > z4)s@IGNTe?4-@J{iz-J0sXQl-
> t%YTPY2a*NG3H5u4hLOwu;LksnSGLopxEym4(PU}
> >
> zuH?IzIQVy6Xt2}fD_YlToF%Kd=m@4tHn(*2G{?$i<XR#m`jsDHe~7=xxhvGOA}
> &jB
> >
> zTR(a9HZF}RoYohePw+nRQ88EtpS3fb{?*)A_OK%_LaBMN#ZqQ+3iHWlXNF>F
> 9XPvK
> >
> z;rHKbd%7(+lZD{k8V&y3=$H^UaIlLK({{+)dqV0*LL;2BG$Cf@?B6cZu3YSx73ckN
> > zH}9#C6|qJ(-
> ~SFy?946+aAa3*&Azq^XmCrx?qeHDVcVdsmd+^*9+BYn9ijX7;Xb5c
> > zmKeJ0NR1rj%NFJgA>QB^aI)cz7h-
> lOnIU!~3U4}<`5{!6`0?Mx?dEo&by<S#lQyxC
> > z(-
> KPKDa)(}ain2Q`v*U1YavZeP=u4+t<5IyuN_mah$9j@`H`&+E6m6x3+b+9*2Lr|
> >
> zlDuhfwNB#t0gk+Lf@ThqGq3+^Kw?Q1dbge7`r|+91^qUhmTnm#XI8@J4NcU
> Sn)edp
> >
> zh_Z0`!4XH`%5vH|&;GYvo2_9%c$*5**c;S$a0s;|)X3@zq?n`aXEUaSo%Q_wuh
> 94r
> >
> z@>}`jOdthbQuJWXs!`?*9ygKqVACy+z$FFT^?5zo+ztAb9TG0IPsiM+nP9?6qG
> kQ;
> >
> zrZ8h#Uq@3nR<?*Lif|ejBBwnVE+pPv`x0jGzb;>Jjh3P`oH{RV1tYz+Nb3%py7}Z
> S
> > z50i$04(#`7>XA&+lsZDtF>fiO=&5jEqFZA4{l&;oIX*9bF&X=kcDyE$ex|9XU;?B!
> > zLKgK@^uHSZLNEF1>n3-
> )R$m&0eqm{zZExO;i0Fu8So)&JS+p9pMjqEJ8)+x~wPT*O
> >
> z|D<vkw!$4U9b9rlfyFniEG+@xoP+B`It*(0T`u}tDQ^^zW>}^Fip?>GIZDk6RgnL?
> >
> zB0akvuCxB*GwT`4EQ7G3&^!OU2Wct3D`Ev!tZx%i**Pz2o~%A7N)tG{8_7hB>
> 4f|!
> > zK$byky=2^HIw%rk$yyQka#QZVgJ~s!xZu)*!gD{J8|8!WuyrGfZF-
> f1_RXCi@Ib*0
> > z#dee-JN%6{XC4>2&2k?+M<_i&3s$`8&Dy4$@+Qn-
> fDferp0V!X9B0;Fs85@B48XtM
> >
> z|Mc&^35aJhII%vg!=EQrC)q~$8BauWdM&_wYvaf(e`#qv)^&N2Gbl_JYkR1fH
> SiVn
> > zP5ZAFYbCS1g7-
> `&ic_myOH<3%QA;fKjl#qL7OMB(w~ft+)F%8}+ovu5K7M>b9GuEt
> >
> zGuqBqw62~MWTgn*)*?O@7DY5Z&9htbp<^4?ffK?XlIQr^BB6roB|_GM3(A4
> NVpdll
> > z)Yfr=!KB!~$Cq97BoC1%{)4Ox)9df+Lb<IV4t=6a-
> 3`@t)z}?8R=?u@$Rw&yc>*^x
> >
> zmSF5Nq0N`BW?JjU^wi0YRdbnVOb8U%=3HzrtYj80E%`T?VJ&;&u(WzCxyzI4v{
> %xn
> > z$xp|a>YpJ*)?#9}#GXxInrfOMTAACKllxR89`wy0#ZrUPhuF!fgq(YGlSIji&pSj0
> > zI!u?7!#B4yQCX-K&Ho)t)zs9);D<}<;B#NVX4Q1SgHVQF`d2}tUUH0`-
> ^FvPyUB5B
> >
> zys+iAopO%aBhk2(&{2wB1wk|p&1Gi_kHmZU&C5_%H)4`2`mdEC^M70RMm
> 5jhv7qJ6
> >
> zU25Oaq<t*#(Y+6Z@7pv_9~GCqRcGg{G2;+kCLg;8mlod8Q_59$rf^m$J?g<kPs
> G&n
> >
> zWcqClI;4K71`$dm7e@!~u|BvM<^K+*vBUCPi2B4!%R7T&${I>Ecy!c~w6WvSc
> X7Yw
> > zZRiWNDSv2G3*L~9Ds2mZuN7)<$G|lR{mf%mFoox_;cErFTJ=B61yeI6rjDA*-
> s7b^
> >
> zWM)A(i}fjK#p$Rr?Pkbnw3;6%h}w;xB2Sxdq(()0l}pp;w5V}jtZ=p~|0Jjqc(NFm
> > zjPV8@p`AbYzMtKX1@uRq`>1bPMaW>#j<(V=YcA7J7)xa^-qHLw`x1;9`{AR-
> qjhhO
> >
> zh=mYQDu?tBu)s@I!W(;q(uV8Ukch;MFOeEN9{UdOFI>;<9$gr3N>FDP>(t6X0)
> |CS
> > z^GD&-H%jsm7i~c(IDGo_-
> ?&4WNN0jkXn*Ntx_2ra;jH^dLoxDHI{ofaq<Es?`_*yw
> > zz6U*?uQut%OesnaU>(TZJ4odNCD7XACj>h-
> %XTOuIK%jeRlC4YOaKdYsipAm+WrxJ
> >
> z9kwhVoOqH+dJ~<k?ZrkW75*pwt2R<wH@AC`w2VMCSu9uJid|{l$3Tu^6)S%
> _emtz|
> >
> zfl2M?e&hnyoQdt0CHCbj$CNlr9J8S(zj&bnQ>ocq+mf?owadeDO;w+o08Y7alV
> qN6
> >
> zKv&WtG7{<YLd|u<GAer%9J>jgbbjj?|E|22L?~~N+yX*%DRP69w3~B`=y<f3w
> Q9VH
> >
> zsze^VfExVRko!ZCuL3P7_$d|t#Nud$<c!N2{7IOG6EdpPG|xtUO(Lza|KRrf39T
> dR
> > zV~2Nf4nuzMdh^)v$Wi4gk-bshX_1MJm-
> z5jm=aFjj$na3>$mvN|33HD3iFuOn0va3
> >
> z?F+M)PuZ<~T2KEz9kW2`YRBY7;#vlci;P5jBsiwV^%pp3mm<frgg<jzf?m{)12%{
> k
> >
> zJ6fM9TGgwJSXf38Xj3QkA)%*M4gIa?n@>_@$ed4jl{{)V>l|qmLM+}f6k48aEgi
> c;
> > zO)ScHYd^W4>p1IZF-
> rKAZjr4z!Gy<44AG*Ch@go#8IKW<rZ)KR(pE%^W0AYq9Inuw
> >
> zphnJh`{fUY&)t$Vw*xTv_U&^t{4MY*opG~dZA#iloKXjGmM=J*yZLW@#45Sp
> q~p!H
> >
> zin}`4yt_!kwfv9*U~jyeyI@zSFd&at;40)v&e=%l$Qzx8+GTQT#^cxC2D*1T3iaB
> R
> >
> z4bgQbq9!T!B#LkE>Y`Kwm0}A*Ik8V@5*T}yS{G7@DU<WK9N0XRV%2b;fZcH
> @xAy1o
> > ze&p!AUY&E~p5@~1Fj36$KJ<-o(Hl-jCP;-
> FZM15GitHqRcHq?uj~t|Ecf`RHq)8Bq
> > z$9x{V=na$iBTQ!__vh46!dlsRYdHcBZDgLEcb-
> d5Kj>373=4;|gla3^9<xGWqY!YN
> >
> zA5#xV)i~ZNh~aBsC5erA6~9w=HBv!4VZF?IvagL6;XRl^Tp_XQ=iRhPZ$JT+k!mF
> ^
> >
> z7yH{Qq&Yes$$nFjc%sfYsbyhbvC*s6Pz&ZAt;Fa;JI0yX2RKl3TSB<X+)(~m<gdV
> e
> > z9LY8j4mP&sA)tW#FgQ3k2N7q0dTBAF<0tTu^90^VMn##KpLzNC5^<zN-
> zaH)%6TeU
> > zDai3Q)sDP}fd8!F4@GgYGt3O#w-
> T9CSSZ^!@!jH!4x+;R`6srf@8?xsUwS9#T=&!#
> > zJ0Gu_jYYss79R?y?(n2h{T}ceksI~=P*&;)`lj`o{{H?bK<B&pHPLJTSm`nAPg3XJ
> >
> zrrke7Kd0wy3<PI895*@PPP3oH$e73C91kMqvC#Pu=`c>*nh@9XksXzg$sl|5A
> >JLS
> >
> zRA=0?q3T5MW|OBO*~~oXN&MPwIeV%tfjKQr(xPc}^^9a_9DPgJ6kQcec}<^
> B^2@xF
> > zjonUY-
> 5OnX8@qQ@9&Zo*oIE6K*Q;OAdvOpJCj=Lg!gX<1d)>|mYO1xERdo-1(TU>k
> > zitryh*C60Y{-waZ4euj}quCjh+VzAm^NW>q-
> I>Wsn^_=%oN0?9m<2++S;$}<NQ!2w
> > z?D}Sa^U&-
> {Px|cMV!PSR_0=p;%&Y+_rlikWu0uW0+1CR_(CAvyqgYSwMZ2^y@4wr+
> >
> z#Nx(F<7o!&h}`$R8Qj&7Q>QzSOL+m=U3vg8sh$Z%$DD~JW19i)&`WCr$n|TW
> igCND
> >
> zNP=8bA<Jio6snrcxDEJre+mP3Bz^+xZXX~Ht^;OqgTVbhb!_x6%0fFo)a>ayn^9
> Gf
> >
> zeU{=D^;JGNMrlY@SUFI$K%ACYV8gHpm^rdPzq(n7d2Z;5JzG*11GJv6z}7Wn
> M+HRe
> > zJcoENfQt4U^0l~Fiszr9b8A>+4BS)r37Bd>-`;2Q0fu5#mAE=ucuq6+tZcY$M5(7>
> > za!gJk%boF}oX4W+asn8VO#`>Ley=~1BQl5m!jM(CJ468jLhtz*z_Qr{>bL8m!-
> N|-
> > z;QcJ-
> _4@&E)tj#aMw#`6G6D5K_WBL78G)>jwt?Zq<3A3|?TW?McocKEwu~=2Vq6r2
> > zIClid0xe8{07)CD2)!X%#5cfHG6TY1v*zHd89-
> g!hJtN?o_BdRpcbbxsh0DZ+c_Y(
> >
> z&7STr&jQZEj(O1Ehdw~jS=)E_TYmxYyaQ&XPIq~D;{ON+8gt#l3xDr~4(%5!;S^
> X^
> > zyiYVwy?{|`8dw1JAeiIlFI$kcll>H^Y<2)^-+LrH^gE!bHMFS45Hpwp`f@`$-o?qL
> > z$w7S_g;0Kz%2G>oa$=hlYF^y+okepKmAfw>)-
> @2p`Q1mt6FY&K(r;IDDBlIE3o@ew
> >
> zPL>i=tYf8Mh>wmXOpc@T$<OM0jO8sFbKsD3Y`%w=2Q19KnhRJ1mGJeQNij
> %2fn_q4
> > zalAS9-3+MI=HRS=A+q&n-hoZy9(_1X@18oncpaQ{aBX)PC|l~jOdW-
> r13r%jU`>=!
> > z8F9+f^5ITaJ6-`p`UaxS{qIb>fP1dU&5;`uq4h!AX*SP@RHS&|cRY#-
> uaNP1Hw%<b
> >
> zbP`?+*bWEbCXc^9{cG6TR2h8b59ROpqNf1X>Nm)M?crO!u+XmO7biWV%*!
> d{;+cG)
> > zu~BpMeOdB%!2$I-hQT`rC_V~K$h*`}0W0wGp7Wn6z-
> 9KqzX4ywpKgSlL&Lplu#f5K
> >
> zzRMG3aTf8=p`LWq8TjQzRHsXxY5jO>qMsI2($IPU*=!5kyj9<+nxV+Y(xoRyhu
> NBe
> >
> zzGums@UauX+eAt*aPD>XT>?Vp70n>sq#B^_kleT^b6ZsniH<0rrPtqyqS8p%q
> b`1J
> >
> zbEbg9uyVKYNdE*1iJ=>SqJ)I$18@_bVcY=0kl&OwaO`6~VXc2&Nz;|Af?m0&n
> 6h9#
> >
> z_6btJYAkF4$*d0rTr1XO!P95qD*jI*i&C_2t}I}|zt+^$WHU%e<GeJv13~Ap8DW
> Ts
> > z@juu7-
> 1mV;+$_+(H`GiCwDd7?XXU>G={{qS(ix+bo01V<G6)wZKSNA7C=V3#HSpa}
> > z!YM(hltCeOlXusjsp>|;B4BR){r$Z!LmIz2h~ei~@$T|#hWul@wn5M8&p;-
> DANPe-
> > zC~r|J+r4_A2f#uO*TJO&xvJZ<l{%O-
> 5(V6@7)dh5bfgA&cuHync~iJmvB~V*KtV56
> > z4%Obc4bQ}m#H`ZWui1dCf-
> 8Ws)*LOJHy)C3S5sTy4u*hqA#?X8V2d^rzc;iHii2qa
> > zb+C?$3O|3;go-#e@V-4E5^j*z3wEC{cGzFK7l-!-J-@1qmsysywzm6-
> 4`oYb>K>Mz
> > z)@ap^9n#f?gMJ%>C*K;XYgEm~@Lo;amAKOu?sWpx4-
> gIH0R$|yhL0%iyEWP)-dMFq
> > zm$PVSo#$pSP|9f_xhQfK_uhlrT4<<KqknFL-
> g*YKLtRiZRx3P1h$De+)0Slkv%n4;
> >
> zRa)xC`fCZWxDGM0t)dq$A+GY?LdB3ypFg4ezCYA<q+#p4756J_#ZKzScH*PJ(-
> #w5
> > zSQe21-
> iJAerRfg?N^^=ob68%FTL6l8p_{xp%I+Q}hIf8><zl5X5J4wVI`!rGWC+XH
> >
> zo5b!C!M#V0RC);ZbbQwfd}b=YGse&3BXN2$_Dsn9FwNeZ<a7a}{x$+Fpkx}l{=
> -h3
> > z!ESlI5nz`fGJ-G(J8OveGIIsA{EsMVi#-
> u}vKD^mZ|<MkJ@{l^Agb&@Py8154|Ht6
> >
> zBbvguApy)(w`IyKq0}Jslc%GR+w~K9d*;Pn1+fe@+(9D<XCxl8)$5!MOPJr*hp*
> VB
> >
> z#q&8ji;61!#cRzU9N}~9o<S|Sa;dHJQTkX;W83wVc^l>>=|_{#GaLo5TY>FoB2vii
> > zg&bWRK^S3uz=;3Y$HYMj&->(+5fj^<G8gg8?1k!9gVR$C-
> NcZPpT3FT+YGkGFM6L6
> > zA~mqz%J*!_$<3{!WD}+zO~*sXQNMmzrXPiaD9{ved@z5s(MB-
> *5bib>R|Lb3>49;t
> >
> z!|X;!M;}dlrA70+8ro=&c5w&9{jX#qZ8HM7Mm0}Tx28Y8|B3$nBZV8L)250iw@
> ZoU
> > z1o^bK^-
> i9ao{8e)=k<sw(QC*0DdoDt*t@4s64&HozU;VMrsE}411EV+0he?$&e<06
> >
> zK<G429`2z9{O16WXdjzi+uyHsDOf00_RtI<nEpI~7T@>4GCix@{rnin*>PGcp23
> |;
> > zI-
> 8Wx{z#5l18NSG8sz&teBT`?AdHken>MZW9rZoM+m49rENcGhd|`HC_be#>0p
> %hX
> > z-z&;-
> 5<s&qddYF2gd*~cYJDJ@%R;^85Iuk}dkR6mike@_9{c;B{{|Zr@1~BV4@{O2
> >
> zs2{youpi7(Utqglqv#=p(%wSrH5aFxL8*=xSXYeBxE2wQwa2I98zXf1Ki%fivpi(*
> >
> znMw8JERe!DlrvGFg7gVTsbxYDEXVlu4W_Opq4!!ryK{A4Cs^S8b!LT`RCId|JiZaf
> >
> zqwkaBJ`^Cs>4nBiPR#JMb`d)}Gc(Fzatz)u3{@~a1>L<?yWWgv{0)2IH@KR7YDL
> mu
> > zzxUgGH6QGZt@4M=g?bwK$RcpRvrxh4ox&Y4_}6RfBO;2wqt-
> )j9cW`J=^32#Q_0v=
> > zYuS>-
> !$p;4{Mn#)`Nkdb>J^8618%@GP{~f!W_ZG(B_VHb4_`%_)jI8tm5F#XU!4T3
> > z&4!%WZ@0SF0&kU>_-JIt2*jBd85c_|d-
> y)f=XrXsJH|Bd|1>`r_i9OfT)OcMXG%(U
> > z6;SpLK}$lNH+Qlh-cKR-
> YMm$D{M@_fP|E|@zTP^g9H_)@UjcT8DWWywo>&oV-UQQh
> >
> zA@Ty(17h<>)6AuJU=NCdj*TTVU8)8BX4#VqXCo{x6K!98ar)5<wu^qIk@3id0
> U(c{
> > zfIZlR!@-
> s6$Q;u;oDvu|R#=e_P`$a;_^AvRlfxU=7@JAY=6Wt*_l%8e!`*%S{=Ld*
> >
> zR4y+03rLxkWnklU7IirKW4C_mu9mgfuSrWqZg1k&w*6Bvs|udy)Cd<NQoT1e
> <WpJJ
> > z-
> `$_=i<_AV{MM>@G+${A$jcvrDQWr3Ra86;7gUQGMMU{HW{W%x_TA<HDZ
> N;@<uUxT
> > z*o>_2?Z8Jb6|qhL74)2q6GL1D>?>o&N=K7&VdxaU-UNa5cMd$3zd@-
> auQ<`tjRFOs
> >
> z;LOghIQ>vUU|{x?SXlcd1<q>d(!Bc%9n0@sPcq8zG2z!Zl3%6GAblq2A)ybxzP^
> Am
> >
> zlB6bvX~!}NbHJmPnhhkH!K;~u{v;fgL6aH4b|eYs_yV45bcL)!eFA#OEPZUh0Q}
> AG
> >
> zO?B&mWBY{pr&J6Z7|NTelY%a9@hN$`C4WC<?KHcj3a4rwVfFe?06AkR^2aB
> e+D$Sx
> > zjN(RqZ>bYB5w+-
> ;*r#mp=SuRKLceNiM0#CrcR*jjK}3)b>KYA3XIykyV($aJy!m-|
> > z2UiCg{-
> >;S;c%*&kXuqQX|X_oR2jXNn`DO;^<5iMe>3{6knMIF{h^=!3!3wktf7<K
> > zTOHkDcgdOyfsEiOu%WtEi(>#Z-
> ~{Ga!Rgn}K?V}trplh8UCK9m(6W65O*TyM`pYu|
> > z<U??81lPsKmVh(O>xPk~LV415e$Gvs-tY1#0pIXI_k}Q=dO%)2V`KNm`XG-
> KacrZ_
> > zb9^@-
> j}kY`ML<mZYuvcmMc}s7ZkyvZK1J6#9*wA$8x`^dt~B5!voM9bt{+|hG>N9F
> > zXaAN~^rm1C>)26f0mj^J_C)t}o_`d30ZNTB;oGO@e}U-
> w88FH|Vp0NA28vf|sjSi!
> > zyMk|iZ#tmLsEBWX|3RjlkhRatuh)2-`7N}x&Lxi(-zho|+kt-
> fK$0VNHs&Mk>^C1D
> >
> zaEZ2D2o0vRNGwWTLhU)^8Yd@d?Q;fNOEVxEtE2iWc3(F2T}`_M{Nb<fy97Cez
> $GM4
> > zROF{;hFBi-
> eQvR=hWG+Pv9y?DrB6!Rwi~_v=i_Q6aAm&|LQ+n$%F_OPiLoDV??+@e
> > zg`wK!-l8aDa_m35OpOA{bq~|+%F-
> ENWnBJJ1zz=ApQviVyhYj<q!3)k#>zx}*$lQ{
> >
> zY)3sH>@Bi0*&kLSIb&lzz9l_=+22;AeVh6L^t{lzJ6+Sej=Qr`1&}zVyU>FjC~GnY
> >
> zW#ZgFCM+a$J<&JU)ZP`wOG!6|qwNR;<=CCt7QifLcx#yTm@)7n<c~8ktZX2G
> Ef!T<
> > z2ci!iV-wM?Bu7s^Huqb-
> 4XWtpk**rM!C@5P53LYW?<u>&(um1`y@zE6rNk#CCt6d4
> >
> z5Pnhl$<&6QOQ&>g#0vC1AHh11F8`j>>&upZX?ctw+P(F;E`iuHQ%zIzm&>w$p
> ;%j)
> >
> z!Vt)F9nvn8o&utKexOnR&JeiQIukEIt&=H)CZsbl10McsuGk=8pZC;?h!4Tgi&lzu
> > zDjuZTHwy^t7q6I)qd+|tpB|d7o!d^VfW8C?{Zr&?EMW2(V<^Q}(hgi?%-
> (2Z`Wl@e
> >
> zI4<xcH>a=4M6>%sjwY+@;+@A(M9xq0HsuIC(>xTK0?!bT^ynHl_KARPH)(c3L
> 1Smv
> > z$$7q&j?=MNqQuSRp`9Xw%3ena)`!GxD%67~RKad><Q!j;XoS0%(8-
> 7j{eN?7xETIA
> > zEzB402g{<PP^oW-<+U?E5GIFo#6H;vt2oUciO;$5b7A-z61xM>g-&p0hhmH-
> #T#5p
> >
> z#(9icBG$h;f2>n&q7qyHXM9_t#hCl?tvc5Jqoa8lUSwt)Tq<<;>6X7ekCt?lxC`XV
> > z0~ET_i;zV_%_?W@6PpBeuXnbkkmg)yJD!rS-
> W4+WUsh43&>4RG*{QQ#GI!wphN<ut
> >
> z@F6q6)=fACihVPnl>ag<&go1fNu$9JG*D(V(t;Rr36Qr&z{oum2BAOsC>IZpv)O
> !8
> >
> z(A9g&ku}f_F2k<)>9(*XlnOmF1c<&%MHADqo|BrgcRyL4X{UPz7Ns=_Gso2sI
> PCli
> > zDUUUhCz8}TMNB07zA7}e%`ulb8dmyI2ag_BJpwW|U`XJkp(@-
> pCM+y02CSFno2|(R
> >
> zny$~CHPnsnWv>$k=(lzqeglQA%#%Hu6!%b5T^4cMb|F217_5R5lkOLjBf!q<vS
> 4D;
> > zw={304(#<oEx&w$KKLiJ!G*kzHQEP_fz+?!{R-
> Jpx~r9!pm?4kz;k|ao%zB@5Hbe<
> >
> z8VY98EUm&jD%$gApar<Y(1ZE3VPAD(*bUymnih8q6q7T@K!bB?c*h#cK4EHV
> $~Mw0
> > zOZZ5=T>*H(5Y&5b|F$TLy`7Pk?>+6Pz|3nb+y=H%<=kcMEo?&S1vwpM-
> j_UaAx<g;
> > zmAr6fyoIA}IvwduC#0A(&}x;x%tYD#h7EswGE(xG6HEdu-
> o$d)MnXpluW?a_({zlg
> >
> zv^8#|fLrlHU*Lmmq?E2*Bcp?ji+|D;>krJ5pq~L5F@adoCT+wHmA^2==lTOf3^
> Nsh
> >
> zI6COif6T<eIsxiEr>#|ab*0;%0mY@UQA8o~pL`QvrJUt4l<;Q1Jp5Cc@?nX=sK^
> H>
> > z@#^-
> Ah6Ui!4W2y_h7NXiaTjT(kC5946mu5EIsuG+IQ9f<e;}hefavgrY|#0sA(u5#
> > zSOvIH`J&3-{Oqj2+;WmTvAVkYXZ1@;KO7S0a8<;0QQl}{u9|6;_A5vtd-
> Ge_d>@=&
> >
> zZA!kjb;;3a9ZAx=x1j$^?)eedfcEMEp@Hiq(?D)?BsPDkAIwg9ZWLIbPmr#v+2zK
> <
> > zN_8RoATaW}d{5!m3i1gyT+$O()xZN-
> q9!|r1Ck1l5#y|GF9)80b*`2x{R5fUvAV>n
> > z@}joV=KHxJ{NM%X7R1eKT#3zvII5_y841&;U}XW?bB9oPG*Hm^A#h-
> 5<hd8`AC$53
> >
> zmx@EmG9ZV(c*b8Z;c$mMs~#NLc`O39MQ?hQ&08C9KtzEpQKHE0Lwg9l=<d
> 7^x3lQL
> >
> zOLz~OwT||427?lND^l3SJ21q9Y}2kY;~FAG9FP$|P)=HE;iL6XN;Wh<v&ih$1R>t
> ^
> > zIc;;9!VGxoj$<=1jQ-utcT%$}&Rpi3WSnCWi&42LuvKot0mF}`n-
> ;m<n!p%lxe5r|
> > zeo2cA<Pw92aB03_2E;cHJ<#un0fqrFR84j$<!!Z5E--
> O%ZaQ5exOt&$Uj1Z*HD)S*
> > zptD`VAkBS6EGPt6fu0(&FQKEd5hMoMFbwikq#%2NpiOj$3hSqT5nT`8-
> 9ip&dZ5@B
> > z-&*JW0-3YW2Pq-
> <fZb(L02zZiSbhLx0R9TvB)`R#_TGYlhjjV3RV__Lg`PGK$X)Ja
> >
> zlx68Va0&0EEg_Jnfx}zHWu>G7`XC{_MPe+D+|6Y*k9mXm78lt!v|EBfV_>3p<D
> @Lj
> >
> zOz_Ha3|0Oz433c=r}_<=aMgLNpM!7P3TlleCAM+YXAhJLbm<pWP22w#C&_`
> ?(Q=eq
> >
> zJ@?4yQxX9_f5?T3hio4b410mQFl&AItWr!kt}~vq(6@x}aEXw^5)%KOl(eFhc^s
> u!
> >
> zK&1K=n08*i2k!xmxFyjCp&tkK@Mqm3K_RnVKYL<02N$e7Caq#BlNgWeAz8n
> `lly-i
> > z`?C11zDLD!zPgvZwnDMKE!;SzPXBQd>}az!j$_a_SOLX%J!+T8fYnvD4~aV77-
> ?_D
> > zC({+U3+B_W-~48o1IOxQMvz_yLMObgGh=-
> #ZF|U1if%4r0!Fqa4AKSYGr=Bp4wS;j
> >
> zpOib&fjLlB^pi4^HY5YM^W3^bV<x#i(GgH^If!@2j1ethC&xncFqwnn{~abgyr$
> fB
> > zeFN6df-
> a9<tEIXg@ZsX*_&owcFfUJ~!6SB9&9lP0hl6_yNWUaR>W>sI&vs3<wSvXa
> >
> zkM^KrIxWjj5taeZn0^7>6VVeep*&B<Cv$^FujZ%lTyncZV^N?kodAhRD;8m~V
> g@KJ
> > zylHB<K26UdQ2ABqe^F8fV<cmx2rW-
> )4VVtF`rp9LOpc5Jw$~|?i+!$7le%+DhL`=`
> > z&VW42>)Wxuhrl92s=jryL3&{z1sX@KSHJ&Q-
> |Gt8<U$^Rmw`&o%H;FN+S+(NH@-}E
> > z2Cwn+EhwCrhjd>|`xu6XCXTJHtnk1dIPUL&;DV*7-
> Otc}jM55$Vtv405ZD8XyXxqT
> >
> z1Z6*6);)KSc0CK4dg%T3pum0vQ>5}aO#{P(tugn`fC4ZbopFsCPQeiF`o|5rZ
> &
> >
> z*m22MLEmLB0~&>EHpNJEr>{`_UHf@bz9YVj?nt;{B*8qXcL_Jy@95+^58e*j7v
> #qf
> >
> z5L#(waJ5Q0<$;3<s@Ty89PzJo`P<sCs7zaEf4lWsmniDI2L`afNR8^e$UHJkAp*M
> &
> >
> z0#ItsUj8u#y(j)y4VYwYN$gWCE`b^f)>AzAd!jD1T|V2>KW<i7c|n#^K9#H_8vXj
> f
> >
> zgW63~AZz^!9{8KFcma8_90MJRsDS%J&|7|J6X1ZID#V|R5*pf14DZ70A4U}f!%
> R0i
> >
> z*xK4bdu9e82m$eCNe5^m`1+0yG+p)Ai%9_%2?uRoJ08p+%l7npYOaAC{!p$C
> m*DkC
> > zHs9kcukmSQnY-`;FsIMBQNgVP-
> Mq098|Xu|qO#!t^l`6t7&?ajJCqs^1g|c#TkBd6
> >
> zpR{hR8s@e{ll100R=OUJ{X%j>s~WE?f7jH1^Ud|LLS!5;2@CUncWN0q>vbVLU
> 7F@}
> > zw=HH~=P!*xj#!bM)-rh6>c${mKtTXni>QJ7c5YwV`pjx{JNI-
> W354EXdcSk^K;5aK
> > zHvx8bZ<vCPQg3=xa%w@Mgt3xEo`4BpuBL`(h-mvmQ8D)-
> a48PghrZ+3AO}YN&bdTo
> >
> ze+0HP<rg5=>QeV^n=){b@msu@xV3hd+za&FlsxgA`2dsYy3J?e`FX%#Qaft?8z
> kce
> > zUC9;r{}|h?AZD?*apNq%44;oG3%FR0jh7ifFLeMtaSv^t-
> MgiMENG=ijNg0)d+}c;
> > zB37-GyMDjRN)Ia5j->kuYeB%$r7mAv^iA8>$p_=e5AM%Zy}ggWNO-
> KB7MVoiX`~8>
> >
> z*7)IjaFf%hHbd3rW}MaKv~)d#H7ZvMEa+7%Q{~f^PXlXDs>=$+9z#!al8x)w0+
> >Eh
> > z-Hb4|sRD?_*C^x(zVj~uoxjbcjk&m-)PDB%_D`$)@T)xnz5%Q$VAe-
> jybQSioRnO6
> > zpm;JeMEQciVCPbow+)K59-
> z&$!uL48A%HNCn>dxp;#*K2Mfodxi7~+XV*OEjSsX$9
> >
> zT=Fj=KZ*1n8p&@at&EGv)B~^#3@m&Xv2G~hEB3*j@(o}iMf$Jd5(bnSj4#JJf
> ps19
> > z%T+-UsiSJN$9ER^tN<(neg*<}@@q~?t9G}Dx|X#&<*nlwsAM-
> V3W7dJ0WrB4!!+0k
> > z;zYZk1x)Y5=+Q4I`1dZe_-
> J!T$nHwi`7v~?2q6!GFp4Yw(%Mgr$9Wf^z&3n(g?G~h
> >
> zw*4)$A+STy91>Cev^o?Sxb^6;q5V&k=QWf<5VEw<PC$T61G$o2jo>7aG;Q1K
> Y^|^o
> >
> zc;E)~o~74@l~yyg&&)$vvi78){L`wW=@l(wF2Ai8JRf6?amb~~1adnQ4yGK6{szY
> w
> > z8&-
> yf@E8>lP~G(eeq=8mS6WA%c!?}J08^@%kHEik2dum#zvEulud`jWwD!Hn_Pl}l
> > zhM=)cOy|@+mV0(&3=)Wz&3}Tu892W0cGmn-
> cjsU7u?E8Rr%=Go&yh&47sj4@fk~gw
> >
> zHbHgW)yUvdc)U*Gf#UVd5K4q{i=exR{YJ*2z>D&vq_mL+0J^Eqr6bB7@jA))o
> z;Vn
> > z-
> 7Hy@NH#Dq0Ye$cbqq?iR`tT{Rb5Gv+Sx<o%cr~s(@*mS_Po94KOuiB$&EiPH-
> #bB
> > zXM$7tum#;TFre>Vdj~M)s3Z!I=Ue0SXR`8|GwH62$W-
> 7Me#XrQ^Tzt>kfFu8R(sYw
> > zLTUgw_~Kc9bey8(!L5MKigRl$SrxK^#-
> HozIURZx??rFE2R1&lHytBUXnb8s0OoiG
> >
> z0(tf($WC5@4zV5}rfoNmN5Y7<f$7<X{b2rPkj(QHwcwCf=BSu5`1Yr|tgb}5fD=|
> B
> > zBZ2G0+rSa=mh%RufgqeOvZnHE_88jdip1+lwbo=GR9dU-
> `l%kXo|H)KHVD6KWh*Rz
> >
> zy}|v0KGX}QfC1NJBeuXreFw^?gfJlI@wcfb7cF63U?#eDlei%aRM!m;Hp;yepx=
> &<
> >
> zlG`I92P`&o5QPF3^!fmpImKoyZ$raWcxfSw1lL>|>??D9()^hX)X!dkMqhTfL%^
> gT
> >
> zDK^9an&lf8RbTYi>wz`Gn%!tz7EKLbxmh;aQH=nf+W{^JM>ncRG;+bx*I3T3AC
> r1>
> > ztA?Lt4IHi+*?xnx?g7u5At5mlGg7z;4@#&stoL;M2_CVx-
> gL}d<c_Mn^@%_FE+g?M
> > zOu>-
> D7w<6mo^=nnPL0|huO7=Z(hxA!cwBQoDlG&99x)D)xt=osIyZVLPiR6BBm<8{
> >
> zG&j0?mmIK>8&DudbNk55!a;SC<Zmv}k*@ol$nL1j?BWjAfb3IyV_sXiDd_>hX
> BrHu
> > zlIbQ*_5-vx6!%Dk-uQNr+Jb_aC)PZ3*uB<MB-
> gw(`|azE*a<_S1weMZAOo%w(L)Kl
> > z-
> dk=TU*Vy1WB5sn85_XnaV<$}6CXy?DXfEPWiUwjNO&?rt8bi$d&cw6WNN_3
> &$$E$
> > z=aZ0KjuN9Z_4@JfBfw~`4R4~T-T;(py=d$WnmIOPpx8)C&OFHoM&-}>8;{c3-
> B{GV
> > zSpajTZ{QTEuIcsDJm3Qr^~?SUv|iA5G&EDlzvJc40|0qdwhkknYRshszfpeE-
> ii1s
> >
> z;li6VZBWk{E_YY<pe&x!XCpJk%58BEA3dVv546&*Ys6Lh02!4QiTeivtQqDe{d0d
> N
> >
> zr7Z|RxZePzdOqJHasLwF{ta>g;N@8`;k=SN<1eSW=2gqJ_aKSDA@PO~Jj2JDy>
> fE#
> >
> ze+59dvO9!1`KKy%xtUWc+Ka3O6<zaOC>*j2+V#*oEC^8Q94dXK1m*<|V>3^l
> 27AMD
> >
> z6%mF(P$gIq8+ehK+zYAB?NnCmK~lSUHd9p~D@$#MgC9s7Y7EeMI;r<O*?LY
> qlamYM
> > zvH`de*Fjc_!0oB;es2ryN-%luo6bBsA=_A=-
> nmZ}%^`N$?z`4}RqF82uB)V>)}QE?
> > zrWiuym1^BE%d4kuv-
> dD%vj@iTDeQBtR#*@Vl}}#wnx+R;HZF8S1|*3=E2yFi7W<MJ
> > z%-
> SI+;^Zd%rtNSOxcQz0AA>HvVOQ{`U+g3bv>?Cw@R$8@o5*nEBfVPA7jh+lHR8
> =T
> > z3DUhcmx%#n=oUMMGkvUbHV_C8X1!ORo-
> @a)b+Ml`1F<g{$T*e1di)$*fQ5m|)PQDO
> > ze$ay35NRLT1K%g*UcpN+klJU$8;N>w38wjVz~lci1kCL-
> 69N^MI1)$EFwkLm8>;g4
> >
> zE){hvSV?1CRSdogpA1TqPJHHqFI?S}{DAkLU#Vrjye#NG=j_8g_krj#`<}TF2$5N
> F
> > zwGTg<?@o6MXS$@<d8ht$-Jw#Qc@o`4-*>;{l7rkS{fsw1r4yrywA-
> k%PLdC*dzw1?
> >
> z*7v2fQ{qIGCy437yA$y|di(tL6bIpZ{lY^>6Wt&{ZTkZ!#*<V!J)Qd?+HtqBIQ>c<
> > zK}4elE7~Y&YgV!U4qDCyR}5|`OKn(1*z$T6VxwDrI@p$*fJ3XCr|G-
> H!u*oMbA84$
> >
> zDf!{}7VK843D#Vh$}Ta>Kr!$QaJu~BaS1!a<L}mY^Lz!P6sh5EdKgl3LVqPFS^`Q|
> >
> z{n|=6!AK_%errba^sqP~f{0y#NGSR=h=aNdl`aZG&#rax@Dx7&qbn3w$#Su<
> ddWSp
> >
> z8`vdtPHOgO!{hWlVcp>`f6wfk_*ofE>?9~Nf&KdW7%?>x`iC4@N`!i@WrFLMC
> K!+9
> > zo2Zwi=FZ~N!#pI^CEXp!BFvxjcn7nbr7DQ^s_67;-LGvLZ-
> >LB_tbbsj!WAr(Gsq%
> > zw_MRqd{G)1`B`l*-
> mCYdXTnk@je)$}Zi4rO5+fVtbt*OU3&evS4Vl<C;)E1=4X|Jg
> > z%|CJYqS8jaFJ<HLLjt-Bd}H32*{ssiz(uV5<$S|``{iW|fi|zD!Oz#~6pTW11hiq~
> >
> zIy@ewD;`ej#S2XrJBQ87($zxdbKz*1{Db)ia=>zV?q^FJ6~C<uF0S<+2G#4J1Ght
> A
> > z2_hWx<I`PCB~|l5u8W1&w+sXq4lDO@uj$Nb)!*2$DYZn6-
> 9?bOShFo2W$of{J{gHl
> >
> zKo1v2B$WmTQ_6m1x04m3U@_UN>RT&J#5`2*Y6DHpj$NOC9QtJl23dJ^%Y$
> TzS4WWp
> >
> z%teWbTOjRq9qVnl3)ut>dUQ)f_}SV#Zn12>C}G14#a=C7``q9)J<}iRV#CF#isP_}
> >
> zETXWDhAcYF1^7<t(Gl+(`qx#^B8F@|{zAJOu@+1A_jgwu&EH&(aM>3e!!3x7
> #T9bz
> >
> zp`GCL&Yf1Hg%_9awphd@vYezbFSK;sW@15<yWpP5Zn1NfEwO{MO396FU?r
> ;7VlOw;
> > z3sB&Z#^LTT*B<=E8aV-1+jcGaNapb*L>5e=mI>Pqr!q7ke_-
> s9fgjkjr739K6W}g;
> >
> zP_#DKt1ZJr#fI3rWXLBlofiSpbG)M<kHQK&1Rmjo7kT}(g@&*nXLWlMkKH6p
> @~Q`G
> > zEyyglM_$F8IF$2X5R^Y=P7n9e@V-YX;s-
> 2}8jJ6dx^p5^hk8Bk;vS?uYYh_l%0w`v
> > z8QwfoitD*@-
> 5862x&Eo1?Tm~{Y1b;eUxUlvFg7K9wfNu8Zu6iVgSw?pf>Yb&E}j~x
> >
> zKygwn@YTO@*^7OBcrZwSNvGLCAjKd0dbmnrRk%tbG0<=QO+1yFPVW@&
> o}${B{GLO@
> > z+f;_u5DzfW3*g{Ot?*lMI4};q<zX(wW~J20O+`nb<2L2Ha+iByJaczlM=6<-
> 3_YO>
> > zw9k?sts|&t^kNY%<N}d)6yIrCH{=CaCl|<W*<7o?v6rcc-
> jlPsK67!Q>`7U~k~@(W
> > z{H{Q{1-
> K+v**L1UXc1|gh*;YWWyLNM1wsT5Oki?G6?N?KyB8Ho^>Joze&r!r#JmFX
> >
> zJqfgVkhU0+y+^}_&B}9G*l1TIfrImD1QDZ|Uag_~4epN0Wk@)a3*!{8wRg^id0
> TYK
> > z-`2+H1Yr#7j9>-
> Q7R$tgZ~a%1i4N>8?sfe7IxWp%G@L~o<bl%S10*{AY>RU}l5M$i
> >
> zl(~B7Gg~f&Tn+@zXs>+0WtDf2n|H+^v9+p<?v`cKqlM|<l?dNRbLO}KM?7{R@
> }8Q-
> >
> zDb>(~0BUEU&<oC0=5o5V6f|sf99#@)*mhVb_emSGFPS_uZ*4FJ&CDm(zVz
> VB{d;Z$
> > z>%q~GMLth%$)7kc<>-
> ;)3FDeQOlqHXE#r+n4C=}QS@MyvfVTr<TK_v;u)W%LX=3xm
> >
> zdlj9XC=X_j4OM8&Dp~zFh_Kk~W<cK<{#E0V)=9vO)EGVYf$<0ZBCv#AW4bW
> 2eba=c
> >
> zOlZE~BW)31P7rRmVQRt7A;MW@YZ%t^m%sCj{k7MjPq?;w&7#RAn(C{3ZUT
> nvLvp4*
> >
> zsyQ`W<_cqWnY?UQ3>b`9TxMll(n#r&pMMWbYzpVm=rj=@Z7*F&5SUT~m
> MJXCoBHnW
> > zXj`JAT5yf!1BoY|+TNp_;13fdJba#>jZP?}>GE-I2(*d{Xg1uX!+z*f;`yEitU!R1
> > zYbEcEJtf;pi?2*YhKK>irJB+{-W^F8)a6oD0=2q}>ZEv_J1((x_sC!@m~1|lxd-9f
> > zSOT@Xr1Bh-
> bbXXRT5_hOT@g{Dp(8w5W)aWZ^A7^F_u>e#G3a4EV0<Z^jO-2|a}K?r
> > zFo(mo@$6w!RCO;!k{m2{z-
> _`_s8cb1@U;62vs7dN4LV`(tZy)kw0qS!Q!11UZ%C_9
> >
> ztbEz1_46;&*;HY>ml01b1bOgokAy{FB1>uh*XlJfhmyKZ+E$$rXds@q<B=Ovg#
> uG8
> >
> z^#=OGDkg3ngdex<VP}scd&Bs%@J{;`a5S2?LW}SWK`_(}^oC{!3(16{sa6;hG4o
> |p
> >
> z$s$VgHx3o4jk_>j=NP<Ve4TKQ?%LHn*7c)K57cGjmBuNkYKy$AiKyRMh?FJ|h
> rKpU
> > zuNu1HJPbQO>i(-FAI3{0OUJ)*Suj)9njiaIzqjj|13DohJD<L)E;cfhvXx@=<C$2G
> > z$O|nV5>2!S18d~_VCX5{Yso44WdWyk|E+~kvOK55+j`-
> GBdrly&WQ1*?kDL@pG<V!
> > zy15r%4El!1g%)F+uwsybyI$e9D%%;vLB3-
> JyC<keh(WCoDi(@n0xqm`@&*0R>;SVa
> > zjE@6rn{H#*&~_Rrk$^~$I8-<rK4wPiYK#p)3&UJ1s*5wd7n>#=PN^_q^_t|?-
> i$S)
> > z&+V3l+}q_-YTf#5;-oME+!rd?0;de%k-B8K=Jk=!(&2<Dgdb!+Q9|Jj-
> ABGpf_{Tj
> > z-j@}G*6l?MCT?VD&;M=?_K2?3^d3eRDsg}bJ$5FgMB@xQ<#-
> 5>lJ2jXZ|?d~C=n*V
> >
> zOe%k%3vPHn&Zy56wfiWs0vg*S7wOw>1~eAetn6;)3I%3|d+3BtSz(DPJNqRC
> R6na4
> > zw-
> T^n&!E}(lqo|tSQ*O=0Bd)N*Ls*l30a+H7gRUiW$%~bo*7>~bfZvS+P$Y}i8+Li
> > zajQH#9E-
> re@K!2m1+(vMn1G%<sDdu^LVV9lDLwQDr)_Q89Pn+>BAl0fTGoC?L675^
> > zR`crJ53$%V%1ym-z<mYLlTq_iV8^{KN=sqR$&(T-
> 5)vkqIFntDZMA1VMOHjx#|#gp
> > z<=jzFhYH`U9&O8-fDan`-
> Y4dT`fuoj6M{EH$cYAwYCB}93Q7pvnY!%6kR9I4peQs9
> > z8gXfY+U%9+QIfUrv-RMP8xj+L96f|0TKE|UW=sIy$!oL;)*-
> U+iW$vXVhjdwb1+B<
> > zCv<nva6{I?0Q$zk^&r>#R!fV)i{_#E&I)1j3D%PzEd+O__nwB9l@0vxf^OBj+(-
> AS
> > z2foG1W*C4?Y~g>$)7v`sHj5VWGE)4G4SN(u3s{8)M2Nr!W-
> JCA@y|<k2?s=otqkXs
> > zRrxzUDcddaRCG#+S1yFOToog>HfknfH$<!GF62`JtQgd-
> n$&cdT0?4AaJ{y8Haf%6
> >
> ztBCCGSv<?V!&3?B*U$7jHMx;&qtP~4{2c&o>jQ__Zs_qc0ioj)*r>>nNWnFgLc
> gV>
> > z^pFUzNJBKo!`J$U<U?I)L`-xzLe{6dPr~AT(79J#aDA=5<Ai7X>-;#A>St>e4yR}-
> >
> zs(xvgxPQWiN$sNZR<pDZz4W|XLI~TaPhkO;94de<Fez?8=jQR(9XhCMjgkE7O
> Pe+{
> > zqPsNRQ2{%PP-S!ukCq^Jh_wt_D|VG<E!CdXkR<b-
> LbUdRv*H4Cj>iO=b6AU_Wkt_g
> >
> zN=W=4;kE1{Z8SE4{eMx%0k|j4mIYN3c4n#E9cuyL$*+>`c4xDUU&kujvGsP><}
> &(L
> > ziB<$da^~Lvx*5xgy++?@K|G?LB8(fubjF6-
> dFS5is`M~bDz>$vvzPgi#c=y}m?56~
> >
> zeqdWidb5&VSRMO9OZ`HwGV_ZI`dR){noB9_sDnUTS@3hqC3b{ibKOT)gLqC
> AIuWDE
> >
> z1y};%<m9qa&Z&f85zw%D^1e(b%5|&^ou~OW$cHe@UISa*Tid)MDa|`tdxPy
> WSRlcK
> > zA!c58g1AC<{{(N&%*e-fRXOWZC8~~T|1k8kB5Cf0<>aE-
> @Y*KD|29REbj1RxL=h8r
> >
> z>+fB0RQ?xV8~i=Y`+comNUz$q`%F8Q`XO=5kHob}M$0h8r&iu16XArAR5vcz7L
> M^W
> >
> z_l0MhYu4d}a8@DFklGq(zEifZ`n>LW6E7ZR4w2#&6?rZcOGgeVQ4yLmo=J>L7?
> _YY
> >
> zh;(3>zy4DXEJ+bjsn`Iv)wK4q?j(>j$8ur(Gk*YreT8Wq!()EpO$qelIY&yM=$Wf(
> >
> zVw!caiJTMU912uWQ52pw=2PzaLhb++yL8sBFt#1*4(V%FAdSlIV7|bP(8F*@
> Wu$Jn
> >
> zRaIs^yAnMwrNj2sVUI?;8^IcDZSyk>kATGymF&x%h}BQRzm^bYk+gcYN6OW`
> jUyi#
> > z9`L}usF?50NtoIsJ-ILb1WoIBu?MEj06ZlmLL@N!i!VM*^e=1-
> 7wk8y&7D+XUbGqc
> >
> zq$zAUBQKS3cDK+FZv*c#3nvye%cSD9ImBX}x=%Lm7nD_SC)Cssol^$;07fal<X{
> B?
> > z{8HuOa0hu?1Ptjp0o#fQAX3nu@V3omX!Vz5-S;{5gFR-
> `ynB}GDY7)z8WdiaOz1?$
> >
> z#Wvg$62Fmk+c8`dhkr*mwTTOM&$kdO_l5LV+~0@N%O1?cBH^E@32>Vxo2
> w_fKH^bO
> >
> zD)#2Vai)r_B11WH<9rKY6?f}OVeqDzYTtQ$$!fu$^tZ4IEf&7AUagbH{B5mH{!C>
> r
> >
> z?!GKDBpbj4hmO|2pJDQE)JgFuQy{V$^bXuRLYQNZ*Q2TAuk(wQD`>ijN)_|{_
> Yb}g
> > zB}RUduv(g5LjT_L=&1!ZB0Z4!n)mBtIZnG)M-
> {XinIi7VVr+Ml&Uk80i^?uHs^eFi
> > zXl`9?-
> $MW^^?Kvyr=pv<S0t@>yYl@UlFn|V!pF4MKtS!xA$Gp~LHOW&Pvao29@(BH
> > zQPs%IT;9S({?mP*=Qnc|D5J-
> |w6F?FKZTjOGJzXLIUY*Ru2cca{Dx^$QP3^v9nf=c
> > zSN1ZZVIUK*PSDoaPh^-w10GaNc#DX+5E^4%Hq4-
> F^%90(P&<beWqvDXsg0?iWV^Yr
> > zBw90n4C4q-
> <Omc0Xce$jZ=HG{#}+mzZ3RQF4j7$^zXADKTj4v(;CzE`W@ALxzm*iO
> > z(vLpGx|Y+-L{mXx>ADwaHTV3J@HNAALJO5#Jh+9E7(=C&1#5R*tv-
> 0T#hDV!d^^pp
> >
> zD=KI;vE6prEu_&FkL3b5ls@u38`P}>koC6hw@9)bj{X2!Z=zk+ejoRZ_UQ#P?i}X
> {
> > zrb9a8cYS#_+gKih=L=`I&pg_3Ph5pKTnl$j{+o$Bqbv=rlzv8bfz4To&~4YEW{6I;
> >
> zM&VTo1yNiOmjRj!72NfL3)}*As(LJyU(NE$Bvq*{h5oBrhFoP?fMbNwOire=!JJ
> uG
> > zsH19Sgn2-N`pP<xuTsk_zK*l<>G;3Da-
> R)wUYvP#%R8D{%W4M3=p@E&YpC5Y<^3Ym
> > ziNry8BJO!6Gs{Spn<~p(CkfRkgVTSPn1xG`u-VH<=3VIqG-dJqz7%-
> wXl_NyC`0qB
> > zZM%WkQ>90*E%1Hy2R)%lpy=dqfBUWbktFoL{8FnV>VG0X?2Xb<Jkr-
> wIc*7PU)!KE
> > z_#*araYa0U+l<aJ^iCV*Dk)$XmC)%|=WpWkwePo)Ek-
> a?2dg6PVM6GVX~3`oj%%M;
> >
> z6<Zs+of_gEHInInz|Jdx_dRVFCnJ7q^+E3?M%fLOZ}n~S=>^{+szPS#p_f>%2S
> %je
> >
> zqp#XEZjXudd#julr>lbGEvjjHhMj>&zMCon58tRQVv_JA)Ve0^^yI!9er^r8x`y}i
> >
> z0^|2WTfYsA_>Kk7xj;Wkz0hg0;^oZ~QmgRs8^9CRzj?m~FgA%a9fCV5_)Pi!qk`
> >g
> > zZ#4%WL}dk{_-%f~DgU9Xd0caLHuWI32Vc-|bSg^HkL<46Rq2oS10%T-
> 2DeQ#fI0ra
> >
> zt6wR&OrE`!68Hh~=HT&7a0EF%XCEs6D6<|DPv=fuY9Z|Wg>Rc{<bc+QKX90%
> U2ISK
> > z7k~rD4m&7xFAX&{$U-
> )37r*j>AyS^AcF>rlN#P53g?MWu@;0ghXJwHmyzHPAm&$g3
> >
> z`1$18`e42z6cX`{J{4$jI2uf2_gZ@V0E@y;uQ>$(sL|;uC&2K26M`_oq%vabh8J1n
> > z1aL-VJQ)6dO{5HCl^)iq1qlQ*@lX46QF;-
> d#*zW#Tye9hV)P&G*REZ2he+xK461iS
> > zOe*6~6)mek=E;_8uuk7U&#*H5vR@QX3Wyx5GIfi5!bd`c7+-
> @izT8*fdO5W<a<>h=
> > zGzN?ht%-;PqozRov8jp4bT1fme{aSh!v>UV9a5L-0o`o~aP?IA9Z!O-
> U`a;Yy~M(7
> > z>2dg0OmlI4rM$fS13oG`9;7}2lHqp%>~TQIr}hx!JPQDk=@6}0-
> *)&Q!XszxM?Zkc
> > zJxsx>FboFMSO_UsBIRuzb;YY9gvg>-
> Jfv0&0L`@`(iY)p>yfDW_@HcbVsotY!jO4s
> >
> z08I2ZtgBns)*2uzd{t{K;P3BM2(E{<0<@&7@olr15`+pC8sOjJs@Mh?*Adfg)<XB
> ^
> > z!JW4a_lmE_m7}#-^(IB?0iFB$A^6h*+-
> z(S6WLx3G#Z3Y%Zw^ZekvMu6ajrh9YmQ9
> > z7-54~(UFH?f-
> J_YMgRjt?>Pj6Z1R+w_BE8};H@ae@Ul+`r*S~jVX*?4uNlei{Pp8V
> > zmVbN(^|1#(h+-lD+oK-
> PFmiCbaNNAfV|D<)!3S_H4j~Ez5MxzGt0E5qs?(|Ia|;Wb
> > zObewKL-
> P(n_4)MK&oN(E2CtnHoZ{Uf84!3wJa{usu+FDdE$udUN03e<HZo}1!E~AL
> >
> zqH`^B_5D901qr8fvd1Xu`fR@xM7!oc`cNYw(TyzV2pd>O0j%K6kaY=*hR`={GJ
> mE}
> >
> zSQHPlHH!s6gms9bXVF>}0F5dT%}`rqL(g7j5drqNfWy)N<+woi?CW%Xek$~q?F
> SAr
> >
> zP%2zztgpfuZW98*d8Or41WZzvm~?<r@;YE+_~kX5QU@l&bv@sMnB=#D#8{
> eM#TotF
> > zf2^1WUw|=jGZ{M_KC6YOEM6I@-
> R;axyygv)z%w>J;QrTqM|G|{NPAfzth@dZ>-!8~
> > zv{li;2o8-iHTEHffIpQ^+w=}y$xOQ%*>@9D_c|rUAQ!t8`3C_or0$Qvu4IstSO-
> Gw
> >
> z_KKgb4QMQlOqh#&87!3f)y$gu(`BZ1MAUU!1UH=Hg_{EVMJ}b&A&tdc(1{tu
> pJvh0
> > z2yd+qIez;p={X=o?0-
> ^Q5e1ZDqF$EWLwk;Wafrm&{*U#O+U?v8JB+Y2(2i;_h6F9F
> > zPt2-p)e8c<$mYLVhT~bJDZ?-u<yK0`<x~@CqukK9-Z~Cuu(Qi-
> 7AsygbO%g|<oo|F
> >
> zD`%m<5pJYWmrlB?SKNYqR@RXWMU&gv+h5yxq;k#HJU18?sR4ZR>)UY+(ac7
> mcGpsI
> >
> zXo&HFMdqhPGxn)K%IBDgft4Rh5@7S1TVo#Sm+}~c0t22w;lZD@Ryh7W;8t@
> zeLf}n
> >
> z{4z3E{9b9XBpKv@UhQ5mpj2{3sjNuZwE!H+HI1X5h4xeR^1Be9`&XydnwnJE_
> V58p
> >
> z&@uEewo6m={lX9bV~R}@7XS!czLY$)p%e(sq~EUR;IeZFJ=6|?4AYy1QVkb!EE
> ;_G
> > zT@lwGAo3iS<CYH)W4?Ri#2Ar!7)52?-
> MFD?P*U@3j?4kV=+6P&6r#j+wuE5{zCuL|
> >
> zj7S)yR*>QrPJVHH%rC6I!f?6=7zcn$WPnoUjkyKt>OFePyty};R9@)aO1RXSfV+
> Y7
> > z*L9AUT{ijtMS0dcKOCKHpr-
> +xSzy>GMi8eh^9$`m0MO)I^4#)6|9fq0Y<#+xpDRp+
> > zM}!>G-HW_0p+C0|#wR#aRBk!spJCi-
> eFOmG^@5nqfLK@zsHWvFIpCjl0MVjSQ!<O&
> > zpbPMU-L7qvJMsXT>7cml^}7Z!%s5@IUxC+CukMlD0G?v&MG2S)m%r-
> sKrwUsCLRyE
> >
> z#47)JIo{@Gc$&*SQq7M+>)_zv#t0(fLNZw=j<$bgGfz6vU0_QXr0m@iz8VH7H
> 1shL
> > zIR4(`^PQ8D?+rA7H_YO#z&)lcnZ{)&bPUlp$ONhc-
> PRL>58O!#8GQp{Cl!yQ=7Ue@
> > zz}|n}(`toMfrbW9KwZjq8o**Dlk-;+gP+U)KKu5a-
> Xj6S$`8%)2B=C`%#X^UsJk;r
> >
> za0em#XMjE$H}AJXLcx~`xsuP8r~t~wzdDjkK}NteCIJ8dKfMq)4coEKZ3U@*i;q
> p`
> >
> zPB%^}<&X}`R8<w5voNtSRrf9<J1GKS$lw*;g^p_Aaz7JqF39n?(NAW~T7Oi<rS4
> +q
> > zo3WCw1P5}HwMm*ukM@<kk<0&6_qH}D-
> B$kndG=Y6ir}mBr@$2Y+D1hg2`HSFo?UV4
> > zWpi&inW)}pTDjzcWI2#9hs__rze4CYs-
> U^p^V*Gvjo14>%6c8@4&Vnrw*Vh73t+H6
> > z7L~CGkPPVw__7_!r(O9hx{|;1vb=ZaW&x?!74dY2I-
> @dCgu?*w68w7U@T2W0@Pm_Y
> > zo{)`1QrI<jRcFVI71%~fo__^M_!i||(+w!N4j}0^M5#`X<Ir{W2ZwrlP41!MVr8j)
> > zD7p1*-zR$f%3svc5cpCsTy8A<X+=Xh8*Ja-(sd-
> `0?1~a)A*1Aq5ZF=PJX$`K|xwK
> > zy(%Iv1B}78tU<S)-
> be<;3Lb}VL1bw!sLTSgG^Tm6U+S0r0^2*=iJk|FL|f$u*XdJ3
> > z{t^|Spx)=5v|Ro*L$|qtIsxiScHK-
> ah(PHB2!PM{{f9CL8Q8qLxKR&v<*sT%{<50P
> > z1nf4JzkGvgr`ceSUg-
> Y`cF~5%)%J<tHQEFQsR>9lT>k3ffBAN4mnfgI#6r1{rkfnH
> > z3w%^07<cfvxTKF%TLy@HO*}pati@R-
> ^vX|KAVC&{2*hQ}^dF=JE#ui~%UM6t$g7Mc
> >
> z4&Iub*Txa<RwsUwdXjb5Y&r<w6@b+qv<juCfIb}Mxq|JMk<KLj@cIu35Rk*L
> wg4XT
> > zZ=5G9{;#<+|A(@D-*`w!h#^~%Z7eCfk(8yWEHh+@2-
> &x>7Mi3KPo##3Vi5A!D~zVd
> >
> zkX<7pMv*03WX~3&@;UFG?;r8?gP)AoyzcwD&ig#C`#6rb#JVJ@@SZXqE=kiH
> J)g}U
> >
> zaCf&=E9^#yykPf>WD5}t2)2xoMPL#bz+*&6H+?C0Y2J+t?v&`3)G3i<h5Z4WPo
> aKg
> > zGL`gU5E4`hnCF03rvo2knVHf3_ju{M{<X)@g3v&M6r?ocDXEvNKs|E4Y-
> AD^;!gx|
> > z$J~t&UI|{AvEA-
> al_eE2(%@PCK;4|OK5}iecCLodATIeZJLQicVz5Mt@)_)$Jam3R
> > zfU=V!Oqro%ZxywKyb9`DgL<+Beu-V-
> O2C<F(Kc=l_AAHdBNE8JqDsVIq2~h~r0vOZ
> >
> z+=NgcKj_}SY&equQvt3G%*eGwP*lfhW(r=DLKraEL`}p|gP5_mDN<`YH^(h8gz
> -DH
> > z(BhgoRx6F)gH&%z1gjO{)|9zOm%3jT{YO*7RnKy-
> >D4Sb%Y2fkipxK`3NB{Zs52m?
> > zJAbA$-Qwf)_D;q{KtfnuNw2wSxdJ<x5<O*a83SOvyXhy29cZr*0n)ET-
> fIoOZ<f~u
> > zdLyyo|2TI~EKjc^><duhbVmHTGsF}V>a*_m%Ol-
> KEmeMx`wo+msu_i=!gCUc5aAFo
> > zR9;S2T$3VK@oRDw+rKWaVw#h1yG0o-
> UlMiBIpwFoxSL(w@3J7A9556*;P>naq(Up`
> > z_KUHlp}~|F^iFZ`BqAC3k4yLzd;v&SH!r6$XE-
> kp8;RCbBEh(6<t|#mnjgI<XQTE7
> > zzRjDd3h~J1Hg$lE6JsA5sySOo!$jtgrqiK?>%)^(o5f`)YKZS$1gNhfX<o$*2k&mr
> >
> zCcv6ub#<o@=+^($v00o=n3S9kIUnQGLvN$<(>!_#%}YQB`RrePG;=qsS1eB6Ei
> 5k7
> >
> zCM$e7c3X>YfQ7+8MCdW<^Ao0?i%q)fW+o;VF1H=7sDyU(rxf}X+YO#K7xm3
> 7i?0^U
> > zk(ToVyjirpyQL$jO>3zd1nZII?H5JbQL;L6MpXsy_U1xSGtk-
> E?}44V&fVSJuUy6C
> > zVZ0QL^9EL}Q+rmi0+hKCO-
> *YX5LjRjE!S(o>%PV^C?8n8LD5yyz4Rs`Y{K6Fv~xq$
> >
> zqyU%D$rVf!QSlm!sQf^UwDbAVGkgNkl^g;@#_W_4%H4i!*h)E08g+6)dcYHm
> ``jz`
> >
> zq6J3zB74#{#24u8?Sq?$73g2Iqy&8sQNw@OWqAQ{xXq;h(V9rMtoD^%stpGq
> rT%2I
> > zY`&F}GibMX+2Cswfl<n|C3D*Y`p*(*>U46a`GXXqz}}}%s<oqfjUr(V5j$B69-
> HYb
> >
> z?R1wSI_kK*>vW2pH$b<P!5#_=`8ZblLE;IxF@OreufNVkxlV7I%78mI4Y?8)f8li9
> >
> zKjk3A;}LDQ<6MRmzV<*!kNE<K=T^>~tpn%yeuoRb;a@QFL}YLKkHmIKfy5eh
> *!tsx
> >
> zj@MvAtCYI0^B_jOsGmznnqp$A^7{t7{ik=<orfAl`zs#x71CDIb4f|otU;h=y#;3C
> >
> z5z?0FNFoEgR!az3eGPt5>Cjf7#ex4L7%Kbn8PyOncovR<*8(1jS`KwPVjV8snWi
> D&
> >
> zU8IMHJ@H|a2CBLea6j!Fzo;6tfrQdE33T@lq*@2vHC@wJh<q*V$a*8}>)s^X
> @*1fT
> > zH*CIJkMPp!c5uW@p`YSD@)2jJCjZ8JLHB_W9Wc|KckjxjjJr-
> G6WS1r9|13yh@Y{v
> > zGn6fLmEWcV1l98v4@VngXn*G--g=_&+3&(z<S&OEt1A&q@*ou6-
> {$zk^x|sZJlO+j
> > zD@^qM5wtrWID6Oyl8t{E-
> +S}qWX$IM(w>_!tIsRG%pfTY&ct`QT#aAqO)g#>xLE}S
> > zE-
> yoAm+U0lf#AKO(M$RN3hkxX*gM;WgM_pS!W3G?hk8b!Kf3~Ub|%7|eJPl9`
> UBK8
> > zQ#_-
> WdUbA~qEs;3RKP0$ES6?$E%oALe$w!<#oe^G)Wlb#MWK}|jXb)QuJK2sHLzP
> 7
> >
> zD@eL0R<6h`tN`(_$jjTl34gsUXX2=pw=CYhg0msJQ7Z!i4K62nPkR?Ue#9r6om*
> TH
> > zFf3NfIr!U%a+tukwTmg6*9{xQTm{(-
> 5!57<DY112C{RV#CHr&VX%UAd_Wt&=w*FLg
> > zsI<EKP=R6SqF-
> IOHVAv;9JYqgFDnPH^i`YXUEuqCyH#w@_{b=@_pT(bd=9aE6Dk*l
> >
> z*kS%5D>8oMvkKYD5V+*hJHRKJl>h!@SXt34BP@?*_Qe%G?Cgnfi3hypN9cCt
> gvZ`h
> > zB!r5_<;BD32UQBjJIcBC&*szKlB2M;cl2@Qv*0AdG6-
> q7*)zY+6;7LJvM>HeW?MMr
> > zic`&sKjKEIehBAU^B~J!?-!Akq8iGqye|p4J#A{KkA#3GDvx+CX8J8+8~}1`G){j%
> > zZ2)N?_Ap!!4LenMpLLzo*5ubP$I!|^^o_)l7^Wqy0u-
> _fVYHP%QJS6G+)Vr9%12>J
> >
> z>iZ5+E#ve(TOgMGZENWJNYQpIq*&gjWdC|j7S5OYkZGUjRPahLtRx>DpT0tw
> Mk8(V
> > zvHhwDNor@^qXCUj%)_zBQ#}&2vOI5*yhv!}su9VlE-IFbN%)-
> ?sMK$L?>Ng)`3v`R
> >
> z_I4IAJG=x>g;7LAsk_X_>1eGB0P!=nQ4T!m9pCWh@RDmisz22HCZ(^_6D0mTl
> NJlM
> > zebUH2=^uJr3jZw?J0~IVrp9~UX-egotj~aByAi-
> f1#Bw(VP<qeg{%cT1IJ97@nLSx
> > z_X-
> ewXo#!y#RDQqNTtC6<ljPy<?)ME3Exe>obA98<{l<zS!~{3@|P?R95q;n!uT45
> > zk6=ztQx5L*MBM3oVvZ%p(()Of?ss!m9hPR!NC;du8$ohMdRTc>4-
> kyiVyjuy47$@|
> >
> z_!X?Yt^*aNMy~~m!*B9#rQ8fqUUn|Dhz0}$)l^q0ED1l4Q@!^7n&HHa9%>nk
> q6<X@
> > znU_F{yaE)mGFu|(^o9_jvG-3^TJ$#@)tCP&=a9dak+@B<RgoXu-
> b=1;<A1a(HF7`i
> >
> z0ASYzrLCvn`bnP`Vb96*RB+<E+BTZs3syLry>uc>SJlsou{TNg*u=v>m|MH|>Y-
> <@
> > zqnXu^?bfaD7wXC2ujaC=@Si`i{p)gtHv_#*5fUTn>Hhqhgb-
> %NnQFS!>!e+)H<J7%
> >
> z38SuzeKUTD9lXM+o;hN&fhC=_Jk$=3%pgLgK|9T<A)A_O)FeonV0Tk2gbrc0rz
> q)L
> > zn)qosOwQ`WUu0h5<o2_oO!ymS;pg~aaO~I3{sHy$_Ss$MS~YXh-
> @%MC4@d0h&s<FN
> > zVmxCkZ(Ob}y6??ZZ=@=+_>x0vID92e@XmVMr$xUR4{bUU8YX?5+V-
> _M01I|m8wTMI
> >
> zT)8#Jo^kh2hOzXFqnE3>JmJblv8m73$_Y5XxOudQorhXT@CqAJF9n@pyeX5L
> d(#T`
> > zaU6321(_tiB|XrMxY6GJM%mmruYY+_|8&cIz7fc}hXWDK-
> OFjWJG?jVvSoZ_a6jbw
> >
> zChVCp3MU>l%_qdCKl|=0PRCZtc}Ny&YXMx1L&g}|vej_av8y?zE!?7}IH@IjaIa
> qQ
> > z%33;(x<w2T<Ph9Bslpu5zPbeoH{aw^qz|6{eArQDX-
> B8hJF!+PDU)2Ng~^@q8be+U
> > zf`~E5@F>wM%Oh-1{iEi!crI+p5r=9$gJ)(RTYsf0J4Ygl)^B5-M$fLt*W!CvlExyk
> >
> zA?|XIa)1h#ieK(S>CeZJ#3!37O318rM2joStx}}#8=&ro<C}U8+5EdaWcKnqi;dCo
> >
> zp)sYYlcVO5wo(O8Akg4cJIm7zyM%rusiq1F#IUoLPZmqWJq$i0IYl{k@no5(*@L
> cp
> > zKSVWp#RY$Lhkns{H6-
> Y$pHTW51f8ryaqKs^Fo{3!q$IHG?q9U`4(p{xHu7_yW0xd}
> >
> zXedmc{`8kfc72VEq+1+=Cq|Sh!R<oA&yYtPY8LRAHxP2i1#?b$i)6vUZL?0LsHX3
> f
> >
> zcJS1QW5n+eWRUpomR#2Yew$F+FavAWf<oj#FKpulInQkZ?1xK^>;M>EFn*-
> i8r$$4
> > zZOqr7#;sW-
> rls;kbWa}BPPIUTEL+%GaWHTPr#OU?ZTOlzR^do#DU#dGWUiy_;4Fzt
> > zap=%geq*b`Jpbp^{nuB!7H+a|2g1-g9-M^dob-
> K5PWDTzJUeq*If}X<4`_2c(`X*0
> > z6;L!+h$=hX6x?t-
> Sw&oO`JQ~q=D7w(4sY%VHWPKO{5@inh7_$yR%7@A2IMY<t#vw;
> >
> z*oJN4X0i$qFv2ZX6a_ShI=MmJ{RLh%f0^vAe7xv7cwvZ4hnTs+QL<kBDD*8ov
> Gzsy
> > z&r3>eq@*BKMfN&W*>mt#-
> zt3%;~$YP+%+f4(!r89$xw&BDSdKI0Yz40Krgn2d4t+{
> >
> zl%s@OOs5Z@rrvt!s?1^;+%Jb+bFGuv?XlL2Y98&2Brg@d=5!K^wB59ar{_3j<wf
> is
> >
> ztH^!sfAhHeID|CCynWom8r0j>JF(g?uapPBlP@4@ycH@;lr%|*LIq+|*c|zS&U
> ;?2
> >
> zLnm=D3yZC((aScvn$Wid0V(2p9=mMb^^gA05Zd&Ga;N>pGAI4caFQ=ayWUc
> v*TAdi
> >
> zH1KZ!u{}9IP_h2$BLX6XljX^pK3;Zt+j42b9qXVMxGeIbd1X6xz)6^f7I*VVICVLS
> > zgMq{Gq@-
> 5Y2}}gUiD)b{=LF{+EEE{L=XHq4z+;Z~8@fX1d5|j{Asr8ha!SX2>bi)I
> >
> zbW}=bui~wHNFiLZXvCu5H=<R4d8EGTi|%noUxOyH5((;Z2x=BU*qJK}y7e`8w)
> lhv
> >
> z+&D5p>g{+oOI2XlhAjgAPpXNfOK_sm5aj_Xa;zZTU!%q&C)riN!EK7!0x;r;ma{k
> K
> >
> z6z3Hn2ZybTE$Ba!STMp221W@^RZZpG)3Ll%CDe7G<HjyKC&{TF)L2u=;M^{KB
> (|Tz
> > z0~t{qJL0!I(@HQ)l7>|nC4b_cGRj8%YE3NLQUN-
> WUnk+a@~B7zHP#Z}O$jL{+XbfG
> > zzUm=^61A`h{;v8%^9P2Pbns)^k49|~XURa#533KR^-
> ;pwarlq8+@E8O5*D1MFF1&w
> > zR1)*L>alz8aW%)}m*VPcrjBjT)}yQK*ju{eV)5t$?1d6<b@g-
> i<&Go;8D`(=Fz!ud
> >
> zKT+*8miySEG5}u>ac7<D><xTaS}!&*>rqL@2gZbnM@A9rM8)7Sg;co<l3JnZ)A
> A^H
> >
> z&#crpnn64+2ZGERDu1w`$nM8+nDj;eCseP9q;PZC`cU`&Km7XV*7jEIHrrQ<W
> vjX2
> > RBat2OV|2<CTVmi8`9DHIo&o>>
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git a/BaseTools/Source/Python/FMMT/PI/Common.py
> b/BaseTools/Source/Python/FMMT/PI/Common.py
> > new file mode 100644
> > index 000000000000..683341094429
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/Common.py
> > @@ -0,0 +1,81 @@
> > +## @file
> > +# This file is used to define the common C struct and functions.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from ctypes import *
> > +import uuid
> > +
> > +# ZeroGuid = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
> > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID('{8C8CE578-8A3D-
> 4f1c-9935-896185C32DD3}')
> > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID('{5473C07A-3DCB-
> 4dca-BD6F-1E9689E7349A}')
> > +# EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID('{1BA0062E-C779-4582-
> 8566-336AE8F78F09}')
> > +
> > +EFI_FIRMWARE_FILE_SYSTEM2_GUID = uuid.UUID("8c8ce578-8a3d-4f1c-
> 9935-896185c32dd3")
> > +EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > +# EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE =
> EFI_FIRMWARE_FILE_SYSTEM2_GUID.bytes
> > +EFI_FIRMWARE_FILE_SYSTEM3_GUID = uuid.UUID("5473C07A-3DCB-
> 4dca-BD6F-1E9689E7349A")
> > +# EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> b'x\xe5\x8c\x8c=\x8a\x1cO\x995\x89a\x85\xc3-\xd3'
> > +EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE =
> b'z\xc0sT\xcb=\xcaM\xbdo\x1e\x96\x89\xe74\x9a'
> > +EFI_SYSTEM_NVDATA_FV_GUID = uuid.UUID("fff12b8d-7696-4c8b-a985-
> 2747075b4f50")
> > +EFI_SYSTEM_NVDATA_FV_GUID_BYTE =
> b"\x8d+\xf1\xff\x96v\x8bL\xa9\x85'G\x07[OP"
> > +EFI_FFS_VOLUME_TOP_FILE_GUID = uuid.UUID("1ba0062e-c779-4582-
> 8566-336ae8f78f09")
> > +EFI_FFS_VOLUME_TOP_FILE_GUID_BYTE =
> b'.\x06\xa0\x1by\xc7\x82E\x85f3j\xe8\xf7\x8f\t'
> > +ZEROVECTOR_BYTE =
> b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
> > +PADVECTOR = uuid.UUID("ffffffff-ffff-ffff-ffff-ffffffffffff")
> > +FVH_SIGNATURE = b'_FVH'
> > +
> > +class GUID(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Guid1', c_uint32),
> > + ('Guid2', c_uint16),
> > + ('Guid3', c_uint16),
> > + ('Guid4', ARRAY(c_uint8, 8)),
> > + ]
> > +
> > + def from_list(self, listformat: list) -> None:
> > + self.Guid1 = listformat[0]
> > + self.Guid2 = listformat[1]
> > + self.Guid3 = listformat[2]
> > + for i in range(8):
> > + self.Guid4[i] = listformat[i+3]
> > +
> > + def __cmp__(self, otherguid) -> bool:
> > + if not isinstance(otherguid, GUID):
> > + return 'Input is not the GUID instance!'
> > + rt = False
> > + if self.Guid1 == otherguid.Guid1 and self.Guid2 == otherguid.Guid2
> and self.Guid3 == otherguid.Guid3:
> > + rt = True
> > + for i in range(8):
> > + rt = rt & (self.Guid4[i] == otherguid.Guid4[i])
> > + return rt
> > +
> > +def ModifyGuidFormat(target_guid: str) -> GUID:
> > + target_guid = target_guid.replace('-', '')
> > + target_list = []
> > + start = [0,8,12,16,18,20,22,24,26,28,30]
> > + end = [8,12,16,18,20,22,24,26,28,30,32]
> > + num = len(start)
> > + for pos in range(num):
> > + new_value = int(target_guid[start[pos]:end[pos]], 16)
> > + target_list.append(new_value)
> > + new_format = GUID()
> > + new_format.from_list(target_list)
> > + return new_format
> > +
> > +
> > +# Get data from ctypes to bytes.
> > +def struct2stream(s) -> bytes:
> > + length = sizeof(s)
> > + p = cast(pointer(s), POINTER(c_char * length))
> > + return p.contents.raw
> > +
> > +
> > +
> > +def GetPadSize(Size: int, alignment: int) -> int:
> > + if Size % alignment == 0:
> > + return 0
> > + Pad_Size = alignment - Size % alignment
> > + return Pad_Size
> > diff --git a/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > new file mode 100644
> > index 000000000000..fb0100420ecc
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/FfsFileHeader.py
> > @@ -0,0 +1,66 @@
> > +## @file
> > +# This file is used to define the Ffs Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +EFI_FFS_FILE_HEADER_LEN = 24
> > +EFI_FFS_FILE_HEADER2_LEN = 32
> > +
> > +class CHECK_SUM(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Header', c_uint8),
> > + ('File', c_uint8),
> > + ]
> > +
> > +class EFI_FFS_INTEGRITY_CHECK(Union):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Checksum', CHECK_SUM),
> > + ('Checksum16', c_uint16),
> > + ]
> > +
> > +
> > +class EFI_FFS_FILE_HEADER(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Name', GUID),
> > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > + ('Type', c_uint8),
> > + ('Attributes', c_uint8),
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('State', c_uint8),
> > + ]
> > +
> > + @property
> > + def FFS_FILE_SIZE(self) -> int:
> > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > +
> > + @property
> > + def HeaderLength(self) -> int:
> > + return 24
> > +
> > +class EFI_FFS_FILE_HEADER2(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Name', GUID),
> > + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
> > + ('Type', c_uint8),
> > + ('Attributes', c_uint8),
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('State', c_uint8),
> > + ('ExtendedSize', c_uint64),
> > + ]
> > +
> > + @property
> > + def FFS_FILE_SIZE(self) -> int:
> > + return self.ExtendedSize
> > +
> > + @property
> > + def HeaderLength(self) -> int:
> > + return 32
> > diff --git a/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > new file mode 100644
> > index 000000000000..51cb15ddac28
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/FvHeader.py
> > @@ -0,0 +1,112 @@
> > +## @file
> > +# This file is used to define the FV Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from ast import Str
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +class EFI_FV_BLOCK_MAP_ENTRY(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('NumBlocks', c_uint32),
> > + ('Length', c_uint32),
> > + ]
> > +
> > +
> > +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > + _fields_ = [
> > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > + ('FileSystemGuid', GUID),
> > + ('FvLength', c_uint64),
> > + ('Signature', c_uint32),
> > + ('Attributes', c_uint32),
> > + ('HeaderLength', c_uint16),
> > + ('Checksum', c_uint16),
> > + ('ExtHeaderOffset', c_uint16),
> > + ('Reserved', c_uint8),
> > + ('Revision', c_uint8),
> > + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, 1)),
> > + ]
> > +
> > +def Refine_FV_Header(nums):
> > + class EFI_FIRMWARE_VOLUME_HEADER(Structure):
> > + _fields_ = [
> > + ('ZeroVector', ARRAY(c_uint8, 16)),
> > + ('FileSystemGuid', GUID),
> > + ('FvLength', c_uint64),
> > + ('Signature', c_uint32),
> > + ('Attributes', c_uint32),
> > + ('HeaderLength', c_uint16),
> > + ('Checksum', c_uint16),
> > + ('ExtHeaderOffset', c_uint16),
> > + ('Reserved', c_uint8),
> > + ('Revision', c_uint8),
> > + ('BlockMap', ARRAY(EFI_FV_BLOCK_MAP_ENTRY, nums)),
> > + ]
> > + return EFI_FIRMWARE_VOLUME_HEADER
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
> > + _fields_ = [
> > + ('FvName', GUID),
> > + ('ExtHeaderSize', c_uint32)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY(Structure):
> > + _fields_ = [
> > + ('ExtEntrySize', c_uint16),
> > + ('ExtEntryType', c_uint16)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE_0(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32),
> > + ('Types', ARRAY(GUID, 1))
> > + ]
> > +
> > +def Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums: int) ->
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE:
> > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('TypeMask', c_uint32),
> > + ('Types', ARRAY(GUID, nums))
> > + ]
> > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE(Structure)
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_0(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID)
> > + ]
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID),
> > + ('Data', ARRAY(c_uint8, 1))
> > + ]
> > +
> > +def Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums: int) ->
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE:
> > + class EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('FormatType', GUID),
> > + ('Data', ARRAY(c_uint8, nums))
> > + ]
> > + return EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE(Structure)
> > +
> > +class EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE(Structure):
> > + _fields_ = [
> > + ('Hdr', EFI_FIRMWARE_VOLUME_EXT_ENTRY),
> > + ('UsedSize', c_uint32)
> > + ]
> > diff --git a/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > new file mode 100644
> > index 000000000000..8c6229819a18
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/SectionHeader.py
> > @@ -0,0 +1,110 @@
> > +## @file
> > +# This file is used to define the Section Header C Struct.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from struct import *
> > +from ctypes import *
> > +from PI.Common import *
> > +
> > +EFI_COMMON_SECTION_HEADER_LEN = 4
> > +EFI_COMMON_SECTION_HEADER2_LEN = 8
> > +
> > +class EFI_COMMON_SECTION_HEADER(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('Type', c_uint8),
> > + ]
> > +
> > + @property
> > + def SECTION_SIZE(self) -> int:
> > + return self.Size[0] | self.Size[1] << 8 | self.Size[2] << 16
> > +
> > + def Common_Header_Size(self) -> int:
> > + return 4
> > +
> > +class EFI_COMMON_SECTION_HEADER2(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('Size', ARRAY(c_uint8, 3)),
> > + ('Type', c_uint8),
> > + ('ExtendedSize', c_uint32),
> > + ]
> > +
> > + @property
> > + def SECTION_SIZE(self) -> int:
> > + return self.ExtendedSize
> > +
> > + def Common_Header_Size(self) -> int:
> > + return 8
> > +
> > +class EFI_COMPRESSION_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('UncompressedLength', c_uint32),
> > + ('CompressionType', c_uint8),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 5
> > +
> > +class EFI_FREEFORM_SUBTYPE_GUID_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('SubTypeGuid', GUID),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 16
> > +
> > +class EFI_GUID_DEFINED_SECTION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('SectionDefinitionGuid', GUID),
> > + ('DataOffset', c_uint16),
> > + ('Attributes', c_uint16),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 20
> > +
> > +def Get_USER_INTERFACE_Header(nums: int):
> > + class EFI_SECTION_USER_INTERFACE(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('FileNameString', ARRAY(c_uint16, nums)),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 2 * nums
> > +
> > + def GetUiString(self) -> str:
> > + UiString = ''
> > + for i in range(nums):
> > + if self.FileNameString[i]:
> > + UiString += chr(self.FileNameString[i])
> > + return UiString
> > +
> > + return EFI_SECTION_USER_INTERFACE
> > +
> > +def Get_VERSION_Header(nums: int):
> > + class EFI_SECTION_VERSION(Structure):
> > + _pack_ = 1
> > + _fields_ = [
> > + ('BuildNumber', c_uint16),
> > + ('VersionString', ARRAY(c_uint16, nums)),
> > + ]
> > +
> > + def ExtHeaderSize(self) -> int:
> > + return 2 * (nums+1)
> > +
> > + def GetVersionString(self) -> str:
> > + VersionString = ''
> > + for i in range(nums):
> > + if self.VersionString[i]:
> > + VersionString += chr(self.VersionString[i])
> > + return VersionString
> > +
> > + return EFI_SECTION_VERSION
> > diff --git a/BaseTools/Source/Python/FMMT/PI/__init__.py
> b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > new file mode 100644
> > index 000000000000..21cbd82effc5
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/PI/__init__.py
> > @@ -0,0 +1,6 @@
> > +## @file
> > +# This file is used to define the FMMT dependent external tool
> management class.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/README.md
> b/BaseTools/Source/Python/FMMT/README.md
> > new file mode 100644
> > index 000000000000..cfbc966a6af6
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/README.md
> > @@ -0,0 +1,180 @@
> > +# FMMT
> > +## Overview
> > +This FMMT tool is the python implementation of the edk2 FMMT tool
> which locates at https://github.com/tianocore/edk2-
> > staging/tree/FceFmmt.
> > +This implementation has the same usage as the edk2 FMMT, but it's more
> readable and relaiable.
> > +
> > +# FMMT User Guide
> > +
> > +#### Last updated October 13, 2021
> > +
> > +Important Changes and Updates:
> > +
> > +- Oct 13, 2021 Initial Draft of FMMT Python Tool
> > +
> > +#### Note:
> > +
> > +- FMMT Python Tool keeps same function with origin FMMT C Tool. It is
> much easier to maintain and extend other functions.
> > +
> > +
> > +
> > +# 1. Introduction
> > +
> > +## 1.1 Overview
> > +
> > +The Firmware Device is a persistent physical repository that contains
> firmware code and/or data. The firmware code and/or
> > data stored in Firmware Volumes. Detail layout of Firmware Volumes is
> described in “Figure 1. The Firmware Volume Format”.
> > +
> > +![](Img/FirmwareVolumeFormat.png)
> > +
> > +
> Figure 1. The Firmware
> > Volume Format
> > +
> > +In firmware development, binary file has its firmware layout following the
> Platform-Initialization Specification. Thus,
> > operation on FV file / FFS file (Firmware File) is an efficient and convenient
> way for firmware function testing and
> > developing. FMMT Python tool is used for firmware files operation.
> > +
> > +## 1.2 Tool Capabilities
> > +
> > +The FMMT tool is capable of:
> > +
> > +- Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware
> Files)
> > +
> > +- Add a new FFS into a FV file (both included in a FD file or not)
> > +
> > +- Replace an FFS in a FV file with a new FFS file
> > +
> > +- Delete an FFS in a FV file (both included in a FD file or not)
> > +
> > +- Extract the FFS from a FV file (both included in a FD file or not)
> > +
> > +## 1.3 References
> > +
> > +| Document |
> > +| ------------------------------------------------ |
> > +| UEFI Platform Initialization (PI) Specification |
> > +
> > +
> > +
> > +# 2. FMMT Python Tool Usage
> > +
> > +## 2.1 Required Files
> > +
> > +### 2.1.1 Independent use
> > +
> > +When independent use the FMMT Python Tool, the following files and
> settings are required:
> > +
> > +- GuidTool executable files used for Decompress/Compress Firmware
> data.
> > +
> > +- Environment variables path with GuidTool path setting.
> > +
> > +### 2.1.2 Use with Build System
> > +
> > +When use the FMMT Python Tool with Build System:
> > +
> > +- If only use Edk2 based GuidTool, do not need other preparation.
> > +
> > +- If use other customized GuidTool, need prepare the config file with
> GuidTool info. The syntax for GuidTool definition
> > shown as follow:
> > +
> > + ***ToolsGuid ShortName Command***
> > +
> > + -- Example: ***3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI
> BrotliCompress***
> > +
> > +## 2.2 Syntax
> > +
> > +### 2.2.1 Syntax for Parse file
> > +
> > + ***-v < Inputfile > < Outputfile > -l < LogFileType >***
> > +
> > +- Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is
> optional, if inputs, the *Inputfile* will be
> > encapsulated into *Outputfile* following the parsed firmware layout. *"-l
> LogFileType"* is optional, it decides the format
> > of log file which saves Binary layout. Currently supports: json, txt. More
> formats will be added in the future.
> > +
> > +### 2.2.2 Syntax for Add a new FFS
> > +
> > + ***-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile >
> < Outputfile >***
> > +
> > +- Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid*
> (Name or Guid) is the TargetFv which *NewFfsFile*
> > will be added into.
> > +
> > +### 2.2.3 Syntax for Delete an FFS
> > +
> > + ***-d < Inputfile > < TargetFfsName > < Outputfile > <
> TargetFvName/TargetFvGuid >***
> > +
> > +- Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs
> which will be deleted.
> > *TargetFvName/TargetFvGuid* is optional, which is the parent of
> TargetFfs*.*
> > +
> > +### 2.2.4 Syntax for Replace an FFS
> > +
> > + ***-r < Inputfile > < TargetFfsName > < NewFfsFile > < Outputfile >
> < TargetFvName/TargetFvGuid >***
> > +
> > +- Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the
> TargetFfs which will be replaced.
> > *TargetFvName/TargetFvGuid* is optional, which is the parent of
> TargetFfs*.*
> > +
> > +### 2.2.5 Syntax for Extract an FFS
> > +
> > + ***-e < Inputfile > < TargetFfsName > < Outputfile >***
> > +
> > +- Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs
> which will be extracted.
> > +
> > +
> > +
> > +# 3. FMMT Python Tool Design
> > +
> > +FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each
> Node have its Data field, which saves the
> > FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the
> parse/add/delete/replace/extract operations are based on the
> > NodeTree (adjusting the layout and data).
> > +
> > +## 3.1 NodeTree
> > +
> > +A whole NodeTree saves all the Firmware info.
> > +
> > +- Parent & Child relationship figured out the Firmware layout.
> > +
> > +- Each Node have several fields. ‘Data’ field saves an FirmwareClass
> instance which contains all the data info of the
> > info.
> > +
> > +### 3.1.1 NodeTree Format
> > +
> > +The NodeTree will be created with parse function. When parse a file, a
> Root Node will be initialized firstly. The Data
> > split and Tree construction process is described with an FD file shown as
> ‘Figure 2. The NodeTree format’:
> > +
> > +- A Root Node is initialized.
> > +
> > +- Use the ‘FV Signature’ as FV key to split Whole FD Data. ‘FV0’, ‘FV1’,
> ‘FV2’… Node created.
> > +
> > +- After FV level Node created, use the ‘Ffs Data Size’ as FFS key to split
> each FV Data. ‘Ffs0’...Node created.
> > +
> > +- After FFS level Node created, use the ‘Section Data Size’ as Section key
> to split each Ffs Data. ‘Section0’...Node
> > created.
> > +
> > +- If some of Section includes other Sections, continue use the ‘Section
> Data Size’ as Section key to split each Section
> > Data.
> > +
> > +- After all Node created, the whole NodeTree saves all the info. (Can be
> used in other functions or print the whole
> > firmware layout into log file)
> > +
> > +![](Img/NodeTreeFormat.png)
> > +
> > +
> > Figure 2. The NodeTree format
> > +
> > +### 3.1.2 Node Factory and Product
> > +
> > +As 3.1.1, Each Node is created by data split and recognition. To extend the
> NodeTree usage, Factory pattern is used in
> > Node created process.
> > +
> > +Each Node have its Factory to create Product and use Product ParserData
> function to deal with the data.
> > +
> > +## 3.2 GuidTool
> > +
> > +There are two ways to set the GuidTool. One from Config file, another
> from environment variables.
> > +
> > +Current GuidTool first check if has Config file.
> > +
> > +- If have, load the config GuidTool Information.
> > +
> > +- Else get from environment variables.
> > +
> > +### 3.2.1 Get from Config file
> > +
> > +- Config file should in same folder with FMMT.py or the path in
> environment variables.
> > +
> > +- Content should follow the format:
> > +
> > + ***ToolsGuid ShortName Command***
> > +
> > +### 3.2.2 Get from Environment Variables
> > +
> > +- The GuidTool Command used must be set in environment variables.
> > +
> > +### 3.2.3 Edk2 Based GuidTool
> > +
> > +| ***Guid*** | ***ShortName*** | ***Command***
> |
> > +| ------------------------------------------ | --------------- | --------------------- |
> > +| ***a31280ad-481e-41b6-95e8-127f4c984779*** | ***TIANO*** |
> ***TianoCompress*** |
> > +| ***ee4e5898-3914-4259-9d6e-dc7bd79403cf*** | ***LZMA*** |
> ***LzmaCompress*** |
> > +| ***fc1bcdb0-7d31-49aa-936a-a4600d9dd083*** | ***CRC32*** |
> ***GenCrc32*** |
> > +| ***d42ae6bd-1352-4bfb-909a-ca72a6eae889*** | ***LZMAF86*** |
> ***LzmaF86Compress*** |
> > +| ***3d532050-5cda-4fd0-879e-0f7f630d5afb*** | ***BROTLI*** |
> ***BrotliCompress*** |
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/__init__.py
> b/BaseTools/Source/Python/FMMT/__init__.py
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > new file mode 100644
> > index 000000000000..afc0a90bd0cd
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
> > @@ -0,0 +1,371 @@
> > +## @file
> > +# This file is used to implement of the various bianry parser.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from re import T
> > +import copy
> > +import os
> > +from PI.Common import *
> > +from core.BiosTreeNode import *
> > +from core.BiosTree import *
> > +from core.GuidTools import *
> > +
> > +ROOT_TREE = 'ROOT'
> > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > +
> > +FV_TREE = 'FV'
> > +DATA_FV_TREE = 'DATA_FV'
> > +FFS_TREE = 'FFS'
> > +FFS_PAD = 'FFS_PAD'
> > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > +SECTION_TREE = 'SECTION'
> > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > +BINARY_DATA = 'BINARY'
> > +Fv_count = 0
> > +
> > +## Abstract factory
> > +class BinaryFactory():
> > + type:list = []
> > +
> > + def Create_Product():
> > + pass
> > +
> > +class BinaryProduct():
> > + ## Use GuidTool to decompress data.
> > + def DeCompressData(self, GuidTool, Section_Data: bytes) -> bytes:
> > + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"
> ..")
> > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > + DecompressedData = guidtool.unpack(Section_Data)
> > + return DecompressedData
> > +
> > + def ParserData():
> > + pass
> > +
> > +class SectionFactory(BinaryFactory):
> > + type = [SECTION_TREE]
> > +
> > + def Create_Product():
> > + return SectionProduct()
> > +
> > +class FfsFactory(BinaryFactory):
> > + type = [ROOT_SECTION_TREE, FFS_TREE]
> > +
> > + def Create_Product():
> > + return FfsProduct()
> > +
> > +class FvFactory(BinaryFactory):
> > + type = [ROOT_FFS_TREE, FV_TREE, SEC_FV_TREE]
> > +
> > + def Create_Product():
> > + return FvProduct()
> > +
> > +class FdFactory(BinaryFactory):
> > + type = [ROOT_FV_TREE, ROOT_TREE]
> > +
> > + def Create_Product():
> > + return FdProduct()
> > +
> > +class SectionProduct(BinaryProduct):
> > + ## Decompress the compressed section.
> > + def ParserData(self, Section_Tree, whole_Data: bytes,
> Rel_Whole_Offset: int=0) -> None:
> > + if Section_Tree.Data.Type == 0x01:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + self.ParserFfs(Section_Tree, b'')
> > + # Guided Define Section
> > + elif Section_Tree.Data.Type == 0x02:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + DeCompressGuidTool =
> Section_Tree.Data.ExtHeader.SectionDefinitionGuid
> > + Section_Tree.Data.Data =
> self.DeCompressData(DeCompressGuidTool, Section_Tree.Data.Data)
> > + Section_Tree.Data.Size = len(Section_Tree.Data.Data) +
> Section_Tree.Data.HeaderLength
> > + self.ParserFfs(Section_Tree, b'')
> > + elif Section_Tree.Data.Type == 0x03:
> > + Section_Tree.Data.OriData = Section_Tree.Data.Data
> > + self.ParserFfs(Section_Tree, b'')
> > + # SEC_FV Section
> > + elif Section_Tree.Data.Type == 0x17:
> > + global Fv_count
> > + Sec_Fv_Info = FvNode(Fv_count, Section_Tree.Data.Data)
> > + Sec_Fv_Tree = BIOSTREE('FV'+ str(Fv_count))
> > + Sec_Fv_Tree.type = SEC_FV_TREE
> > + Sec_Fv_Tree.Data = Sec_Fv_Info
> > + Sec_Fv_Tree.Data.HOffset = Section_Tree.Data.DOffset
> > + Sec_Fv_Tree.Data.DOffset = Sec_Fv_Tree.Data.HOffset +
> Sec_Fv_Tree.Data.Header.HeaderLength
> > + Sec_Fv_Tree.Data.Data =
> Section_Tree.Data.Data[Sec_Fv_Tree.Data.Header.HeaderLength:]
> > + Section_Tree.insertChild(Sec_Fv_Tree)
> > + Fv_count += 1
> > +
> > + def ParserFfs(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> > + Rel_Offset = 0
> > + Section_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get it
> from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Section_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Section recorded in its Parent
> Section.
> > + while Rel_Offset < Data_Size:
> > + # Create a SectionNode and set it as the SectionTree's Data
> > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > + Section_Tree = BIOSTREE(Section_Info.Name)
> > + Section_Tree.type = SECTION_TREE
> > + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> Rel_Offset+Section_Info.Size]
> > + Section_Info.DOffset = Section_Offset +
> Section_Info.HeaderLength + Rel_Whole_Offset
> > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> > + Section_Info.ROffset = Rel_Offset
> > + if Section_Info.Header.Type == 0:
> > + break
> > + # The final Section in parent Section does not need to add padding,
> else must be 4-bytes align with parent
> > Section start offset
> > + Pad_Size = 0
> > + if
> (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> Data_Size):
> > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > + Section_Info.PadData = Pad_Size * b'\x00'
> > + if Section_Info.Header.Type == 0x02:
> > + Section_Info.DOffset = Section_Offset +
> Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > Rel_Offset+Section_Info.Size]
> > + if Section_Info.Header.Type == 0x14:
> > + ParTree.Data.Version =
> Section_Info.ExtHeader.GetVersionString()
> > + if Section_Info.Header.Type == 0x15:
> > + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
> > + Section_Offset += Section_Info.Size + Pad_Size
> > + Rel_Offset += Section_Info.Size + Pad_Size
> > + Section_Tree.Data = Section_Info
> > + ParTree.insertChild(Section_Tree)
> > +
> > +class FfsProduct(BinaryProduct):
> > + # ParserFFs / GetSection
> > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> > + Rel_Offset = 0
> > + Section_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get it
> from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Section_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Section recorded in Ffs.
> > + while Rel_Offset < Data_Size:
> > + # Create a SectionNode and set it as the SectionTree's Data
> > + Section_Info = SectionNode(Whole_Data[Rel_Offset:])
> > + Section_Tree = BIOSTREE(Section_Info.Name)
> > + Section_Tree.type = SECTION_TREE
> > + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.HeaderLength:
> Rel_Offset+Section_Info.Size]
> > + Section_Info.DOffset = Section_Offset +
> Section_Info.HeaderLength + Rel_Whole_Offset
> > + Section_Info.HOffset = Section_Offset + Rel_Whole_Offset
> > + Section_Info.ROffset = Rel_Offset
> > + if Section_Info.Header.Type == 0:
> > + break
> > + # The final Section in Ffs does not need to add padding, else must
> be 4-bytes align with Ffs start offset
> > + Pad_Size = 0
> > + if
> (Rel_Offset+Section_Info.HeaderLength+len(Section_Info.Data) !=
> Data_Size):
> > + Pad_Size = GetPadSize(Section_Info.Size, 4)
> > + Section_Info.PadData = Pad_Size * b'\x00'
> > + if Section_Info.Header.Type == 0x02:
> > + Section_Info.DOffset = Section_Offset +
> Section_Info.ExtHeader.DataOffset + Rel_Whole_Offset
> > + Section_Info.Data =
> Whole_Data[Rel_Offset+Section_Info.ExtHeader.DataOffset:
> > Rel_Offset+Section_Info.Size]
> > + # If Section is Version or UI type, it saves the version and UI info of
> its parent Ffs.
> > + if Section_Info.Header.Type == 0x14:
> > + ParTree.Data.Version =
> Section_Info.ExtHeader.GetVersionString()
> > + if Section_Info.Header.Type == 0x15:
> > + ParTree.Data.UiName = Section_Info.ExtHeader.GetUiString()
> > + Section_Offset += Section_Info.Size + Pad_Size
> > + Rel_Offset += Section_Info.Size + Pad_Size
> > + Section_Tree.Data = Section_Info
> > + ParTree.insertChild(Section_Tree)
> > +
> > +class FvProduct(BinaryProduct):
> > + ## ParserFv / GetFfs
> > + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset:
> int=0) -> None:
> > + Ffs_Offset = 0
> > + Rel_Offset = 0
> > + # Get the Data from parent tree, if do not have the tree then get it
> from the whole_data.
> > + if ParTree.Data != None:
> > + Data_Size = len(ParTree.Data.Data)
> > + Ffs_Offset = ParTree.Data.DOffset
> > + Whole_Data = ParTree.Data.Data
> > + else:
> > + Data_Size = len(Whole_Data)
> > + # Parser all the data to collect all the Ffs recorded in Fv.
> > + while Rel_Offset < Data_Size:
> > + # Create a FfsNode and set it as the FFsTree's Data
> > + if Data_Size - Rel_Offset < 24:
> > + Ffs_Tree = BIOSTREE('Free_Space')
> > + Ffs_Tree.type = FFS_FREE_SPACE
> > + Ffs_Tree.Data = FreeSpaceNode(Whole_Data[Rel_Offset:])
> > + Ffs_Tree.Data.HOffset = Ffs_Offset + Rel_Whole_Offset
> > + Ffs_Tree.Data.DOffset = Ffs_Tree.Data.HOffset
> > + ParTree.Data.Free_Space = Data_Size - Rel_Offset
> > + ParTree.insertChild(Ffs_Tree)
> > + Rel_Offset = Data_Size
> > + else:
> > + Ffs_Info = FfsNode(Whole_Data[Rel_Offset:])
> > + Ffs_Tree = BIOSTREE(Ffs_Info.Name)
> > + Ffs_Info.HOffset = Ffs_Offset + Rel_Whole_Offset
> > + Ffs_Info.DOffset = Ffs_Offset + Ffs_Info.Header.HeaderLength +
> Rel_Whole_Offset
> > + Ffs_Info.ROffset = Rel_Offset
> > + if Ffs_Info.Name == PADVECTOR:
> > + Ffs_Tree.type = FFS_PAD
> > + Ffs_Info.Data =
> Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> Rel_Offset+Ffs_Info.Size]
> > + Ffs_Info.Size = len(Ffs_Info.Data) +
> Ffs_Info.Header.HeaderLength
> > + # if current Ffs is the final ffs of Fv and full of b'\xff', define it
> with Free_Space
> > + if struct2stream(Ffs_Info.Header).replace(b'\xff', b'') == b'':
> > + Ffs_Tree.type = FFS_FREE_SPACE
> > + Ffs_Info.Data = Whole_Data[Rel_Offset:]
> > + Ffs_Info.Size = len(Ffs_Info.Data)
> > + ParTree.Data.Free_Space = Ffs_Info.Size
> > + else:
> > + Ffs_Tree.type = FFS_TREE
> > + Ffs_Info.Data =
> Whole_Data[Rel_Offset+Ffs_Info.Header.HeaderLength:
> Rel_Offset+Ffs_Info.Size]
> > + # The final Ffs in Fv does not need to add padding, else must be 8-
> bytes align with Fv start offset
> > + Pad_Size = 0
> > + if Ffs_Tree.type != FFS_FREE_SPACE and
> (Rel_Offset+Ffs_Info.Header.HeaderLength+len(Ffs_Info.Data) !=
> > Data_Size):
> > + Pad_Size = GetPadSize(Ffs_Info.Size, 8)
> > + Ffs_Info.PadData = Pad_Size * b'\xff'
> > + Ffs_Offset += Ffs_Info.Size + Pad_Size
> > + Rel_Offset += Ffs_Info.Size + Pad_Size
> > + Ffs_Tree.Data = Ffs_Info
> > + ParTree.insertChild(Ffs_Tree)
> > +
> > +class FdProduct(BinaryProduct):
> > + type = [ROOT_FV_TREE, ROOT_TREE]
> > +
> > + ## Create DataTree with first level /fv Info, then parser each Fv.
> > + def ParserData(self, WholeFvTree, whole_data: bytes=b'', offset: int=0)
> -> None:
> > + # Get all Fv image in Fd with offset and length
> > + Fd_Struct = self.GetFvFromFd(whole_data)
> > + data_size = len(whole_data)
> > + Binary_count = 0
> > + global Fv_count
> > + # If the first Fv image is the Binary Fv, add it into the tree.
> > + if Fd_Struct[0][1] != 0:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data = whole_data[:Fd_Struct[0][1]]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset = 0 + offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > + # Add the first collected Fv image into the tree.
> > + Cur_node = BIOSTREE(Fd_Struct[0][0]+ str(Fv_count))
> > + Cur_node.type = Fd_Struct[0][0]
> > + Cur_node.Data = FvNode(Fv_count,
> whole_data[Fd_Struct[0][1]:Fd_Struct[0][1]+Fd_Struct[0][2][0]])
> > + Cur_node.Data.HOffset = Fd_Struct[0][1] + offset
> > + Cur_node.Data.DOffset =
> Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > + Cur_node.Data.Data =
> >
> whole_data[Fd_Struct[0][1]+Cur_node.Data.Header.HeaderLength:Fd_Struc
> t[0][1]+Cur_node.Data.Size]
> > + WholeFvTree.insertChild(Cur_node)
> > + Fv_count += 1
> > + Fv_num = len(Fd_Struct)
> > + # Add all the collected Fv image and the Binary Fv image between
> them into the tree.
> > + for i in range(Fv_num-1):
> > + if Fd_Struct[i][1]+Fd_Struct[i][2][0] != Fd_Struct[i+1][1]:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data =
> whole_data[Fd_Struct[i][1]+Fd_Struct[i][2][0]:Fd_Struct[i+1][1]]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset = Fd_Struct[i][1]+Fd_Struct[i][2][0] +
> offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > + Cur_node = BIOSTREE(Fd_Struct[i+1][0]+ str(Fv_count))
> > + Cur_node.type = Fd_Struct[i+1][0]
> > + Cur_node.Data = FvNode(Fv_count,
> whole_data[Fd_Struct[i+1][1]:Fd_Struct[i+1][1]+Fd_Struct[i+1][2][0]])
> > + Cur_node.Data.HOffset = Fd_Struct[i+1][1] + offset
> > + Cur_node.Data.DOffset =
> Cur_node.Data.HOffset+Cur_node.Data.Header.HeaderLength
> > + Cur_node.Data.Data =
> >
> whole_data[Fd_Struct[i+1][1]+Cur_node.Data.Header.HeaderLength:Fd_Str
> uct[i+1][1]+Cur_node.Data.Size]
> > + WholeFvTree.insertChild(Cur_node)
> > + Fv_count += 1
> > + # If the final Fv image is the Binary Fv, add it into the tree
> > + if Fd_Struct[-1][1] + Fd_Struct[-1][2][0] != data_size:
> > + Binary_node = BIOSTREE('BINARY'+ str(Binary_count))
> > + Binary_node.type = BINARY_DATA
> > + Binary_node.Data = BinaryNode(str(Binary_count))
> > + Binary_node.Data.Data = whole_data[Fd_Struct[-1][1]+Fd_Struct[-
> 1][2][0]:]
> > + Binary_node.Data.Size = len(Binary_node.Data.Data)
> > + Binary_node.Data.HOffset = Fd_Struct[-1][1]+Fd_Struct[-1][2][0] +
> offset
> > + WholeFvTree.insertChild(Binary_node)
> > + Binary_count += 1
> > +
> > + ## Get the first level Fv from Fd file.
> > + def GetFvFromFd(self, whole_data: bytes=b'') -> list:
> > + Fd_Struct = []
> > + data_size = len(whole_data)
> > + cur_index = 0
> > + # Get all the EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE FV image
> offset and length.
> > + while cur_index < data_size:
> > + if EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE in
> whole_data[cur_index:]:
> > + target_index =
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE)
> + cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-
> > 16:target_index] == ZEROVECTOR_BYTE:
> > + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q",
> > whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + cur_index = 0
> > + # Get all the EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE FV image
> offset and length.
> > + while cur_index < data_size:
> > + if EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE in
> whole_data[cur_index:]:
> > + target_index =
> whole_data[cur_index:].index(EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE)
> + cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-
> > 16:target_index] == ZEROVECTOR_BYTE:
> > + Fd_Struct.append([FV_TREE, target_index - 16, unpack("Q",
> > whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + cur_index = 0
> > + # Get all the EFI_SYSTEM_NVDATA_FV_GUID_BYTE FV image offset
> and length.
> > + while cur_index < data_size:
> > + if EFI_SYSTEM_NVDATA_FV_GUID_BYTE in whole_data[cur_index:]:
> > + target_index =
> whole_data[cur_index:].index(EFI_SYSTEM_NVDATA_FV_GUID_BYTE) +
> cur_index
> > + if whole_data[target_index+24:target_index+28] ==
> FVH_SIGNATURE and whole_data[target_index-
> > 16:target_index] == ZEROVECTOR_BYTE:
> > + Fd_Struct.append([DATA_FV_TREE, target_index - 16,
> unpack("Q",
> > whole_data[target_index+16:target_index+24])])
> > + cur_index = Fd_Struct[-1][1] + Fd_Struct[-1][2][0]
> > + else:
> > + cur_index = target_index + 16
> > + else:
> > + cur_index = data_size
> > + # Sort all the collect Fv image with offset.
> > + Fd_Struct.sort(key=lambda x:x[1])
> > + tmp_struct = copy.deepcopy(Fd_Struct)
> > + tmp_index = 0
> > + Fv_num = len(Fd_Struct)
> > + # Remove the Fv image included in another Fv image.
> > + for i in range(1,Fv_num):
> > + if tmp_struct[i][1]+tmp_struct[i][2][0] < tmp_struct[i-
> 1][1]+tmp_struct[i-1][2][0]:
> > + Fd_Struct.remove(Fd_Struct[i-tmp_index])
> > + tmp_index += 1
> > + return Fd_Struct
> > +
> > +class ParserEntry():
> > + FactoryTable:dict = {
> > + SECTION_TREE: SectionFactory,
> > + ROOT_SECTION_TREE: FfsFactory,
> > + FFS_TREE: FfsFactory,
> > + ROOT_FFS_TREE: FvFactory,
> > + FV_TREE: FvFactory,
> > + SEC_FV_TREE: FvFactory,
> > + ROOT_FV_TREE: FdFactory,
> > + ROOT_TREE: FdFactory,
> > + }
> > +
> > + def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
> > + if Tree_type in self.FactoryTable:
> > + return self.FactoryTable[Tree_type]
> > +
> > + def Generate_Product(self, TargetFactory: BinaryFactory, Tree, Data:
> bytes, Offset: int) -> None:
> > + New_Product = TargetFactory.Create_Product()
> > + New_Product.ParserData(Tree, Data, Offset)
> > +
> > + def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
> > + TargetFactory = self.GetTargetFactory(Tree.type)
> > + if TargetFactory:
> > + self.Generate_Product(TargetFactory, Tree, Data, Offset)
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py
> b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > new file mode 100644
> > index 000000000000..b2cdb49f9f3f
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
> > @@ -0,0 +1,199 @@
> > +## @file
> > +# This file is used to define the Bios layout tree structure and related
> operations.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import collections
> > +from typing import OrderedDict
> > +from PI.Common import *
> > +
> > +ROOT_TREE = 'ROOT'
> > +ROOT_FV_TREE = 'ROOT_FV_TREE'
> > +ROOT_FFS_TREE = 'ROOT_FFS_TREE'
> > +ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
> > +
> > +FV_TREE = 'FV'
> > +DATA_FV_TREE = 'DATA_FV'
> > +FFS_TREE = 'FFS'
> > +FFS_PAD = 'FFS_PAD'
> > +FFS_FREE_SPACE = 'FFS_FREE_SPACE'
> > +SECTION_TREE = 'SECTION'
> > +SEC_FV_TREE = 'SEC_FV_IMAGE'
> > +BINARY_DATA = 'BINARY'
> > +
> > +RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE,
> ROOT_SECTION_TREE]
> > +FvType = [FV_TREE, SEC_FV_TREE]
> > +FfsType = FFS_TREE
> > +SecType = SECTION_TREE
> > +
> > +class BIOSTREE:
> > + def __init__(self, NodeName: str) -> None:
> > + self.key = NodeName
> > + self.type = None
> > + self.Data = None
> > + self.Child = []
> > + self.Findlist = []
> > + self.Parent = None
> > + self.NextRel = None
> > + self.LastRel = None
> > +
> > + def HasChild(self) -> bool:
> > + if self.Child == []:
> > + return False
> > + else:
> > + return True
> > +
> > + def isFinalChild(self) -> bool:
> > + ParTree = self.Parent
> > + if ParTree:
> > + if ParTree.Child[-1] == self:
> > + return True
> > + return False
> > +
> > + # FvTree.insertChild()
> > + def insertChild(self, newNode, pos: int=None) -> None:
> > + if len(self.Child) == 0:
> > + self.Child.append(newNode)
> > + else:
> > + if not pos:
> > + LastTree = self.Child[-1]
> > + self.Child.append(newNode)
> > + LastTree.NextRel = newNode
> > + newNode.LastRel = LastTree
> > + else:
> > + newNode.NextRel = self.Child[pos-1].NextRel
> > + newNode.LastRel = self.Child[pos].LastRel
> > + self.Child[pos-1].NextRel = newNode
> > + self.Child[pos].LastRel = newNode
> > + self.Child.insert(pos, newNode)
> > + newNode.Parent = self
> > +
> > + # lastNode.insertRel(newNode)
> > + def insertRel(self, newNode) -> None:
> > + if self.Parent:
> > + parentTree = self.Parent
> > + new_index = parentTree.Child.index(self) + 1
> > + parentTree.Child.insert(new_index, newNode)
> > + self.NextRel = newNode
> > + newNode.LastRel = self
> > +
> > + def deleteNode(self, deletekey: str) -> None:
> > + FindStatus, DeleteTree = self.FindNode(deletekey)
> > + if FindStatus:
> > + parentTree = DeleteTree.Parent
> > + lastTree = DeleteTree.LastRel
> > + nextTree = DeleteTree.NextRel
> > + if parentTree:
> > + index = parentTree.Child.index(DeleteTree)
> > + del parentTree.Child[index]
> > + if lastTree and nextTree:
> > + lastTree.NextRel = nextTree
> > + nextTree.LastRel = lastTree
> > + elif lastTree:
> > + lastTree.NextRel = None
> > + elif nextTree:
> > + nextTree.LastRel = None
> > + return DeleteTree
> > + else:
> > + print('Could not find the target tree')
> > + return None
> > +
> > + def FindNode(self, key: str, Findlist: list) -> None:
> > + if self.key == key or (self.Data and self.Data.Name == key) or
> (self.type == FFS_TREE and self.Data.UiName ==
> > key):
> > + Findlist.append(self)
> > + else:
> > + for item in self.Child:
> > + item.FindNode(key, Findlist)
> > +
> > + def GetTreePath(self):
> > + BiosTreePath = [self]
> > + while self.Parent:
> > + BiosTreePath.insert(0, self.Parent)
> > + self = self.Parent
> > + return BiosTreePath
> > +
> > + def parserTree(self, TargetDict: dict=None, Info: list=None, space: int=0)
> -> None:
> > + Key = list(TargetDict.keys())[0]
> > + if TargetDict[Key]["Type"] in RootType:
> > + Info.append("Image File: {}".format(Key))
> > + Info.append("FilesNum:
> {}".format(TargetDict.get(Key).get('FilesNum')))
> > + Info.append("\n")
> > + elif TargetDict[Key]["Type"] in FvType:
> > + space += 2
> > + if TargetDict[Key]["Type"] == SEC_FV_TREE:
> > + Info.append("{}Child FV named {} of {}".format(space*" ", Key,
> self.FvId))
> > + space += 2
> > + else:
> > + Info.append("FvId: {}".format(Key))
> > + self.FvId = Key
> > + Info.append("{}FvNameGuid: {}".format(space*" ",
> TargetDict.get(Key).get('FvNameGuid')))
> > + Info.append("{}Attributes: {}".format(space*" ",
> TargetDict.get(Key).get('Attributes')))
> > + Info.append("{}Total Volume Size: {}".format(space*" ",
> TargetDict.get(Key).get('Size')))
> > + Info.append("{}Free Volume Size: {}".format(space*" ",
> TargetDict.get(Key).get('FreeSize')))
> > + Info.append("{}Volume Offset: {}".format(space*" ",
> TargetDict.get(Key).get('Offset')))
> > + Info.append("{}FilesNum: {}".format(space*" ",
> TargetDict.get(Key).get('FilesNum')))
> > + elif TargetDict[Key]["Type"] in FfsType:
> > + space += 2
> > + if TargetDict.get(Key).get('UiName') != "b''":
> > + Info.append("{}File: {} / {}".format(space*" ", Key,
> TargetDict.get(Key).get('UiName')))
> > + else:
> > + Info.append("{}File: {}".format(space*" ", Key))
> > + if "Files" in list(TargetDict[Key].keys()):
> > + for item in TargetDict[Key]["Files"]:
> > + self.parserTree(item, Info, space)
> > +
> > + def ExportTree(self,TreeInfo: dict=None) -> dict:
> > + if TreeInfo is None:
> > + TreeInfo =collections.OrderedDict()
> > +
> > + if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type
> == ROOT_FFS_TREE or self.type ==
> > ROOT_SECTION_TREE:
> > + key = str(self.key)
> > + TreeInfo[self.key] = collections.OrderedDict()
> > + TreeInfo[self.key]["Name"] = key
> > + TreeInfo[self.key]["Type"] = self.type
> > + TreeInfo[self.key]["FilesNum"] = len(self.Child)
> > + elif self.type == FV_TREE or self.type == SEC_FV_TREE:
> > + key = str(self.Data.FvId)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + if self.Data.FvId != self.Data.Name:
> > + TreeInfo[key]["FvNameGuid"] = str(self.Data.Name)
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Attributes"] = hex(self.Data.Header.Attributes)
> > + TreeInfo[key]["Size"] = hex(self.Data.Header.FvLength)
> > + TreeInfo[key]["FreeSize"] = hex(self.Data.Free_Space)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self.type == FFS_TREE:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["UiName"] = '{}'.format(self.Data.UiName)
> > + TreeInfo[key]["Version"] = '{}'.format(self.Data.Version)
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self.type == SECTION_TREE and self.Data.Type == 0x02:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(len(self.Data.OriData) +
> self.Data.HeaderLength)
> > + TreeInfo[key]["DecompressedSize"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > + elif self is not None:
> > + key = str(self.Data.Name)
> > + TreeInfo[key] = collections.OrderedDict()
> > + TreeInfo[key]["Name"] = key
> > + TreeInfo[key]["Type"] = self.type
> > + TreeInfo[key]["Size"] = hex(self.Data.Size)
> > + TreeInfo[key]["Offset"] = hex(self.Data.HOffset)
> > + TreeInfo[key]["FilesNum"] = len(self.Child)
> > +
> > + for item in self.Child:
> > + TreeInfo[key].setdefault('Files',[]).append( item.ExportTree())
> > +
> > + return TreeInfo
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > new file mode 100644
> > index 000000000000..b77d9100e7b3
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
> > @@ -0,0 +1,191 @@
> > +## @file
> > +# This file is used to define the BIOS Tree Node.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from PI.FvHeader import *
> > +from PI.FfsFileHeader import *
> > +from PI.SectionHeader import *
> > +from PI.Common import *
> > +import uuid
> > +
> > +SectionHeaderType = {
> > + 0x01:'EFI_COMPRESSION_SECTION',
> > + 0x02:'EFI_GUID_DEFINED_SECTION',
> > + 0x03:'EFI_SECTION_DISPOSABLE',
> > + 0x10:'EFI_SECTION_PE32',
> > + 0x11:'EFI_SECTION_PIC',
> > + 0x12:'EFI_SECTION_TE',
> > + 0x13:'EFI_SECTION_DXE_DEPEX',
> > + 0x14:'EFI_SECTION_VERSION',
> > + 0x15:'EFI_SECTION_USER_INTERFACE',
> > + 0x16:'EFI_SECTION_COMPATIBILITY16',
> > + 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
> > + 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
> > + 0x19:'EFI_SECTION_RAW',
> > + 0x1B:'EFI_SECTION_PEI_DEPEX',
> > + 0x1C:'EFI_SECTION_MM_DEPEX'
> > +}
> > +HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
> > +
> > +class BinaryNode:
> > + def __init__(self, name: str) -> None:
> > + self.Size = 0
> > + self.Name = "BINARY" + str(name)
> > + self.HOffset = 0
> > + self.Data = b''
> > +
> > +class FvNode:
> > + def __init__(self, name, buffer: bytes) -> None:
> > + self.Header =
> EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
> > + Map_num = (self.Header.HeaderLength - 56)//8
> > + self.Header =
> Refine_FV_Header(Map_num).from_buffer_copy(buffer)
> > + self.FvId = "FV" + str(name)
> > + self.Name = "FV" + str(name)
> > + if self.Header.ExtHeaderOffset:
> > + self.ExtHeader =
> EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer_copy(buffer[self.Head
> er.ExtHeaderOffset:])
> > + self.Name =
> uuid.UUID(bytes_le=struct2stream(self.ExtHeader.FvName))
> > + self.ExtEntryOffset = self.Header.ExtHeaderOffset + 20
> > + if self.ExtHeader.ExtHeaderSize != 20:
> > + self.ExtEntryExist = 1
> > + self.ExtEntry =
> EFI_FIRMWARE_VOLUME_EXT_ENTRY.from_buffer_copy(buffer[self.ExtEnt
> ryOffset:])
> > + self.ExtTypeExist = 1
> > + if self.ExtEntry.ExtEntryType == 0x01:
> > + nums = (self.ExtEntry.ExtEntrySize - 8) // 16
> > + self.ExtEntry =
> >
> Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums).from_buffer_copy(buffe
> r[self.ExtEntryOffset:])
> > + elif self.ExtEntry.ExtEntryType == 0x02:
> > + nums = self.ExtEntry.ExtEntrySize - 20
> > + self.ExtEntry =
> >
> Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums).from_buffer_copy(buff
> er[self.ExtEntryOffset:])
> > + elif self.ExtEntry.ExtEntryType == 0x03:
> > + self.ExtEntry =
> >
> EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE.from_buffer_copy(
> buffer[self.ExtEntryOffset:])
> > + else:
> > + self.ExtTypeExist = 0
> > + else:
> > + self.ExtEntryExist = 0
> > + self.Size = self.Header.FvLength
> > + self.HeaderLength = self.Header.HeaderLength
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + if self.Header.Signature != 1213613663:
> > + print('Invalid! Fv Header Signature {} is not
> "_FVH".'.format(self.Header.Signature))
> > + with open(str(self.Name)+'.fd', "wb") as f:
> > + f.write(struct2stream(self.Header))
> > + assert False
> > + self.PadData = b''
> > + self.Free_Space = 0
> > + self.ModCheckSum()
> > +
> > + def ModCheckSum(self) -> None:
> > + # Fv Header Sums to 0.
> > + Header = struct2stream(self.Header)[::-1]
> > + Size = self.HeaderLength // 2
> > + Sum = 0
> > + for i in range(Size):
> > + Sum += int(Header[i*2: i*2 + 2].hex(), 16)
> > + if Sum & 0xffff:
> > + self.Header.Checksum = int(hex(0x10000 - int(hex(Sum -
> self.Header.Checksum)[-4:], 16)), 16)
> > +
> > + def ModFvExt(self) -> None:
> > + # If used space changes and self.ExtEntry.UsedSize exists,
> self.ExtEntry.UsedSize need to be changed.
> > + if self.Header.ExtHeaderOffset and self.ExtEntryExist and
> self.ExtTypeExist and self.ExtEntry.Hdr.ExtEntryType ==
> > 0x03:
> > + self.ExtEntry.UsedSize = self.Header.FvLength - self.Free_Space
> > +
> > + def ModFvSize(self) -> None:
> > + # If Fv Size changed, self.Header.FvLength and
> self.Header.BlockMap[i].NumBlocks need to be changed.
> > + BlockMapNum = len(self.Header.BlockMap)
> > + for i in range(BlockMapNum):
> > + if self.Header.BlockMap[i].Length:
> > + self.Header.BlockMap[i].NumBlocks = self.Header.FvLength //
> self.Header.BlockMap[i].Length
> > +
> > + def ModExtHeaderData(self) -> None:
> > + if self.Header.ExtHeaderOffset:
> > + ExtHeaderData = struct2stream(self.ExtHeader)
> > + ExtHeaderDataOffset = self.Header.ExtHeaderOffset -
> self.HeaderLength
> > + self.Data = self.Data[:ExtHeaderDataOffset] + ExtHeaderData +
> self.Data[ExtHeaderDataOffset+20:]
> > + if self.Header.ExtHeaderOffset and self.ExtEntryExist:
> > + ExtHeaderEntryData = struct2stream(self.ExtEntry)
> > + ExtHeaderEntryDataOffset = self.Header.ExtHeaderOffset + 20 -
> self.HeaderLength
> > + self.Data = self.Data[:ExtHeaderEntryDataOffset] +
> ExtHeaderEntryData +
> > self.Data[ExtHeaderEntryDataOffset+len(ExtHeaderEntryData):]
> > +
> > +class FfsNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + self.Header = EFI_FFS_FILE_HEADER.from_buffer_copy(buffer)
> > + # self.Attributes = unpack("<B", buffer[21:22])[0]
> > + if self.Header.Size != 0 and self.Header.Attributes == 0x01:
> > + print('Error Ffs Header! Ffs Header Size and Attributes is not
> matched!')
> > + if self.Header.Size == 0 and self.Header.Attributes == 0x01:
> > + self.Header = EFI_FFS_FILE_HEADER2.from_buffer_copy(buffer)
> > + self.Name = uuid.UUID(bytes_le=struct2stream(self.Header.Name))
> > + self.UiName = b''
> > + self.Version = b''
> > + self.Size = self.Header.FFS_FILE_SIZE
> > + self.HeaderLength = self.Header.HeaderLength
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + self.PadData = b''
> > +
> > + def ModCheckSum(self) -> None:
> > + HeaderData = struct2stream(self.Header)
> > + HeaderSum = 0
> > + for item in HeaderData:
> > + HeaderSum += item
> > + HeaderSum -= self.Header.State
> > + HeaderSum -= self.Header.IntegrityCheck.Checksum.File
> > + if HeaderSum & 0xff:
> > + Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 -
> int(hex(HeaderSum)[-2:], 16)
> > + self.Header.IntegrityCheck.Checksum.Header = int(hex(Header)[-
> 2:], 16)
> > +
> > +class SectionNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + if buffer[0:3] != b'\xff\xff\xff':
> > + self.Header =
> EFI_COMMON_SECTION_HEADER.from_buffer_copy(buffer)
> > + else:
> > + self.Header =
> EFI_COMMON_SECTION_HEADER2.from_buffer_copy(buffer)
> > + if self.Header.Type in SectionHeaderType:
> > + self.Name = SectionHeaderType[self.Header.Type]
> > + elif self.Header.Type == 0:
> > + self.Name = "EFI_SECTION_RAW"
> > + else:
> > + self.Name = "SECTION"
> > + if self.Header.Type in HeaderType:
> > + self.ExtHeader = self.GetExtHeader(self.Header.Type,
> buffer[self.Header.Common_Header_Size():],
> > (self.Header.SECTION_SIZE-self.Header.Common_Header_Size()))
> > + self.HeaderLength = self.Header.Common_Header_Size() +
> self.ExtHeader.ExtHeaderSize()
> > + else:
> > + self.ExtHeader = None
> > + self.HeaderLength = self.Header.Common_Header_Size()
> > + self.Size = self.Header.SECTION_SIZE
> > + self.Type = self.Header.Type
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.Data = b''
> > + self.OriData = b''
> > + self.OriHeader = b''
> > + self.PadData = b''
> > +
> > + def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None:
> > + if Type == 0x01:
> > + return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
> > + elif Type == 0x02:
> > + return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
> > + elif Type == 0x14:
> > + return Get_VERSION_Header((nums -
> 2)//2).from_buffer_copy(buffer)
> > + elif Type == 0x15:
> > + return
> Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
> > + elif Type == 0x18:
> > + return
> EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
> > +
> > +class FreeSpaceNode:
> > + def __init__(self, buffer: bytes) -> None:
> > + self.Name = 'Free_Space'
> > + self.Data = buffer
> > + self.Size = len(buffer)
> > + self.HOffset = 0
> > + self.DOffset = 0
> > + self.ROffset = 0
> > + self.PadData = b''
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > new file mode 100644
> > index 000000000000..e42565965909
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py
> > @@ -0,0 +1,140 @@
> > +## @file
> > +# This file is used to define the functions to operate bios binary file.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from core.FMMTParser import *
> > +from core.FvHandler import *
> > +from utils.FvLayoutPrint import *
> > +
> > +global Fv_count
> > +Fv_count = 0
> > +
> > +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE',
> 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE'
> > +def ParserFile(inputfile: str, ROOT_TYPE: str, logfile: str=None, outputfile:
> str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TYPE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # 3. Log Output
> > + InfoDict = FmmtParser.WholeFvTree.ExportTree()
> > + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo)
> > + GetFormatter("").LogPrint(FmmtParser.BinaryInfo)
> > + if logfile:
> > + GetFormatter(logfile.lower()).dump(InfoDict,
> >
> FmmtParser.BinaryInfo,"Parser_Log_{}{}".format(os.path.basename(inputfil
> e),".{}".format(logfile.lower())))
> > + # 4. Data Encapsultion
> > + if outputfile:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name:
> str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # 3. Data Modify
> > + FmmtParser.WholeFvTree.FindNode(TargetFfs_name,
> FmmtParser.WholeFvTree.Findlist)
> > + # Choose the Specfic DeleteFfs with Fv info
> > + if Fv_name:
> > + for item in FmmtParser.WholeFvTree.Findlist:
> > + if item.Parent.key != Fv_name and item.Parent.Data.Name !=
> Fv_name:
> > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist:
> > + FfsMod = FvHandler(None, Delete_Ffs)
> > + Status = FfsMod.DeleteFfs()
> > + else:
> > + print('Target Ffs not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str)
> -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + # Get Target Fv and Target Ffs_Pad
> > + FmmtParser.WholeFvTree.FindNode(Fv_name,
> FmmtParser.WholeFvTree.Findlist)
> > + # Create new ffs Tree
> > + with open(newffsfile, "rb") as f:
> > + new_ffs_data = f.read()
> > + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE)
> > + Status = False
> > + # 3. Data Modify
> > + if FmmtParser.WholeFvTree.Findlist:
> > + for TargetFv in FmmtParser.WholeFvTree.Findlist:
> > + TargetFfsPad = TargetFv.Child[-1]
> > + if TargetFfsPad.type == FFS_FREE_SPACE:
> > + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> new_ffs_data, TargetFfsPad.Data.HOffset)
> > + else:
> > + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree,
> new_ffs_data,
> > TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size)
> > + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0],
> TargetFfsPad)
> > + Status = FfsMod.AddFfs()
> > + else:
> > + print('Target Fv not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str,
> Fv_name: str=None) -> None:
> > + # 1. Data Prepare
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + # 2. DataTree Create
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + with open(newffsfile, "rb") as f:
> > + new_ffs_data = f.read()
> > + newFmmtParser = FMMTParser(newffsfile, FV_TREE)
> > + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree,
> new_ffs_data)
> > + Status = False
> > + # 3. Data Modify
> > + new_ffs = newFmmtParser.WholeFvTree.Child[0]
> > + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, 8) * b'\xff'
> > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> FmmtParser.WholeFvTree.Findlist)
> > + if Fv_name:
> > + for item in FmmtParser.WholeFvTree.Findlist:
> > + if item.Parent.key != Fv_name and item.Parent.Data.Name !=
> Fv_name:
> > + FmmtParser.WholeFvTree.Findlist.remove(item)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + for TargetFfs in FmmtParser.WholeFvTree.Findlist:
> > + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0],
> TargetFfs)
> > + Status = FfsMod.ReplaceFfs()
> > + else:
> > + print('Target Ffs not found!!!')
> > + # 4. Data Encapsultion
> > + if Status:
> > + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)
> > + with open(outputfile, "wb") as f:
> > + f.write(FmmtParser.FinalData)
> > +
> > +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str) -> None:
> > + with open(inputfile, "rb") as f:
> > + whole_data = f.read()
> > + FmmtParser = FMMTParser(inputfile, ROOT_TREE)
> > + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)
> > + FmmtParser.WholeFvTree.FindNode(Ffs_name,
> FmmtParser.WholeFvTree.Findlist)
> > + if FmmtParser.WholeFvTree.Findlist != []:
> > + TargetNode = FmmtParser.WholeFvTree.Findlist[0]
> > + TargetFv = TargetNode.Parent
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + TargetNode.Data.Header.State = c_uint8(
> > + ~TargetNode.Data.Header.State)
> > + FinalData = struct2stream(TargetNode.Data.Header) +
> TargetNode.Data.Data
> > + with open(outputfile, "wb") as f:
> > + f.write(FinalData)
> > + else:
> > + print('Target Ffs not found!!!')
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > new file mode 100644
> > index 000000000000..6f35d4dd76cf
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
> > @@ -0,0 +1,86 @@
> > +## @file
> > +# This file is used to define the interface of Bios Parser.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +from PI.Common import *
> > +from core.BinaryFactoryProduct import ParserEntry
> > +from core.BiosTreeNode import *
> > +from core.BiosTree import *
> > +from core.GuidTools import *
> > +
> > +class FMMTParser:
> > + def __init__(self, name: str, TYPE: str) -> None:
> > + self.WholeFvTree = BIOSTREE(name)
> > + self.WholeFvTree.type = TYPE
> > + self.FinalData = b''
> > + self.BinaryInfo = []
> > +
> > + ## Parser the nodes in WholeTree.
> > + def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'',
> Reloffset: int=0) -> None:
> > + if WholeFvTree.type == ROOT_TREE or WholeFvTree.type ==
> ROOT_FV_TREE:
> > + ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset)
> > + else:
> > + ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset)
> > + for Child in WholeFvTree.Child:
> > + self.ParserFromRoot(Child, "")
> > +
> > + ## Encapuslation all the data in tree into self.FinalData
> > + def Encapsulation(self, rootTree, CompressStatus: bool) -> None:
> > + # If current node is Root node, skip it.
> > + if rootTree.type == ROOT_TREE or rootTree.type == ROOT_FV_TREE
> or rootTree.type == ROOT_FFS_TREE or rootTree.type
> > == ROOT_SECTION_TREE:
> > + print('Start at Root !')
> > + # If current node do not have Header, just add Data.
> > + elif rootTree.type == BINARY_DATA or rootTree.type ==
> FFS_FREE_SPACE:
> > + self.FinalData += rootTree.Data.Data
> > + rootTree.Child = []
> > + # If current node do not have Child and ExtHeader, just add its Header
> and Data.
> > + elif rootTree.type == DATA_FV_TREE or rootTree.type == FFS_PAD:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> rootTree.Data.Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + if ParTree.type != 'ROOT':
> > + self.FinalData += ParTree.Data.PadData
> > + rootTree.Child = []
> > + # If current node is not Section node and may have Child and
> ExtHeader, add its Header,ExtHeader. If do not have
> > Child, add its Data.
> > + elif rootTree.type == FV_TREE or rootTree.type == FFS_TREE or
> rootTree.type == SEC_FV_TREE:
> > + if rootTree.HasChild():
> > + self.FinalData += struct2stream(rootTree.Data.Header)
> > + else:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> rootTree.Data.Data + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + if ParTree.type != 'ROOT':
> > + self.FinalData += ParTree.Data.PadData
> > + # If current node is Section, need to consider its ExtHeader, Child and
> Compressed Status.
> > + elif rootTree.type == SECTION_TREE:
> > + # Not compressed section
> > + if rootTree.Data.OriData == b'' or (rootTree.Data.OriData != b'' and
> CompressStatus):
> > + if rootTree.HasChild():
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader)
> > + else:
> > + self.FinalData += struct2stream(rootTree.Data.Header)
> > + else:
> > + Data = rootTree.Data.Data
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader) +
> > Data + rootTree.Data.PadData
> > + else:
> > + self.FinalData += struct2stream(rootTree.Data.Header) + Data
> + rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + self.FinalData += ParTree.Data.PadData
> > + # If compressed section
> > + else:
> > + Data = rootTree.Data.OriData
> > + rootTree.Child = []
> > + if rootTree.Data.ExtHeader:
> > + self.FinalData += struct2stream(rootTree.Data.Header) +
> struct2stream(rootTree.Data.ExtHeader) + Data
> > + rootTree.Data.PadData
> > + else:
> > + self.FinalData += struct2stream(rootTree.Data.Header) + Data +
> rootTree.Data.PadData
> > + if rootTree.isFinalChild():
> > + ParTree = rootTree.Parent
> > + self.FinalData += ParTree.Data.PadData
> > + for Child in rootTree.Child:
> > + self.Encapsulation(Child, CompressStatus)
> > diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py
> b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > new file mode 100644
> > index 000000000000..7809e1598c1e
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
> > @@ -0,0 +1,521 @@
> > +## @file
> > +# This file is used to the implementation of Bios layout handler.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import os
> > +from core.BiosTree import *
> > +from core.GuidTools import GUIDTools
> > +from core.BiosTreeNode import *
> > +from PI.Common import *
> > +
> > +EFI_FVB2_ERASE_POLARITY = 0x00000800
> > +
> > +def ChangeSize(TargetTree, size_delta: int=0) -> None:
> > + if type(TargetTree.Data.Header) == type(EFI_FFS_FILE_HEADER2()) or
> type(TargetTree.Data.Header) ==
> > type(EFI_COMMON_SECTION_HEADER2()):
> > + TargetTree.Data.Size -= size_delta
> > + TargetTree.Data.Header.ExtendedSize -= size_delta
> > + elif TargetTree.type == SECTION_TREE and TargetTree.Data.OriData:
> > + OriSize = TargetTree.Data.Header.SECTION_SIZE
> > + OriSize -= size_delta
> > + TargetTree.Data.Header.Size[0] = OriSize % (16**2)
> > + TargetTree.Data.Header.Size[1] = OriSize % (16**4) //(16**2)
> > + TargetTree.Data.Header.Size[2] = OriSize // (16**4)
> > + else:
> > + TargetTree.Data.Size -= size_delta
> > + TargetTree.Data.Header.Size[0] = TargetTree.Data.Size % (16**2)
> > + TargetTree.Data.Header.Size[1] = TargetTree.Data.Size % (16**4)
> //(16**2)
> > + TargetTree.Data.Header.Size[2] = TargetTree.Data.Size // (16**4)
> > +
> > +def ModifyFfsType(TargetFfs) -> None:
> > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER()) and
> (TargetFfs.Data.HeaderLength + TargetFfs.Data.Size)
> > > 0xFFFFFF:
> > + ExtendSize = TargetFfs.Data.Header.FFS_FILE_SIZE + 8
> > + New_Header = EFI_FFS_FILE_HEADER2()
> > + New_Header.Name = TargetFfs.Data.Header.Name
> > + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
> > + New_Header.Type = TargetFfs.Data.Header.Type
> > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > + New_Header.Size = 0
> > + New_Header.State = TargetFfs.Data.Header.State
> > + New_Header.ExtendedSize = ExtendSize
> > + TargetFfs.Data.Header = New_Header
> > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
> > + TargetFfs.Data.ModCheckSum()
> > + elif type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()) and
> (TargetFfs.Data.HeaderLength +
> > TargetFfs.Data.Size) <= 0xFFFFFF:
> > + New_Header = EFI_FFS_FILE_HEADER()
> > + New_Header.Name = TargetFfs.Data.Header.Name
> > + New_Header.IntegrityCheck = TargetFfs.Data.Header.IntegrityCheck
> > + New_Header.Type = TargetFfs.Data.Header.Type
> > + New_Header.Attributes = TargetFfs.Data.Header.Attributes
> > + New_Header.Size = TargetFfs.Data.HeaderLength +
> TargetFfs.Data.Size
> > + New_Header.State = TargetFfs.Data.Header.State
> > + TargetFfs.Data.Header = New_Header
> > + TargetFfs.Data.Size = TargetFfs.Data.Header.FFS_FILE_SIZE
> > + TargetFfs.Data.HeaderLength = TargetFfs.Data.Header.HeaderLength
> > + TargetFfs.Data.ModCheckSum()
> > + if struct2stream(TargetFfs.Parent.Data.Header.FileSystemGuid) ==
> EFI_FIRMWARE_FILE_SYSTEM3_GUID_BYTE:
> > + NeedChange = True
> > + for item in TargetFfs.Parent.Child:
> > + if type(item.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> > + NeedChange = False
> > + if NeedChange:
> > + TargetFfs.Parent.Data.Header.FileSystemGuid =
> ModifyGuidFormat("8c8ce578-8a3d-4f1c-9935-896185c32dd3")
> > +
> > + if type(TargetFfs.Data.Header) == type(EFI_FFS_FILE_HEADER2()):
> > + TarParent = TargetFfs.Parent
> > + while TarParent:
> > + if TarParent.type == FV_TREE and
> struct2stream(TarParent.Data.Header.FileSystemGuid) ==
> > EFI_FIRMWARE_FILE_SYSTEM2_GUID_BYTE:
> > + TarParent.Data.Header.FileSystemGuid =
> ModifyGuidFormat("5473C07A-3DCB-4dca-BD6F-1E9689E7349A")
> > + TarParent = TarParent.Parent
> > +
> > +class FvHandler:
> > + def __init__(self, NewFfs, TargetFfs) -> None:
> > + self.NewFfs = NewFfs
> > + self.TargetFfs = TargetFfs
> > + self.Status = False
> > + self.Remain_New_Free_Space = 0
> > +
> > + ## Use for Compress the Section Data
> > + def CompressData(self, TargetTree) -> None:
> > + TreePath = TargetTree.GetTreePath()
> > + pos = len(TreePath)
> > + self.Status = True
> > + while pos:
> > + if self.Status:
> > + if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-
> 1].Data.Type == 0x02:
> > + self.CompressSectionData(TreePath[pos-1], None,
> TreePath[pos-1].Data.ExtHeader.SectionDefinitionGuid)
> > + else:
> > + if pos == len(TreePath):
> > + self.CompressSectionData(TreePath[pos-1], pos)
> > + else:
> > + self.CompressSectionData(TreePath[pos-1], None)
> > + pos -= 1
> > +
> > + def CompressSectionData(self, TargetTree, pos: int, GuidTool=None) ->
> None:
> > + NewData = b''
> > + temp_save_child = TargetTree.Child
> > + if TargetTree.Data:
> > + for item in temp_save_child:
> > + if item.type == SECTION_TREE and not item.Data.OriData and
> item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) + item.Data.Data +
> > item.Data.PadData
> > + elif item.type == SECTION_TREE and item.Data.OriData and not
> item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> item.Data.OriData + item.Data.PadData
> > + elif item.type == SECTION_TREE and item.Data.OriData and
> item.Data.ExtHeader:
> > + NewData += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) + item.Data.OriData +
> > item.Data.PadData
> > + elif item.type == FFS_FREE_SPACE:
> > + NewData += item.Data.Data + item.Data.PadData
> > + else:
> > + NewData += struct2stream(item.Data.Header) + item.Data.Data
> + item.Data.PadData
> > + if TargetTree.type == FFS_TREE:
> > + New_Pad_Size = GetPadSize(len(NewData), 8)
> > + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> > + ChangeSize(TargetTree, -Size_delta)
> > + Delta_Pad_Size = len(TargetTree.Data.PadData) - New_Pad_Size
> > + self.Remain_New_Free_Space += Delta_Pad_Size
> > + TargetTree.Data.PadData = b'\xff' * New_Pad_Size
> > + TargetTree.Data.ModCheckSum()
> > + elif TargetTree.type == FV_TREE or TargetTree.type ==
> SEC_FV_TREE and not pos:
> > + if self.Remain_New_Free_Space:
> > + if TargetTree.Data.Free_Space:
> > + TargetTree.Data.Free_Space +=
> self.Remain_New_Free_Space
> > + NewData += self.Remain_New_Free_Space * b'\xff'
> > + TargetTree.Child[-1].Data.Data +=
> self.Remain_New_Free_Space * b'\xff'
> > + else:
> > + TargetTree.Data.Data += self.Remain_New_Free_Space *
> b'\xff'
> > + New_Free_Space = BIOSTREE('FREE_SPACE')
> > + New_Free_Space.type = FFS_FREE_SPACE
> > + New_Free_Space.Data = FreeSpaceNode(b'\xff' *
> self.Remain_New_Free_Space)
> > + TargetTree.insertChild(New_Free_Space)
> > + self.Remain_New_Free_Space = 0
> > + if TargetTree.type == SEC_FV_TREE:
> > + Size_delta = len(NewData) + self.Remain_New_Free_Space -
> len(TargetTree.Data.Data)
> > + TargetTree.Data.Header.FvLength += Size_delta
> > + TargetTree.Data.ModFvExt()
> > + TargetTree.Data.ModFvSize()
> > + TargetTree.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetTree)
> > + TargetTree.Data.ModCheckSum()
> > + elif TargetTree.type == SECTION_TREE and TargetTree.Data.Type !=
> 0x02:
> > + New_Pad_Size = GetPadSize(len(NewData), 4)
> > + Size_delta = len(NewData) - len(TargetTree.Data.Data)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + Delta_Pad_Size = len(TargetTree.Data.PadData) -
> New_Pad_Size
> > + self.Remain_New_Free_Space += Delta_Pad_Size
> > + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> > + TargetTree.Data.Data = NewData
> > + if GuidTool:
> > + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__))+os.path.sep+"
> ..")
> > + ToolPath = os.path.join(ParPath, r'FMMTConfig.ini')
> > + guidtool =
> GUIDTools(ToolPath).__getitem__(struct2stream(GuidTool))
> > + CompressedData = guidtool.pack(TargetTree.Data.Data)
> > + if len(CompressedData) < len(TargetTree.Data.OriData):
> > + New_Pad_Size = GetPadSize(len(CompressedData), 4)
> > + Size_delta = len(CompressedData) - len(TargetTree.Data.OriData)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> > + self.Remain_New_Free_Space = len(TargetTree.Data.OriData)
> + len(TargetTree.Data.PadData) -
> > len(CompressedData) - New_Pad_Size
> > + else:
> > + TargetTree.Data.PadData = b''
> > + self.Remain_New_Free_Space = len(TargetTree.Data.OriData) -
> len(CompressedData)
> > + TargetTree.Data.OriData = CompressedData
> > + elif len(CompressedData) == len(TargetTree.Data.OriData):
> > + TargetTree.Data.OriData = CompressedData
> > + elif len(CompressedData) > len(TargetTree.Data.OriData):
> > + New_Pad_Size = GetPadSize(CompressedData, 4)
> > + self.Remain_New_Free_Space = len(CompressedData) +
> New_Pad_Size - len(TargetTree.Data.OriData) -
> > len(TargetTree.Data.PadData)
> > + Size_delta = len(TargetTree.Data.OriData) - len(CompressedData)
> > + ChangeSize(TargetTree, -Size_delta)
> > + if TargetTree.NextRel:
> > + TargetTree.Data.PadData = b'\x00' * New_Pad_Size
> > + TargetTree.Data.OriData = CompressedData
> > + self.ModifyTest(TargetTree, self.Remain_New_Free_Space)
> > + self.Status = False
> > +
> > + def ModifyFvExtData(self, TreeNode) -> None:
> > + FvExtData = b''
> > + if TreeNode.Data.Header.ExtHeaderOffset:
> > + FvExtHeader = struct2stream(TreeNode.Data.ExtHeader)
> > + FvExtData += FvExtHeader
> > + if TreeNode.Data.Header.ExtHeaderOffset and
> TreeNode.Data.ExtEntryExist:
> > + FvExtEntry = struct2stream(TreeNode.Data.ExtEntry)
> > + FvExtData += FvExtEntry
> > + if FvExtData:
> > + InfoNode = TreeNode.Child[0]
> > + InfoNode.Data.Data = FvExtData +
> InfoNode.Data.Data[TreeNode.Data.ExtHeader.ExtHeaderSize:]
> > + InfoNode.Data.ModCheckSum()
> > +
> > + def ModifyTest(self, ParTree, Needed_Space: int) -> None:
> > + if Needed_Space > 0:
> > + if ParTree.type == FV_TREE or ParTree.type == SEC_FV_TREE:
> > + ParTree.Data.Data = b''
> > + Needed_Space = Needed_Space - ParTree.Data.Free_Space
> > + if Needed_Space < 0:
> > + ParTree.Child[-1].Data.Data = b'\xff' * (-Needed_Space)
> > + ParTree.Data.Free_Space = (-Needed_Space)
> > + self.Status = True
> > + else:
> > + if ParTree.type == FV_TREE:
> > + self.Status = False
> > + else:
> > + BlockSize = ParTree.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - Needed_Space%BlockSize
> > + if New_Add_Len % BlockSize:
> > + ParTree.Child[-1].Data.Data = b'\xff' * New_Add_Len
> > + ParTree.Data.Free_Space = New_Add_Len
> > + Needed_Space += New_Add_Len
> > + else:
> > + ParTree.Child.remove(ParTree.Child[-1])
> > + ParTree.Data.Free_Space = 0
> > + ParTree.Data.Size += Needed_Space
> > + ParTree.Data.Header.Fvlength = ParTree.Data.Size
> > + for item in ParTree.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + ParTree.Data.Data += item.Data.Data + item.Data.PadData
> > + else:
> > + ParTree.Data.Data += struct2stream(item.Data.Header)+
> item.Data.Data + item.Data.PadData
> > + ParTree.Data.ModFvExt()
> > + ParTree.Data.ModFvSize()
> > + ParTree.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(ParTree)
> > + ParTree.Data.ModCheckSum()
> > + elif ParTree.type == FFS_TREE:
> > + ParTree.Data.Data = b''
> > + for item in ParTree.Child:
> > + if item.Data.OriData:
> > + if item.Data.ExtHeader:
> > + ParTree.Data.Data += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) +
> > item.Data.OriData + item.Data.PadData
> > + else:
> > + ParTree.Data.Data += struct2stream(item.Data.Header)+
> item.Data.OriData + item.Data.PadData
> > + else:
> > + if item.Data.ExtHeader:
> > + ParTree.Data.Data += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) +
> > item.Data.Data + item.Data.PadData
> > + else:
> > + ParTree.Data.Data += struct2stream(item.Data.Header)+
> item.Data.Data + item.Data.PadData
> > + ChangeSize(ParTree, -Needed_Space)
> > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 8)
> > + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> > + Needed_Space += Delta_Pad_Size
> > + ParTree.Data.PadData = b'\xff' * GetPadSize(ParTree.Data.Size, 8)
> > + ParTree.Data.ModCheckSum()
> > + elif ParTree.type == SECTION_TREE:
> > + OriData = ParTree.Data.Data
> > + ParTree.Data.Data = b''
> > + for item in ParTree.Child:
> > + if item.type == SECTION_TREE and item.Data.ExtHeader and
> item.Data.Type != 0x02:
> > + ParTree.Data.Data += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) +
> > item.Data.Data + item.Data.PadData
> > + elif item.type == SECTION_TREE and item.Data.ExtHeader and
> item.Data.Type == 0x02:
> > + ParTree.Data.Data += struct2stream(item.Data.Header) +
> struct2stream(item.Data.ExtHeader) +
> > item.Data.OriData + item.Data.PadData
> > + else:
> > + ParTree.Data.Data += struct2stream(item.Data.Header) +
> item.Data.Data + item.Data.PadData
> > + if ParTree.Data.Type == 0x02:
> > + ParTree.Data.Size += Needed_Space
> > + ParPath =
> os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
> > + ToolPath = os.path.join(os.path.dirname(ParPath),
> r'FMMTConfig.ini')
> > + guidtool =
> >
> GUIDTools(ToolPath).__getitem__(struct2stream(ParTree.Data.ExtHeader.S
> ectionDefinitionGuid))
> > + CompressedData = guidtool.pack(ParTree.Data.Data)
> > + Needed_Space = len(CompressedData) -
> len(ParTree.Data.OriData)
> > + ParTree.Data.OriData = CompressedData
> > + New_Size = ParTree.Data.HeaderLength + len(CompressedData)
> > + ParTree.Data.Header.Size[0] = New_Size % (16**2)
> > + ParTree.Data.Header.Size[1] = New_Size % (16**4) //(16**2)
> > + ParTree.Data.Header.Size[2] = New_Size // (16**4)
> > + if ParTree.NextRel:
> > + New_Pad_Size = GetPadSize(New_Size, 4)
> > + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> > + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> > + Needed_Space += Delta_Pad_Size
> > + else:
> > + ParTree.Data.PadData = b''
> > + elif Needed_Space:
> > + ChangeSize(ParTree, -Needed_Space)
> > + New_Pad_Size = GetPadSize(ParTree.Data.Size, 4)
> > + Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
> > + Needed_Space += Delta_Pad_Size
> > + ParTree.Data.PadData = b'\x00' * New_Pad_Size
> > + NewParTree = ParTree.Parent
> > + ROOT_TYPE = [ROOT_FV_TREE, ROOT_FFS_TREE,
> ROOT_SECTION_TREE, ROOT_TREE]
> > + if NewParTree and NewParTree.type not in ROOT_TYPE:
> > + self.ModifyTest(NewParTree, Needed_Space)
> > + else:
> > + self.Status = True
> > +
> > + def ReplaceFfs(self) -> bool:
> > + TargetFv = self.TargetFfs.Parent
> > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child Ffs
> Header State need be reversed.
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + # NewFfs parsing will not calculate the PadSize, thus recalculate.
> > + self.NewFfs.Data.PadData = b'\xff' *
> GetPadSize(self.NewFfs.Data.Size, 8)
> > + if self.NewFfs.Data.Size > self.TargetFfs.Data.Size:
> > + Needed_Space = self.NewFfs.Data.Size +
> len(self.NewFfs.Data.PadData) - self.TargetFfs.Data.Size -
> > len(self.TargetFfs.Data.PadData)
> > + # If TargetFv have enough free space, just move part of the free
> space to NewFfs.
> > + if TargetFv.Data.Free_Space >= Needed_Space:
> > + # Modify TargetFv Child info and BiosTree.
> > + TargetFv.Child[-1].Data.Data = b'\xff' *
> (TargetFv.Data.Free_Space - Needed_Space)
> > + TargetFv.Data.Free_Space -= Needed_Space
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + # Modify TargetFv Header and ExtHeader info.
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # return the Status
> > + self.Status = True
> > + # If TargetFv do not have enough free space, need move part of the
> free space of TargetFv's parent Fv to
> > TargetFv/NewFfs.
> > + else:
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + else:
> > + # Recalculate TargetFv needed space to keep it match the
> BlockSize setting.
> > + Needed_Space -= TargetFv.Data.Free_Space
> > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - Needed_Space%BlockSize
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + if New_Add_Len % BlockSize:
> > + TargetFv.Child[-1].Data.Data = b'\xff' * New_Add_Len
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + Needed_Space += New_Add_Len
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + else:
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.Data.Free_Space = 0
> > + TargetFv.insertChild(self.NewFfs)
> > + # Encapsulate the Fv Data for update.
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> > + else:
> > + TargetFv.Data.Data += struct2stream(item.Data.Header)+
> item.Data.Data + item.Data.PadData
> > + TargetFv.Data.Size += Needed_Space
> > + # Modify TargetFv Data Header and ExtHeader info.
> > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # Start free space calculating and moving process.
> > + self.ModifyTest(TargetFv.Parent, Needed_Space)
> > + else:
> > + New_Free_Space = self.TargetFfs.Data.Size - self.NewFfs.Data.Size
> > + # If TargetFv already have free space, move the new free space into
> it.
> > + if TargetFv.Data.Free_Space:
> > + TargetFv.Child[-1].Data.Data += b'\xff' * New_Free_Space
> > + TargetFv.Data.Free_Space += New_Free_Space
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + self.Status = True
> > + # If TargetFv do not have free space, create free space for Fv.
> > + else:
> > + New_Free_Space_Tree = BIOSTREE('FREE_SPACE')
> > + New_Free_Space_Tree.type = FFS_FREE_SPACE
> > + New_Free_Space_Tree.Data = FfsNode(b'\xff' *
> New_Free_Space)
> > + TargetFv.Data.Free_Space = New_Free_Space
> > + TargetFv.insertChild(New_Free_Space)
> > + Target_index = TargetFv.Child.index(self.TargetFfs)
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs, Target_index)
> > + self.Status = True
> > + # Modify TargetFv Header and ExtHeader info.
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + return self.Status
> > +
> > + def AddFfs(self) -> bool:
> > + # NewFfs parsing will not calculate the PadSize, thus recalculate.
> > + self.NewFfs.Data.PadData = b'\xff' *
> GetPadSize(self.NewFfs.Data.Size, 8)
> > + if self.TargetFfs.type == FFS_FREE_SPACE:
> > + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData)
> - self.TargetFfs.Data.Size -
> > len(self.TargetFfs.Data.PadData)
> > + TargetFv = self.TargetFfs.Parent
> > + # If the Fv Header Attributes is EFI_FVB2_ERASE_POLARITY, Child
> Ffs Header State need be reversed.
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + # If TargetFv have enough free space, just move part of the free
> space to NewFfs, split free space to NewFfs
> > and new free space.
> > + if TargetLen < 0:
> > + self.Status = True
> > + self.TargetFfs.Data.Data = b'\xff' * (-TargetLen)
> > + TargetFv.Data.Free_Space = (-TargetLen)
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + TargetFv.insertChild(self.NewFfs, -1)
> > + ModifyFfsType(self.NewFfs)
> > + elif TargetLen == 0:
> > + self.Status = True
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs)
> > + ModifyFfsType(self.NewFfs)
> > + # If TargetFv do not have enough free space, need move part of the
> free space of TargetFv's parent Fv to
> > TargetFv/NewFfs.
> > + else:
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + elif TargetFv.type == SEC_FV_TREE:
> > + # Recalculate TargetFv needed space to keep it match the
> BlockSize setting.
> > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - TargetLen%BlockSize
> > + if New_Add_Len % BlockSize:
> > + self.TargetFfs.Data.Data = b'\xff' * New_Add_Len
> > + self.TargetFfs.Data.Size = New_Add_Len
> > + TargetLen += New_Add_Len
> > + TargetFv.insertChild(self.NewFfs, -1)
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + else:
> > + TargetFv.Child.remove(self.TargetFfs)
> > + TargetFv.insertChild(self.NewFfs)
> > + TargetFv.Data.Free_Space = 0
> > + ModifyFfsType(self.NewFfs)
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> > + else:
> > + TargetFv.Data.Data += struct2stream(item.Data.Header)+
> item.Data.Data + item.Data.PadData
> > + # Encapsulate the Fv Data for update.
> > + TargetFv.Data.Size += TargetLen
> > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + # Start free space calculating and moving process.
> > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > + else:
> > + # If TargetFv do not have free space, need directly move part of the
> free space of TargetFv's parent Fv to
> > TargetFv/NewFfs.
> > + TargetLen = self.NewFfs.Data.Size + len(self.NewFfs.Data.PadData)
> > + TargetFv = self.TargetFfs.Parent
> > + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY:
> > + self.NewFfs.Data.Header.State = c_uint8(
> > + ~self.NewFfs.Data.Header.State)
> > + if TargetFv.type == FV_TREE:
> > + self.Status = False
> > + elif TargetFv.type == SEC_FV_TREE:
> > + BlockSize = TargetFv.Data.Header.BlockMap[0].Length
> > + New_Add_Len = BlockSize - TargetLen%BlockSize
> > + if New_Add_Len % BlockSize:
> > + New_Free_Space = BIOSTREE('FREE_SPACE')
> > + New_Free_Space.type = FFS_FREE_SPACE
> > + New_Free_Space.Data = FreeSpaceNode(b'\xff' *
> New_Add_Len)
> > + TargetLen += New_Add_Len
> > + TargetFv.Data.Free_Space = New_Add_Len
> > + TargetFv.insertChild(self.NewFfs)
> > + TargetFv.insertChild(New_Free_Space)
> > + else:
> > + TargetFv.insertChild(self.NewFfs)
> > + ModifyFfsType(self.NewFfs)
> > + TargetFv.Data.Data = b''
> > + for item in TargetFv.Child:
> > + if item.type == FFS_FREE_SPACE:
> > + TargetFv.Data.Data += item.Data.Data + item.Data.PadData
> > + else:
> > + TargetFv.Data.Data += struct2stream(item.Data.Header)+
> item.Data.Data + item.Data.PadData
> > + TargetFv.Data.Size += TargetLen
> > + TargetFv.Data.Header.FvLength = TargetFv.Data.Size
> > + TargetFv.Data.ModFvExt()
> > + TargetFv.Data.ModFvSize()
> > + TargetFv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(TargetFv)
> > + TargetFv.Data.ModCheckSum()
> > + self.ModifyTest(TargetFv.Parent, TargetLen)
> > + return self.Status
> > +
> > + def DeleteFfs(self) -> bool:
> > + Delete_Ffs = self.TargetFfs
> > + Delete_Fv = Delete_Ffs.Parent
> > + Add_Free_Space = Delete_Ffs.Data.Size +
> len(Delete_Ffs.Data.PadData)
> > + if Delete_Fv.Data.Free_Space:
> > + if Delete_Fv.type == SEC_FV_TREE:
> > + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space -
> Add_Free_Space
> > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> > + New_Free_Space = BlockSize - Used_Size % BlockSize
> > + self.Remain_New_Free_Space += Delete_Fv.Data.Free_Space +
> Add_Free_Space - New_Free_Space
> > + Delete_Fv.Child[-1].Data.Data = New_Free_Space * b'\xff'
> > + Delete_Fv.Data.Free_Space = New_Free_Space
> > + else:
> > + Used_Size = Delete_Fv.Data.Size - Delete_Fv.Data.Free_Space -
> Add_Free_Space
> > + Delete_Fv.Child[-1].Data.Data += Add_Free_Space * b'\xff'
> > + Delete_Fv.Data.Free_Space += Add_Free_Space
> > + New_Free_Space = Delete_Fv.Data.Free_Space +
> Add_Free_Space
> > + else:
> > + if Delete_Fv.type == SEC_FV_TREE:
> > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > + BlockSize = Delete_Fv.Data.Header.BlockMap[0].Length
> > + New_Free_Space = BlockSize - Used_Size % BlockSize
> > + self.Remain_New_Free_Space += Add_Free_Space -
> New_Free_Space
> > + Add_Free_Space = New_Free_Space
> > + else:
> > + Used_Size = Delete_Fv.Data.Size - Add_Free_Space
> > + New_Free_Space = Add_Free_Space
> > + New_Free_Space_Info = FfsNode(Add_Free_Space * b'\xff')
> > + New_Free_Space_Info.Data = Add_Free_Space * b'\xff'
> > + New_Ffs_Tree = BIOSTREE(New_Free_Space_Info.Name)
> > + New_Ffs_Tree.type = FFS_FREE_SPACE
> > + New_Ffs_Tree.Data = New_Free_Space_Info
> > + Delete_Fv.insertChild(New_Ffs_Tree)
> > + Delete_Fv.Data.Free_Space = Add_Free_Space
> > + Delete_Fv.Child.remove(Delete_Ffs)
> > + Delete_Fv.Data.Header.FvLength = Used_Size + New_Free_Space
> > + Delete_Fv.Data.ModFvExt()
> > + Delete_Fv.Data.ModFvSize()
> > + Delete_Fv.Data.ModExtHeaderData()
> > + self.ModifyFvExtData(Delete_Fv)
> > + Delete_Fv.Data.ModCheckSum()
> > + self.CompressData(Delete_Fv)
> > + self.Status = True
> > + return self.Status
> > diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py
> b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > new file mode 100644
> > index 000000000000..287b949cc32f
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/core/GuidTools.py
> > @@ -0,0 +1,152 @@
> > +## @file
> > +# This file is used to define the FMMT dependent external tool
> management class.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +import glob
> > +import logging
> > +import os
> > +import shutil
> > +import sys
> > +import tempfile
> > +import uuid
> > +from PI.Common import *
> > +from utils.FmmtLogger import FmmtLogger as logger
> > +import subprocess
> > +
> > +def ExecuteCommand(cmd: list) -> None:
> > + subprocess.run(cmd,stdout=subprocess.DEVNULL)
> > +
> > +class GUIDTool:
> > + def __init__(self, guid: str, short_name: str, command: str) -> None:
> > + self.guid: str = guid
> > + self.short_name: str = short_name
> > + self.command: str = command
> > +
> > + def pack(self, buffer: bytes) -> bytes:
> > + """
> > + compress file.
> > + """
> > + tool = self.command
> > + if tool:
> > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > + ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")
> > + ToolOuputFile = os.path.join(tmp, "pack_sec_file")
> > + try:
> > + file = open(ToolInputFile, "wb")
> > + file.write(buffer)
> > + file.close()
> > + command = [tool, '-e', '-o', ToolOuputFile,
> > + ToolInputFile]
> > + ExecuteCommand(command)
> > + buf = open(ToolOuputFile, "rb")
> > + res_buffer = buf.read()
> > + except Exception as msg:
> > + logger.error(msg)
> > + return ""
> > + else:
> > + buf.close()
> > + if os.path.exists(tmp):
> > + shutil.rmtree(tmp)
> > + return res_buffer
> > + else:
> > + logger.error(
> > + "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be
> parsed at this time.")
> > + logger.info("Its GUID is: %s" % self.guid)
> > + return ""
> > +
> > +
> > + def unpack(self, buffer: bytes) -> bytes:
> > + """
> > + buffer: remove common header
> > + uncompress file
> > + """
> > + tool = self.command
> > + if tool:
> > + tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
> > + ToolInputFile = os.path.join(tmp, "unpack_sec_file")
> > + ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")
> > + try:
> > + file = open(ToolInputFile, "wb")
> > + file.write(buffer)
> > + file.close()
> > + command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]
> > + ExecuteCommand(command)
> > + buf = open(ToolOuputFile, "rb")
> > + res_buffer = buf.read()
> > + except Exception as msg:
> > + logger.error(msg)
> > + return ""
> > + else:
> > + buf.close()
> > + if os.path.exists(tmp):
> > + shutil.rmtree(tmp)
> > + return res_buffer
> > + else:
> > + logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED
> cannot be parsed at this time.")
> > + logger.info("Its GUID is: %s" % self.guid)
> > + return ""
> > +
> > +class GUIDTools:
> > + '''
> > + GUIDTools is responsible for reading FMMTConfig.ini, verify the tools
> and provide interfaces to access those tools.
> > + '''
> > + default_tools = {
> > + struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-
> 127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-
> > 127f4c984779", "TIANO", "TianoCompress"),
> > + struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-
> dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-
> > dc7bd79403cf", "LZMA", "LzmaCompress"),
> > + struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-
> a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-
> > a4600d9dd083", "CRC32", "GenCrc32"),
> > + struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-
> ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-
> > ca72a6eae889", "LZMAF86", "LzmaF86Compress"),
> > + struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-
> 0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-
> > 0f7f630d5afb", "BROTLI", "BrotliCompress"),
> > + }
> > +
> > + def __init__(self, tooldef_file: str=None) -> None:
> > + self.dir = os.path.dirname(__file__)
> > + self.tooldef_file = tooldef_file if tooldef_file else os.path.join(
> > + self.dir, "FMMTConfig.ini")
> > + self.tooldef = dict()
> > + self.load()
> > +
> > + def VerifyTools(self) -> None:
> > + """
> > + Verify Tools and Update Tools path.
> > + """
> > + path_env = os.environ.get("PATH")
> > + path_env_list = path_env.split(os.pathsep)
> > + path_env_list.append(os.path.dirname(__file__))
> > + path_env_list = list(set(path_env_list))
> > + for tool in self.tooldef.values():
> > + cmd = tool.command
> > + if os.path.isabs(cmd):
> > + if not os.path.exists(cmd):
> > + print("Tool Not found %s" % cmd)
> > + else:
> > + for syspath in path_env_list:
> > + if glob.glob(os.path.join(syspath, cmd+"*")):
> > + break
> > + else:
> > + print("Tool Not found %s" % cmd)
> > +
> > + def load(self) -> None:
> > + if os.path.exists(self.tooldef_file):
> > + with open(self.tooldef_file, "r") as fd:
> > + config_data = fd.readlines()
> > + for line in config_data:
> > + try:
> > + guid, short_name, command = line.split()
> > + new_format_guid =
> struct2stream(ModifyGuidFormat(guid.strip()))
> > + self.tooldef[new_format_guid] = GUIDTool(
> > + guid.strip(), short_name.strip(), command.strip())
> > + except:
> > + print("GuidTool load error!")
> > + continue
> > + else:
> > + self.tooldef.update(self.default_tools)
> > +
> > + self.VerifyTools()
> > +
> > + def __getitem__(self, guid) -> None:
> > + return self.tooldef.get(guid)
> > +
> > +
> > +guidtools = GUIDTools()
> > diff --git a/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > new file mode 100644
> > index 000000000000..5289fc27049a
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/utils/FmmtLogger.py
> > @@ -0,0 +1,18 @@
> > +## @file
> > +# This file is used to define the Fmmt Logger.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +##
> > +
> > +import logging
> > +import sys
> > +
> > +FmmtLogger = logging.getLogger('FMMT')
> > +FmmtLogger.setLevel(logging.INFO)
> > +
> > +lh=logging.StreamHandler(sys.stdout)
> > +lf=logging.Formatter("%(levelname)-8s: %(message)s")
> > +lh.setFormatter(lf)
> > +FmmtLogger.addHandler(lh)
> > \ No newline at end of file
> > diff --git a/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > new file mode 100644
> > index 000000000000..83a31aeea3fe
> > --- /dev/null
> > +++ b/BaseTools/Source/Python/FMMT/utils/FvLayoutPrint.py
> > @@ -0,0 +1,54 @@
> > +## @file
> > +# This file is used to define the printer for Bios layout.
> > +#
> > +# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +
> > +def GetFormatter(layout_format: str):
> > + if layout_format == 'json':
> > + return JsonFormatter()
> > + elif layout_format == 'yaml':
> > + return YamlFormatter()
> > + elif layout_format == 'html':
> > + return HtmlFormatter()
> > + else:
> > + return TxtFormatter()
> > +
> > +class Formatter(object):
> > + def dump(self, layoutdict, layoutlist, outputfile: str=None) -> None:
> > + raise NotImplemented
> > +
> > +class JsonFormatter(Formatter):
> > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) ->
> None:
> > + try:
> > + import json
> > + except:
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > + return
> > + print(outputfile)
> > + if outputfile:
> > + with open(outputfile,"w") as fw:
> > + json.dump(layoutdict, fw, indent=2)
> > + else:
> > + print(json.dumps(layoutdict,indent=2))
> > +
> > +class TxtFormatter(Formatter):
> > + def LogPrint(self,layoutlist: list) -> None:
> > + for item in layoutlist:
> > + print(item)
> > + print('\n')
> > +
> > + def dump(self,layoutdict: dict, layoutlist: list, outputfile: str=None) ->
> None:
> > + print(outputfile)
> > + with open(outputfile, "w") as f:
> > + for item in layoutlist:
> > + f.writelines(item + '\n')
> > +
> > +class YamlFormatter(Formatter):
> > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > +
> > +class HtmlFormatter(Formatter):
> > + def dump(self,layoutdict, layoutlist, outputfile = None):
> > + TxtFormatter().dump(layoutdict, layoutlist, outputfile)
> > \ No newline at end of file
> > --
> > 2.27.0.windows.1
> >
> >
> >
> >
> >
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-12-06 9:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-01 1:29 [PATCH 1/1] BaseTools: Add FMMT Tool Yuwei Chen
2021-12-03 3:18 ` 回复: [edk2-devel] " gaoliming
2021-12-06 8:34 ` Yuwei Chen
2021-12-06 9:44 ` 回复: " gaoliming
-- strict thread matches above, loose matches on Subject: below --
2021-11-09 0:09 Yuwei Chen
2021-11-09 0:29 ` [edk2-devel] " Michael D Kinney
2021-11-09 1:34 ` Yuwei Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox