From 243f0e325c3904681577b90ce43d2b4edcd685ef Mon Sep 17 00:00:00 2001 From: lash Date: Sat, 11 Feb 2023 05:41:41 +0000 Subject: [PATCH] Implement new chainlib arg setup, rename deploy to publish --- python/eth_address_declarator/runnable/add.py | 95 ++++++++------- .../eth_address_declarator/runnable/deploy.py | 84 ------------- .../runnable/publish.py | 110 ++++++++++++++++++ .../eth_address_declarator/runnable/view.py | 99 ++++++++-------- python/setup.cfg | 2 +- solidity/AddressDeclarator.bin | 2 +- 6 files changed, 216 insertions(+), 176 deletions(-) delete mode 100644 python/eth_address_declarator/runnable/deploy.py create mode 100644 python/eth_address_declarator/runnable/publish.py diff --git a/python/eth_address_declarator/runnable/add.py b/python/eth_address_declarator/runnable/add.py index dc84064..6063080 100644 --- a/python/eth_address_declarator/runnable/add.py +++ b/python/eth_address_declarator/runnable/add.py @@ -1,5 +1,4 @@ """Adds a new Address declaration - .. moduleauthor:: Louis Holbrook .. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 @@ -21,6 +20,19 @@ from hexathon import ( add_0x, strip_0x, ) +from chainlib.eth.cli.arg import ( + Arg, + ArgFlag, + process_args, + ) +from chainlib.eth.cli.config import ( + Config, + process_config, + ) +from chainlib.eth.cli.log import process_log +from chainlib.eth.settings import process_settings +from chainlib.settings import ChainSettings + # local imports from eth_address_declarator.declarator import AddressDeclarator @@ -28,58 +40,57 @@ from eth_address_declarator.declarator import AddressDeclarator logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -script_dir = os.path.dirname(__file__) -data_dir = os.path.join(script_dir, '..', 'data') -arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC -argparser = chainlib.eth.cli.ArgumentParser(arg_flags) -argparser.add_argument('-a', '--address', type=str, help='Address to add declaration for') -argparser.add_positional('declaration', type=str, help='SHA256 sum of endorsement data to add') +def process_config_local(config, arg, args, flags): + hsh = strip_0x(config.get('_POSARG')) + if len(hsh) != 64: + raise ValueError('declaration hash must be 32 bytes') + config.add(hsh, '_DECLARATION') + return config + + +arg_flags = ArgFlag() +arg = Arg(arg_flags) +flags = arg_flags.STD_WRITE | arg_flags.WALLET | arg_flags.EXEC + +argparser = chainlib.eth.cli.ArgumentParser() +argparser = process_args(argparser, arg, flags) +argparser.add_argument('declaration', type=str, help='SHA256 sum of endorsement data to add') args = argparser.parse_args() -extra_args = { - 'address': None, - 'declaration': None, - } -config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AddressDeclarator.gas()) +logg = process_log(args, logg) -wallet = chainlib.eth.cli.Wallet() -wallet.from_config(config) +config = Config() +config = process_config(config, arg, args, flags, positional_name='declaration') +config = process_config_local(config, arg, args, flags) +logg.debug('config loaded:\n{}'.format(config)) -rpc = chainlib.eth.cli.Rpc(wallet=wallet) -conn = rpc.connect_by_config(config) - -chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) +settings = ChainSettings() +settings = process_settings(settings, config) +logg.debug('settings loaded:\n{}'.format(settings)) def main(): - signer = rpc.get_signer() - signer_address = rpc.get_sender_address() + conn = settings.get('CONN') + c = AddressDeclarator( + settings.get('CHAIN_SPEC'), + signer=settings.get('SIGNER'), + gas_oracle=settings.get('FEE_ORACLE'), + nonce_oracle=settings.get('NONCE_ORACLE'), + ) + subject_address = to_checksum_address(settings.get('RECIPIENT')) + contract_address = to_checksum_address(settings.get('EXEC')) - gas_oracle = rpc.get_gas_oracle() - nonce_oracle = rpc.get_nonce_oracle() + (tx_hash_hex, o) = c.add_declaration( + settings.get('EXEC'), + settings.get('SENDER_ADDRESS'), + settings.get('RECIPIENT'), + add_0x(config.get('_DECLARATION')), + ) - c = AddressDeclarator(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) - - subject_address = to_checksum_address(config.get('_ADDRESS')) - if not config.true('_UNSAFE') and subject_address != add_0x(config.get('_ADDRESS')): - raise ValueError('invalid checksum address for subject_address') - - contract_address = to_checksum_address(config.get('_EXEC_ADDRESS')) - if not config.true('_UNSAFE') and contract_address != add_0x(config.get('_EXEC_ADDRESS')): - raise ValueError('invalid checksum address for contract') - - declaration = config.get('_DECLARATION') - declaration_bytes = bytes.fromhex(strip_0x(declaration)) - if len(declaration_bytes) != 32: - raise ValueError('declaration hash must be 32 bytes') - declaration = add_0x(declaration) - - (tx_hash_hex, o) = c.add_declaration(contract_address, signer_address, subject_address, declaration) - - if config.get('_RPC_SEND'): + if settings.get('RPC_SEND'): conn.do(o) - if config.get('_WAIT'): + if config.true('_WAIT'): r = conn.wait(tx_hash_hex) if r['status'] == 0: sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') diff --git a/python/eth_address_declarator/runnable/deploy.py b/python/eth_address_declarator/runnable/deploy.py deleted file mode 100644 index f112d09..0000000 --- a/python/eth_address_declarator/runnable/deploy.py +++ /dev/null @@ -1,84 +0,0 @@ -"""Deploys address declaration contract - -.. moduleauthor:: Louis Holbrook -.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 - -""" - -# standard imports -import sys -import os -import json -import argparse -import logging -from hexathon import ( - add_0x, - strip_0x, - ) - -# external imports -import chainlib.eth.cli -from chainlib.chain import ChainSpec -from chainlib.eth.connection import EthHTTPConnection -from chainlib.eth.tx import receipt - -# local imports -from eth_address_declarator.declarator import AddressDeclarator - -logging.basicConfig(level=logging.WARNING) -logg = logging.getLogger() - -arg_flags = chainlib.eth.cli.argflag_std_write -argparser = chainlib.eth.cli.ArgumentParser(arg_flags) -argparser.add_argument('owner_description_hash', type=str, help='SHA256 of description metadata of contract deployer') -args = argparser.parse_args() - -extra_args = { - 'owner_description_hash': None, - } -config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AddressDeclarator.gas()) - -wallet = chainlib.eth.cli.Wallet() -wallet.from_config(config) - -rpc = chainlib.eth.cli.Rpc(wallet=wallet) -conn = rpc.connect_by_config(config) - -chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) - - -def main(): - signer = rpc.get_signer() - signer_address = rpc.get_sender_address() - - gas_oracle = rpc.get_gas_oracle() - nonce_oracle = rpc.get_nonce_oracle() - - c = AddressDeclarator(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) - - owner_description_hash = config.get('_OWNER_DESCRIPTION_HASH') - owner_description_hash_bytes = bytes.fromhex(strip_0x(owner_description_hash)) - if len(owner_description_hash_bytes) != 32: - raise ValueError('chain config hash must be 32 bytes') - owner_description_hash = add_0x(owner_description_hash) - - (tx_hash_hex, o) = c.constructor(signer_address, owner_description_hash) - if config.get('_RPC_SEND'): - conn.do(o) - if config.get('_WAIT'): - r = conn.wait(tx_hash_hex) - if r['status'] == 0: - sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') - sys.exit(1) - # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) - address = r['contractAddress'] - - print(address) - else: - print(tx_hash_hex) - else: - print(o) - - -if __name__ == '__main__': - main() diff --git a/python/eth_address_declarator/runnable/publish.py b/python/eth_address_declarator/runnable/publish.py new file mode 100644 index 0000000..94ef833 --- /dev/null +++ b/python/eth_address_declarator/runnable/publish.py @@ -0,0 +1,110 @@ +"""Deploys address declaration contract + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# standard imports +import sys +import os +import json +import argparse +import logging +from hexathon import ( + add_0x, + strip_0x, + ) + +# external imports +import chainlib.eth.cli +from chainlib.chain import ChainSpec +from chainlib.eth.connection import EthHTTPConnection +from chainlib.eth.tx import receipt +from chainlib.eth.cli.arg import ( + Arg, + ArgFlag, + process_args, + ) +from chainlib.eth.cli.config import ( + Config, + process_config, + ) +from chainlib.eth.cli.log import process_log +from chainlib.eth.settings import process_settings +from chainlib.settings import ChainSettings +from chainlib.eth.constant import ZERO_CONTENT + +# local imports +from eth_address_declarator.declarator import AddressDeclarator + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + + +def process_config_local(config, arg, args, flags): + hsh = args.owner_description_hash + if hsh == None: + hsh = ZERO_CONTENT + hsh = add_0x(hsh) + config.add(hsh, '_OWNER_DESCRIPTION_HASH') + return config + + +arg_flags = ArgFlag() +arg = Arg(arg_flags) +flags = arg_flags.STD_WRITE + +argparser = chainlib.eth.cli.ArgumentParser() +argparser = process_args(argparser, arg, flags) +argparser.add_argument('--owner-description-hash', type=str, help='SHA256 of description metadata of contract deployer') +args = argparser.parse_args() + +logg = process_log(args, logg) + +config = Config() +config = process_config(config, arg, args, flags) +config = process_config_local(config, arg, args, flags) +logg.debug('config loaded:\n{}'.format(config)) + +settings = ChainSettings() +settings = process_settings(settings, config) +logg.debug('settings loaded:\n{}'.format(settings)) + + +def main(): + conn = settings.get('CONN') + c = AddressDeclarator( + settings.get('CHAIN_SPEC'), + signer=settings.get('SIGNER'), + gas_oracle=settings.get('FEE_ORACLE'), + nonce_oracle=settings.get('NONCE_ORACLE'), + ) + owner_description_hash = config.get('_OWNER_DESCRIPTION_HASH') + owner_description_hash_bytes = bytes.fromhex(strip_0x(owner_description_hash)) + if len(owner_description_hash_bytes) != 32: + raise ValueError('chain config hash must be 32 bytes') + + (tx_hash_hex, o) = c.constructor( + settings.get('SENDER_ADDRESS'), + owner_description_hash, + ) + if settings.get('RPC_SEND'): + conn.do(o) + if config.true('_WAIT'): + r = conn.wait(tx_hash_hex) + if r['status'] == 0: + sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') + sys.exit(1) + # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) + address = r['contractAddress'] + + print(address) + else: + print(tx_hash_hex) + else: + print(o) + + +if __name__ == '__main__': + main() diff --git a/python/eth_address_declarator/runnable/view.py b/python/eth_address_declarator/runnable/view.py index fe85255..878f9f5 100644 --- a/python/eth_address_declarator/runnable/view.py +++ b/python/eth_address_declarator/runnable/view.py @@ -22,6 +22,19 @@ from hexathon import ( add_0x, strip_0x, ) +from chainlib.eth.cli.arg import ( + Arg, + ArgFlag, + process_args, + ) +from chainlib.eth.cli.config import ( + Config, + process_config, + ) +from chainlib.eth.cli.log import process_log +from chainlib.eth.settings import process_settings +from chainlib.settings import ChainSettings + # local imports from eth_address_declarator import Declarator @@ -30,27 +43,38 @@ from eth_address_declarator.declarator import AddressDeclarator logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -#argparser.add_argument('--resolve', action='store_true', help='Attempt to resolve the hashes to actual content') -#argparser.add_argument('--resolve-http', dest='resolve_http', type=str, help='Base url to look up content hashes') -arg_flags = chainlib.eth.cli.argflag_std_read | chainlib.eth.cli.Flag.EXEC | chainlib.eth.cli.Flag.WALLET -argparser = chainlib.eth.cli.ArgumentParser(arg_flags, arg_long={'-a': '--declarator-address'}) -argparser.add_positional('address', type=str, help='Ethereum declaration address to look up') + +def process_config_local(config, arg, args, flags): + a = strip_0x(config.get('_POSARG')) + ac = to_checksum_address(a) + if config.true('_UNSAFE'): + a = ac + else: + if a != ac: + raise ValueError('declarator is not a valid checksum address') + config.add(a, '_DECLARATOR') + return config + + +arg_flags = ArgFlag() +arg = Arg(arg_flags) +flags = arg_flags.STD_WRITE | arg_flags.WALLET | arg_flags.EXEC + +argparser = chainlib.eth.cli.ArgumentParser() +argparser = process_args(argparser, arg, flags) +argparser.add_argument('declarator', type=str, help='Ethereum declaration address to look up') args = argparser.parse_args() -extra_args = { - 'address': None, - } -config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AddressDeclarator.gas()) +logg = process_log(args, logg) -wallet = chainlib.eth.cli.Wallet() -wallet.from_config(config) +config = Config() +config = process_config(config, arg, args, flags, positional_name='declarator') +config = process_config_local(config, arg, args, flags) +logg.debug('config loaded:\n{}'.format(config)) -rpc = chainlib.eth.cli.Rpc() -conn = rpc.connect_by_config(config) - -chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) - -declarator_address = config.get('_WALLET_ADDRESS') +settings = ChainSettings() +settings = process_settings(settings, config) +logg.debug('settings loaded:\n{}'.format(settings)) def out_element(e, w=sys.stdout): @@ -68,41 +92,20 @@ def ls(ifc, conn, contract_address, declarator_address, subject_address, w=sys.s def main(): - c = Declarator(chain_spec) + c = Declarator( + settings.get('CHAIN_SPEC') + ) - contract_address = to_checksum_address(config.get('_EXEC_ADDRESS')) - if not config.true('_UNSAFE') and contract_address != add_0x(config.get('_EXEC_ADDRESS')): - raise ValueError('invalid checksum address for contract') - - - declarator_address = to_checksum_address(config.get('_DECLARATOR_ADDRESS')) - if not config.true('_UNSAFE') and declarator_address != add_0x(config.get('_DECLARATOR_ADDRESS')): - raise ValueError('invalid checksum address for declarator') - - subject_address = to_checksum_address(config.get('_ADDRESS')) - if not config.true('_UNSAFE') and subject_address != add_0x(config.get('_ADDRESS')): - raise ValueError('invalid checksum address for subject') - - ls(c, conn, contract_address, declarator_address, subject_address) + ls( + c, + settings.get('CONN'), + settings.get('EXEC'), + config.get('_DECLARATOR'), + settings.get('RECIPIENT'), + ) declarations = [] -# for d in declarations: -# if not args.resolve: -# print(d.hex()) -# continue -# if args.resolve_http: -# try: -# r = try_sha256(d) -# print(r) -# continue -# except urllib.error.HTTPError: -# pass -# try: -# print(try_utf8(d)) -# except UnicodeDecodeError: -# pass - if __name__ == '__main__': main() diff --git a/python/setup.cfg b/python/setup.cfg index 68fb660..adf1ffe 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -36,6 +36,6 @@ packages = [options.entry_points] console_scripts = - eth-address-declarator-deploy = eth_address_declarator.runnable.deploy:main + eth-address-declarator-publish = eth_address_declarator.runnable.publish:main eth-address-declarator-add = eth_address_declarator.runnable.add:main eth-address-declarator-view = eth_address_declarator.runnable.view:main diff --git a/solidity/AddressDeclarator.bin b/solidity/AddressDeclarator.bin index 93f775a..ee37d03 100644 --- a/solidity/AddressDeclarator.bin +++ b/solidity/AddressDeclarator.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620021eb380380620021eb8339818101604052810190620000379190620009ba565b606060058190806001815401808255809150506001900390600052602060002001600090919091909150908051906020019062000076929190620008e7565b50600560016005805490506200008d919062000a25565b81548110620000a157620000a062000a60565b5b9060005260206000200143409080600181540180825580915050600190039060005260206000200160009091909190915055620000ee3383620000f7640100000000026401000000009004565b50505062000cb2565b60006200010362000939565b6060600062000123328787620003c3640100000000026401000000009004565b9250600160008460006002811062000140576200013f62000a60565b5b602002015181526020019081526020016000205490506000811415620002f457600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020329080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506005829080600181540180825580915050600190039060005260206000200160009091909190915090805190602001906200023d929190620008e7565b506000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020869080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600580549050620002f1919062000a25565b90505b80600160008560006002811062000310576200030f62000a60565b5b6020020151815260200190815260200160002081905550600581815481106200033e576200033d62000a60565b5b90600052602060002001859080600181540180825580915050600190039060005260206000200160009091909190915055600160046000856001600281106200038c576200038b62000a60565b5b6020020151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001935050505092915050565b620003cd62000939565b6000620003d962000939565b6000604067ffffffffffffffff811115620003f957620003f862000a8f565b5b6040519080825280601f01601f1916602001820160405280156200042c5781602001600182028036833780820191505090505b5090506200044a878762000641640100000000026401000000009004565b925060005b6020811015620004ed578381602081106200046f576200046e62000a60565b5b1a7f010000000000000000000000000000000000000000000000000000000000000002828281518110620004a857620004a762000a60565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080620004e49062000abe565b9150506200044f565b5060005b60208110156200059d5785816020811062000511576200051062000a60565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000028260208362000544919062000b0c565b8151811062000558576200055762000a60565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080620005949062000abe565b915050620004f1565b508282600060028110620005b657620005b562000a60565b5b602002018181525050600281604051620005d1919062000bec565b602060405180830381855afa158015620005ef573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620006149190620009ba565b826001600281106200062b576200062a62000a60565b5b6020020181815250508193505050509392505050565b6000806000602867ffffffffffffffff81111562000664576200066362000a8f565b5b6040519080825280601f01601f191660200182016040528015620006975781602001600182028036833780820191505090505b509050600085604051602001620006af919062000c95565b604051602081830303815290604052905060005b60148110156200078857818181518110620006e357620006e262000a60565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000283828151811062000743576200074262000a60565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806200077f9062000abe565b915050620006c3565b50846040516020016200079c919062000c95565b604051602081830303815290604052905060005b60148110156200088357818181518110620007d057620007cf62000a60565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002836014836200082a919062000b0c565b815181106200083e576200083d62000a60565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806200087a9062000abe565b915050620007b0565b5060028260405162000896919062000bec565b602060405180830381855afa158015620008b4573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620008d99190620009ba565b925082935050505092915050565b82805482825590600052602060002090810192821562000926579160200282015b828111156200092557825182559160200191906001019062000908565b5b5090506200093591906200095b565b5090565b6040518060400160405280600290602082028036833780820191505090505090565b5b80821115620009765760008160009055506001016200095c565b5090565b600080fd5b6000819050919050565b62000994816200097f565b8114620009a057600080fd5b50565b600081519050620009b48162000989565b92915050565b600060208284031215620009d357620009d26200097a565b5b6000620009e384828501620009a3565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000a3282620009ec565b915062000a3f83620009ec565b92508282101562000a555762000a54620009f6565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600062000acb82620009ec565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141562000b015762000b00620009f6565b5b600182019050919050565b600062000b1982620009ec565b915062000b2683620009ec565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000b5e5762000b5d620009f6565b5b828201905092915050565b600081519050919050565b600081905092915050565b60005b8381101562000b9f57808201518184015260208101905062000b82565b8381111562000baf576000848401525b50505050565b600062000bc28262000b69565b62000bce818562000b74565b935062000be081856020860162000b7f565b80840191505092915050565b600062000bfa828462000bb5565b915081905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000c328262000c05565b9050919050565b60006c0100000000000000000000000082029050919050565b600062000c5f8262000c39565b9050919050565b600062000c738262000c52565b9050919050565b62000c8f62000c898262000c25565b62000c66565b82525050565b600062000ca3828462000c7a565b60148201915081905092915050565b6115298062000cc26000396000f3fe608060405234801561001057600080fd5b50600436106100b0576000357c0100000000000000000000000000000000000000000000000000000000900480638c661b36116100835780638c661b3614610175578063ae47ece0146101a5578063b68e6f31146101d5578063d0e95db114610205578063ff7496b414610235576100b0565b806301ffc9a7146100b557806322168e4f146100e557806350e0c6d3146101155780637d64bf1d14610145575b600080fd5b6100cf60048036038101906100ca9190610e46565b610265565b6040516100dc9190610e8e565b60405180910390f35b6100ff60048036038101906100fa9190610f3d565b610317565b60405161010c9190610f8c565b60405180910390f35b61012f600480360381019061012a9190610fa7565b61039c565b60405161013c9190610fe3565b60405180910390f35b61015f600480360381019061015a9190610f3d565b6103e7565b60405161016c9190610f8c565b60405180910390f35b61018f600480360381019061018a9190610ffe565b61046d565b60405161019c9190611106565b60405180910390f35b6101bf60048036038101906101ba9190611154565b61050b565b6040516101cc9190610e8e565b60405180910390f35b6101ef60048036038101906101ea9190611194565b6107b3565b6040516101fc9190610e8e565b60405180910390f35b61021f600480360381019061021a9190610fa7565b61080d565b60405161022c9190610fe3565b60405180910390f35b61024f600480360381019061024a91906111e7565b610859565b60405161025c9190611236565b60405180910390f35b60006327beb9107c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156102ba5760019050610312565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561030d5760019050610312565b600090505b919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061036957610368611251565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061043a57610439611251565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b606060008061047c8585610896565b915060016000838152602001908152602001600020549050600581815481106104a8576104a7611251565b5b906000526020600020018054806020026020016040519081016040528092919081815260200182805480156104fc57602002820191906000526020600020905b8154815260200190600101908083116104e8575b50505050509250505092915050565b6000610515610d5d565b60606000610524328787610b19565b9250600160008460006002811061053e5761053d611251565b5b6020020151815260200190815260200160002054905060008114156106ed57600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020329080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600582908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190610638929190610d7f565b506000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020869080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016005805490506106ea91906112af565b90505b80600160008560006002811061070657610705611251565b5b60200201518152602001908152602001600020819055506005818154811061073157610730611251565b5b906000526020600020018590806001815401808255809150506001900390600052602060002001600090919091909150556001600460008560016002811061077c5761077b611251565b5b6020020151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001935050505092915050565b60006107bd610d5d565b6107c8858585610b19565b905060046000826001600281106107e2576107e1611251565b5b6020020151815260200190815260200160002060009054906101000a900460ff169150509392505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6005828154811061086957600080fd5b90600052602060002001818154811061088157600080fd5b90600052602060002001600091509150505481565b6000806000602867ffffffffffffffff8111156108b6576108b56112e3565b5b6040519080825280601f01601f1916602001820160405280156108e85781602001600182028036833780820191505090505b5090506000856040516020016108fe9190611366565b604051602081830303815290604052905060005b60148110156109cd5781818151811061092e5761092d611251565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000283828151811061098b5761098a611251565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806109c590611381565b915050610912565b50846040516020016109df9190611366565b604051602081830303815290604052905060005b6014811015610aba57818181518110610a0f57610a0e611251565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000283601483610a6791906113ca565b81518110610a7857610a77611251565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610ab290611381565b9150506109f3565b50600282604051610acb919061149a565b602060405180830381855afa158015610ae8573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610b0b91906114c6565b925082935050505092915050565b610b21610d5d565b6000610b2b610d5d565b6000604067ffffffffffffffff811115610b4857610b476112e3565b5b6040519080825280601f01601f191660200182016040528015610b7a5781602001600182028036833780820191505090505b509050610b878787610896565b925060005b6020811015610c2057838160208110610ba857610ba7611251565b5b1a7f010000000000000000000000000000000000000000000000000000000000000002828281518110610bde57610bdd611251565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610c1890611381565b915050610b8c565b5060005b6020811015610cc457858160208110610c4057610c3f611251565b5b1a7f01000000000000000000000000000000000000000000000000000000000000000282602083610c7191906113ca565b81518110610c8257610c81611251565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610cbc90611381565b915050610c24565b508282600060028110610cda57610cd9611251565b5b602002018181525050600281604051610cf3919061149a565b602060405180830381855afa158015610d10573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d3391906114c6565b82600160028110610d4757610d46611251565b5b6020020181815250508193505050509392505050565b6040518060400160405280600290602082028036833780820191505090505090565b828054828255906000526020600020908101928215610dbb579160200282015b82811115610dba578251825591602001919060010190610d9f565b5b509050610dc89190610dcc565b5090565b5b80821115610de5576000816000905550600101610dcd565b5090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610e2381610dee565b8114610e2e57600080fd5b50565b600081359050610e4081610e1a565b92915050565b600060208284031215610e5c57610e5b610de9565b5b6000610e6a84828501610e31565b91505092915050565b60008115159050919050565b610e8881610e73565b82525050565b6000602082019050610ea36000830184610e7f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610ed482610ea9565b9050919050565b610ee481610ec9565b8114610eef57600080fd5b50565b600081359050610f0181610edb565b92915050565b6000819050919050565b610f1a81610f07565b8114610f2557600080fd5b50565b600081359050610f3781610f11565b92915050565b60008060408385031215610f5457610f53610de9565b5b6000610f6285828601610ef2565b9250506020610f7385828601610f28565b9150509250929050565b610f8681610ec9565b82525050565b6000602082019050610fa16000830184610f7d565b92915050565b600060208284031215610fbd57610fbc610de9565b5b6000610fcb84828501610ef2565b91505092915050565b610fdd81610f07565b82525050565b6000602082019050610ff86000830184610fd4565b92915050565b6000806040838503121561101557611014610de9565b5b600061102385828601610ef2565b925050602061103485828601610ef2565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61107d8161106a565b82525050565b600061108f8383611074565b60208301905092915050565b6000602082019050919050565b60006110b38261103e565b6110bd8185611049565b93506110c88361105a565b8060005b838110156110f95781516110e08882611083565b97506110eb8361109b565b9250506001810190506110cc565b5085935050505092915050565b6000602082019050818103600083015261112081846110a8565b905092915050565b6111318161106a565b811461113c57600080fd5b50565b60008135905061114e81611128565b92915050565b6000806040838503121561116b5761116a610de9565b5b600061117985828601610ef2565b925050602061118a8582860161113f565b9150509250929050565b6000806000606084860312156111ad576111ac610de9565b5b60006111bb86828701610ef2565b93505060206111cc86828701610ef2565b92505060406111dd8682870161113f565b9150509250925092565b600080604083850312156111fe576111fd610de9565b5b600061120c85828601610f28565b925050602061121d85828601610f28565b9150509250929050565b6112308161106a565b82525050565b600060208201905061124b6000830184611227565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112ba82610f07565b91506112c583610f07565b9250828210156112d8576112d7611280565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006c0100000000000000000000000082029050919050565b600061133682611312565b9050919050565b60006113488261132b565b9050919050565b61136061135b82610ec9565b61133d565b82525050565b6000611372828461134f565b60148201915081905092915050565b600061138c82610f07565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156113bf576113be611280565b5b600182019050919050565b60006113d582610f07565b91506113e083610f07565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561141557611414611280565b5b828201905092915050565b600081519050919050565b600081905092915050565b60005b83811015611454578082015181840152602081019050611439565b83811115611463576000848401525b50505050565b600061147482611420565b61147e818561142b565b935061148e818560208601611436565b80840191505092915050565b60006114a68284611469565b915081905092915050565b6000815190506114c081611128565b92915050565b6000602082840312156114dc576114db610de9565b5b60006114ea848285016114b1565b9150509291505056fea26469706673582212202b2faf629dd8ed0c1253030a53dc866c1429e8a5ff25d683335d4713c57d8c4964736f6c634300080b0033 \ No newline at end of file +60806040523480156200001157600080fd5b506040516200218e3803806200218e8339818101604052810190620000379190620009b9565b606060058190806001815401808255809150506001900390600052602060002001600090919091909150908051906020019062000076929190620008e6565b50600560016005805490506200008d919062000a24565b81548110620000a157620000a062000a5f565b5b9060005260206000200143409080600181540180825580915050600190039060005260206000200160009091909190915055620000ee3383620000f7640100000000026401000000009004565b50505062000c84565b60006200010362000938565b6060600062000123328787620003c2640100000000026401000000009004565b9250600160008460006002811062000140576200013f62000a5f565b5b6020020151815260200190815260200160002054905060008103620002f357600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020329080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506005829080600181540180825580915050600190039060005260206000200160009091909190915090805190602001906200023c929190620008e6565b506000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020869080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600580549050620002f0919062000a24565b90505b8060016000856000600281106200030f576200030e62000a5f565b5b6020020151815260200190815260200160002081905550600581815481106200033d576200033c62000a5f565b5b90600052602060002001859080600181540180825580915050600190039060005260206000200160009091909190915055600160046000856001600281106200038b576200038a62000a5f565b5b6020020151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001935050505092915050565b620003cc62000938565b6000620003d862000938565b6000604067ffffffffffffffff811115620003f857620003f762000a8e565b5b6040519080825280601f01601f1916602001820160405280156200042b5781602001600182028036833780820191505090505b50905062000449878762000640640100000000026401000000009004565b925060005b6020811015620004ec578381602081106200046e576200046d62000a5f565b5b1a7f010000000000000000000000000000000000000000000000000000000000000002828281518110620004a757620004a662000a5f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080620004e39062000abd565b9150506200044e565b5060005b60208110156200059c5785816020811062000510576200050f62000a5f565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000028260208362000543919062000b0a565b8151811062000557576200055662000a5f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080620005939062000abd565b915050620004f0565b508282600060028110620005b557620005b462000a5f565b5b602002018181525050600281604051620005d0919062000bbe565b602060405180830381855afa158015620005ee573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620006139190620009b9565b826001600281106200062a576200062962000a5f565b5b6020020181815250508193505050509392505050565b6000806000602867ffffffffffffffff81111562000663576200066262000a8e565b5b6040519080825280601f01601f191660200182016040528015620006965781602001600182028036833780820191505090505b509050600085604051602001620006ae919062000c67565b604051602081830303815290604052905060005b60148110156200078757818181518110620006e257620006e162000a5f565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000283828151811062000742576200074162000a5f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806200077e9062000abd565b915050620006c2565b50846040516020016200079b919062000c67565b604051602081830303815290604052905060005b60148110156200088257818181518110620007cf57620007ce62000a5f565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000028360148362000829919062000b0a565b815181106200083d576200083c62000a5f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080620008799062000abd565b915050620007af565b5060028260405162000895919062000bbe565b602060405180830381855afa158015620008b3573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620008d89190620009b9565b925082935050505092915050565b82805482825590600052602060002090810192821562000925579160200282015b828111156200092457825182559160200191906001019062000907565b5b5090506200093491906200095a565b5090565b6040518060400160405280600290602082028036833780820191505090505090565b5b80821115620009755760008160009055506001016200095b565b5090565b600080fd5b6000819050919050565b62000993816200097e565b81146200099f57600080fd5b50565b600081519050620009b38162000988565b92915050565b600060208284031215620009d257620009d162000979565b5b6000620009e284828501620009a2565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000a3182620009eb565b915062000a3e83620009eb565b925082820390508181111562000a595762000a58620009f5565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600062000aca82620009eb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362000aff5762000afe620009f5565b5b600182019050919050565b600062000b1782620009eb565b915062000b2483620009eb565b925082820190508082111562000b3f5762000b3e620009f5565b5b92915050565b600081519050919050565b600081905092915050565b60005b8381101562000b7b57808201518184015260208101905062000b5e565b60008484015250505050565b600062000b948262000b45565b62000ba0818562000b50565b935062000bb281856020860162000b5b565b80840191505092915050565b600062000bcc828462000b87565b915081905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000c048262000bd7565b9050919050565b60006c0100000000000000000000000082029050919050565b600062000c318262000c0b565b9050919050565b600062000c458262000c24565b9050919050565b62000c6162000c5b8262000bf7565b62000c38565b82525050565b600062000c75828462000c4c565b60148201915081905092915050565b6114fa8062000c946000396000f3fe608060405234801561001057600080fd5b50600436106100b0576000357c0100000000000000000000000000000000000000000000000000000000900480638c661b36116100835780638c661b3614610175578063ae47ece0146101a5578063b68e6f31146101d5578063d0e95db114610205578063ff7496b414610235576100b0565b806301ffc9a7146100b557806322168e4f146100e557806350e0c6d3146101155780637d64bf1d14610145575b600080fd5b6100cf60048036038101906100ca9190610e43565b610265565b6040516100dc9190610e8b565b60405180910390f35b6100ff60048036038101906100fa9190610f3a565b610315565b60405161010c9190610f89565b60405180910390f35b61012f600480360381019061012a9190610fa4565b61039a565b60405161013c9190610fe0565b60405180910390f35b61015f600480360381019061015a9190610f3a565b6103e5565b60405161016c9190610f89565b60405180910390f35b61018f600480360381019061018a9190610ffb565b61046b565b60405161019c9190611103565b60405180910390f35b6101bf60048036038101906101ba9190611151565b610509565b6040516101cc9190610e8b565b60405180910390f35b6101ef60048036038101906101ea9190611191565b6107b0565b6040516101fc9190610e8b565b60405180910390f35b61021f600480360381019061021a9190610fa4565b61080a565b60405161022c9190610fe0565b60405180910390f35b61024f600480360381019061024a91906111e4565b610856565b60405161025c9190611233565b60405180910390f35b60006327beb9107c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036102b95760019050610310565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361030b5760019050610310565b600090505b919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106103675761036661124e565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106104385761043761124e565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b606060008061047a8585610893565b915060016000838152602001908152602001600020549050600581815481106104a6576104a561124e565b5b906000526020600020018054806020026020016040519081016040528092919081815260200182805480156104fa57602002820191906000526020600020905b8154815260200190600101908083116104e6575b50505050509250505092915050565b6000610513610d5a565b60606000610522328787610b16565b9250600160008460006002811061053c5761053b61124e565b5b60200201518152602001908152602001600020549050600081036106ea57600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020329080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600582908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190610635929190610d7c565b506000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020869080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016005805490506106e791906112ac565b90505b8060016000856000600281106107035761070261124e565b5b60200201518152602001908152602001600020819055506005818154811061072e5761072d61124e565b5b90600052602060002001859080600181540180825580915050600190039060005260206000200160009091909190915055600160046000856001600281106107795761077861124e565b5b6020020151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001935050505092915050565b60006107ba610d5a565b6107c5858585610b16565b905060046000826001600281106107df576107de61124e565b5b6020020151815260200190815260200160002060009054906101000a900460ff169150509392505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6005828154811061086657600080fd5b90600052602060002001818154811061087e57600080fd5b90600052602060002001600091509150505481565b6000806000602867ffffffffffffffff8111156108b3576108b26112e0565b5b6040519080825280601f01601f1916602001820160405280156108e55781602001600182028036833780820191505090505b5090506000856040516020016108fb9190611363565b604051602081830303815290604052905060005b60148110156109ca5781818151811061092b5761092a61124e565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000028382815181106109885761098761124e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806109c29061137e565b91505061090f565b50846040516020016109dc9190611363565b604051602081830303815290604052905060005b6014811015610ab757818181518110610a0c57610a0b61124e565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000283601483610a6491906113c6565b81518110610a7557610a7461124e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610aaf9061137e565b9150506109f0565b50600282604051610ac8919061146b565b602060405180830381855afa158015610ae5573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610b089190611497565b925082935050505092915050565b610b1e610d5a565b6000610b28610d5a565b6000604067ffffffffffffffff811115610b4557610b446112e0565b5b6040519080825280601f01601f191660200182016040528015610b775781602001600182028036833780820191505090505b509050610b848787610893565b925060005b6020811015610c1d57838160208110610ba557610ba461124e565b5b1a7f010000000000000000000000000000000000000000000000000000000000000002828281518110610bdb57610bda61124e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610c159061137e565b915050610b89565b5060005b6020811015610cc157858160208110610c3d57610c3c61124e565b5b1a7f01000000000000000000000000000000000000000000000000000000000000000282602083610c6e91906113c6565b81518110610c7f57610c7e61124e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610cb99061137e565b915050610c21565b508282600060028110610cd757610cd661124e565b5b602002018181525050600281604051610cf0919061146b565b602060405180830381855afa158015610d0d573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d309190611497565b82600160028110610d4457610d4361124e565b5b6020020181815250508193505050509392505050565b6040518060400160405280600290602082028036833780820191505090505090565b828054828255906000526020600020908101928215610db8579160200282015b82811115610db7578251825591602001919060010190610d9c565b5b509050610dc59190610dc9565b5090565b5b80821115610de2576000816000905550600101610dca565b5090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610e2081610deb565b8114610e2b57600080fd5b50565b600081359050610e3d81610e17565b92915050565b600060208284031215610e5957610e58610de6565b5b6000610e6784828501610e2e565b91505092915050565b60008115159050919050565b610e8581610e70565b82525050565b6000602082019050610ea06000830184610e7c565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610ed182610ea6565b9050919050565b610ee181610ec6565b8114610eec57600080fd5b50565b600081359050610efe81610ed8565b92915050565b6000819050919050565b610f1781610f04565b8114610f2257600080fd5b50565b600081359050610f3481610f0e565b92915050565b60008060408385031215610f5157610f50610de6565b5b6000610f5f85828601610eef565b9250506020610f7085828601610f25565b9150509250929050565b610f8381610ec6565b82525050565b6000602082019050610f9e6000830184610f7a565b92915050565b600060208284031215610fba57610fb9610de6565b5b6000610fc884828501610eef565b91505092915050565b610fda81610f04565b82525050565b6000602082019050610ff56000830184610fd1565b92915050565b6000806040838503121561101257611011610de6565b5b600061102085828601610eef565b925050602061103185828601610eef565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61107a81611067565b82525050565b600061108c8383611071565b60208301905092915050565b6000602082019050919050565b60006110b08261103b565b6110ba8185611046565b93506110c583611057565b8060005b838110156110f65781516110dd8882611080565b97506110e883611098565b9250506001810190506110c9565b5085935050505092915050565b6000602082019050818103600083015261111d81846110a5565b905092915050565b61112e81611067565b811461113957600080fd5b50565b60008135905061114b81611125565b92915050565b6000806040838503121561116857611167610de6565b5b600061117685828601610eef565b92505060206111878582860161113c565b9150509250929050565b6000806000606084860312156111aa576111a9610de6565b5b60006111b886828701610eef565b93505060206111c986828701610eef565b92505060406111da8682870161113c565b9150509250925092565b600080604083850312156111fb576111fa610de6565b5b600061120985828601610f25565b925050602061121a85828601610f25565b9150509250929050565b61122d81611067565b82525050565b60006020820190506112486000830184611224565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112b782610f04565b91506112c283610f04565b92508282039050818111156112da576112d961127d565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006c0100000000000000000000000082029050919050565b60006113338261130f565b9050919050565b600061134582611328565b9050919050565b61135d61135882610ec6565b61133a565b82525050565b600061136f828461134c565b60148201915081905092915050565b600061138982610f04565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113bb576113ba61127d565b5b600182019050919050565b60006113d182610f04565b91506113dc83610f04565b92508282019050808211156113f4576113f361127d565b5b92915050565b600081519050919050565b600081905092915050565b60005b8381101561142e578082015181840152602081019050611413565b60008484015250505050565b6000611445826113fa565b61144f8185611405565b935061145f818560208601611410565b80840191505092915050565b6000611477828461143a565b915081905092915050565b60008151905061149181611125565b92915050565b6000602082840312156114ad576114ac610de6565b5b60006114bb84828501611482565b9150509291505056fea2646970667358221220759dd0747f2dbc52fe85f93963bb4768d5d1a8dd59bdcbfa6c35d8386559cc0c64736f6c63430008110033 \ No newline at end of file