Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ERC1155Crafts
- Optimization enabled
- false
- Compiler version
- v0.8.20+commit.a1b79de6
- EVM Version
- paris
- Verified at
- 2024-06-03T08:51:38.640987Z
Constructor Arguments
0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f486f706576657273652043726166740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a437261667420466f6d756c6120666f7220486f70657665727365000000000000
Arg [0] (string) : Hopeverse Craft
Arg [1] (string) : Craft Fomula for Hopeverse
contracts/Craftable/ERC1155Crafts.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../base/TokenOperatableTemplateContract.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; contract ERC1155Crafts is TokenOperatableTemplateContract { using Math for uint256; using ERC165Checker for address; struct CraftInput{ address token_address; uint256 token_id; uint256 amount; } struct CraftOutput{ address token_address; uint256 token_id; uint256 amount; bool multi_token; } struct CraftFormula { CraftInput[] inputs; CraftOutput[] outputs; } uint256 private _templateIds; mapping(uint256 => CraftFormula) private templates; event OnCraftFoumulaDefined(uint256 indexed template_id,CraftFormula formula); event OnCraftFormulaUpdated(uint256 indexed template_id,CraftFormula formula); constructor(string memory name_,string memory description_) TokenOperatableTemplateContract(name_,description_) { } function get_last_template_id() public view virtual override returns (uint256) {return _templateIds;} function _fill_template_inputs(uint256 tpl_id,CraftInput[] memory inputs) internal { for(uint256 i = 0; i < inputs.length; i++){ require(_is_operatable_erc1155(inputs[i].token_address),"I_BAD_TOKEN"); IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(inputs[i].token_address); require(asErc1155.isTokenDefined(inputs[i].token_id),"NO_TOKEN_ID"); templates[tpl_id].inputs.push(inputs[i]); } } function _fill_template_outputs(uint256 tpl_id,CraftOutput[] memory ouputs) internal { for(uint256 i = 0; i < ouputs.length; i++){ bool is_erc1155 = _is_operatable_erc1155(ouputs[i].token_address); bool is_erc721 = _is_operatable_erc721(ouputs[i].token_address); require(is_erc1155 || is_erc721,"O_BAD_TOKEN"); if(is_erc1155){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(ouputs[i].token_address); require(asErc1155.isTokenDefined(ouputs[i].token_id),"NO_TOKEN_ID"); } templates[tpl_id].outputs.push(CraftOutput(ouputs[i].token_address,ouputs[i].token_id,ouputs[i].amount,is_erc1155)); } } function define_template(string memory name,string memory desc,uint256 op_price, bool start_enabled,address merchant,address currency, CraftInput[] memory inputs,CraftOutput[] memory outputs) external onlyOwner returns (uint256){ (bool result,uint256 tpl_id) = _templateIds.tryAdd(1); _templateIds = tpl_id; require(result,"TPL_ID_OVERFLOW"); _fill_template_metadata(tpl_id,name,desc,op_price,start_enabled,merchant,currency); _fill_template_inputs(tpl_id,inputs); _fill_template_outputs(tpl_id,outputs); emit OnCraftFoumulaDefined(tpl_id,templates[tpl_id]); return tpl_id; } function udpate_template_formula(uint256 template_id, CraftInput[] memory inputs,CraftOutput[] memory outputs) external onlyOwner { require(is_defined(template_id),"NOT_DEFINED"); delete templates[template_id].inputs; delete templates[template_id].outputs; _fill_template_inputs(template_id,inputs); _fill_template_outputs(template_id,outputs); emit OnCraftFormulaUpdated(template_id,templates[template_id]); } function craft(uint256 template_id,uint256 applyCount) external payable{ require(is_enabled(template_id),"TEMPLATE_DISABLED"); _check_valid_token(template_id); CraftFormula memory template = templates[template_id]; for(uint8 i = 0; i < template.inputs.length; i++) { (bool result,uint256 total) = template.inputs[i].amount.tryMul(applyCount); require(result,"TOTAL_OVERFLOW"); IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(template.inputs[i].token_address); asErc1155.burnNFTFor(msg.sender, template.inputs[i].token_id,total); } for(uint8 i = 0; i < template.outputs.length; i++) { (bool result,uint256 total) = template.outputs[i].amount.tryMul(applyCount); require(result,"TOTAL_OVERFLOW"); if(template.outputs[i].multi_token){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(template.outputs[i].token_address); asErc1155.mintNFTFor(msg.sender, template.outputs[i].token_id,total); } else{ IOperatableERC721Token asErc721 = IOperatableERC721Token(template.outputs[i].token_address); asErc721.mintNFTsFor(msg.sender, total); } } consume_operation_cost(template_id,applyCount); } function onUndefineTemplate(uint256 template_id) internal virtual override{ delete templates[template_id]; } function get_template_formula(uint256 template_id) external view returns (address[] memory,uint256[] memory,uint256[] memory,address[] memory,uint256[] memory,uint256[] memory,bool[] memory){ CraftFormula memory template = templates[template_id]; address[] memory _input_addresses = new address[](template.inputs.length); uint256[] memory _input_token_ids = new uint256[](template.inputs.length); uint256[] memory _input_amounts = new uint256[](template.inputs.length); for(uint8 i = 0; i < template.inputs.length; i++){ _input_addresses[i] = template.inputs[i].token_address; _input_token_ids[i] = template.inputs[i].token_id; _input_amounts[i] = template.inputs[i].amount; } address[] memory _output_addresses = new address[](template.outputs.length); uint256[] memory _output_token_ids = new uint256[](template.outputs.length); uint256[] memory _output_amounts = new uint256[](template.outputs.length); bool[] memory _output_multitokens = new bool[](template.outputs.length); for(uint8 i = 0; i < template.outputs.length; i++){ _output_addresses[i] = template.outputs[i].token_address; _output_token_ids[i] = template.outputs[i].token_id; _output_amounts[i] = template.outputs[i].amount; _output_multitokens[i] = template.outputs[i].multi_token; } return (_input_addresses,_input_token_ids,_input_amounts,_output_addresses,_output_token_ids,_output_amounts,_output_multitokens); } function _check_valid_token(uint256 tpl_id) internal view { uint256 input_count = templates[tpl_id].inputs.length; for(uint256 i = 0; i < input_count; i++){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(templates[tpl_id].inputs[i].token_address); require(asErc1155.isTokenDefined(templates[tpl_id].inputs[i].token_id),"NO_TOKEN_ID"); } uint256 output_count = templates[tpl_id].outputs.length; for(uint256 i = 0; i < output_count; i++){ bool is_erc1155 = templates[tpl_id].outputs[i].multi_token; if(is_erc1155){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(templates[tpl_id].outputs[i].token_address); require(asErc1155.isTokenDefined(templates[tpl_id].outputs[i].token_id),"NO_TOKEN_ID"); } } } }
contracts/Interfaces/ITokenOperatableTemplate.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITokenOperatableTemplate { function get_name() external view returns (string memory); function get_description() external view returns (string memory); function get_template_metadata(uint256 template_id) external view returns (string memory,string memory,uint256,bool,address); function is_template_defined(uint256 template_id) external view returns (bool); function is_template_enabled(uint256 template_id) external view returns (bool); }
contracts/base/TokenOperatableTemplateContract.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../Interfaces/ITokenOperatableTemplate.sol"; import "../Interfaces/IOperatableERC1155Token.sol"; import "../Interfaces/IOperatableERC721Token.sol"; abstract contract TokenOperatableTemplateContract is Ownable2Step,ITokenOperatableTemplate { using Math for uint256; using ERC165Checker for address; string private name; string private description; mapping(uint256 => string) private template_names; mapping(uint256 => string) private template_descs; mapping(uint256 => uint256) private operation_prices; mapping(uint256 => bool) private template_enabled; //For some reason in marketing we have template specific merchant if not set just use merchant address. mapping(uint256 => address) private template_merchants; mapping(uint256 => address) private template_currencies; address private merchant_address; address private currency_address = address(0); mapping(address => bool) private _operators; error OperatorAccount(address account); constructor(string memory name_,string memory description_) Ownable(msg.sender) { name = name_; description = description_; merchant_address = msg.sender; } event OnTemplateUndefined(uint256 template_id); function set_currency(address addr) external onlyOperator { require(addr == address(0) || addr.supportsInterface(type(IERC20).interfaceId),"UNSUPPORT_CURRENCY"); currency_address = addr; } function set_merchant(address merchant) external onlyOperator { require((merchant_address != merchant) && (merchant != address(0)),"INVALID_MERCHANT"); merchant_address = merchant; } function get_last_template_id() public view virtual returns (uint256) {return 0;} function get_currency_address(uint256 template_id) public view returns (address){ address addr = template_currencies[template_id]; return addr != address(0) ? addr : currency_address; } function get_merchant_address(uint256 template_id) public view returns(address){ address addr = template_merchants[template_id]; return addr != address(0) ? addr : merchant_address; } function undefine_templates(uint256[] memory template_ids) external onlyOperator { for(uint256 i = 0; i < template_ids.length; i++) _undefine_template(template_ids[i]); } function update_template_names(uint256[] memory template_ids,string[] memory template_names_) external onlyOperator { require(template_ids.length == template_names_.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _udpate_template_name(template_ids[i],template_names_[i]); } function update_template_descs(uint256[] memory template_ids,string[] memory descs) external onlyOperator { require(template_ids.length == descs.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_desc(template_ids[i],descs[i]); } function update_operation_prices(uint256[] memory template_ids,uint256[] memory prices) external onlyOperator { require(template_ids.length == prices.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_operation_price(template_ids[i],prices[i]); } function update_template_merchants(uint256[] memory template_ids,address[] memory merchants) external onlyOperator { require(template_ids.length == merchants.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_merchant(template_ids[i],merchants[i]); } function update_template_currencies(uint256[] memory template_ids,address[] memory currencies) external onlyOperator { require(template_ids.length == currencies.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_currency(template_ids[i],currencies[i]); } function enable_templates(uint256[] memory template_ids,bool[] memory enables) external onlyOperator { require(template_ids.length == enables.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _enable_template(template_ids[i],enables[i]); } function is_defined(uint256 template_id) public view returns(bool) {return (bytes(template_names[template_id]).length > 0);} function is_enabled(uint256 template_id) public view returns(bool) {return template_enabled[template_id];} function _undefine_template(uint256 template_id) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); _clear_template_metadata(template_id); onUndefineTemplate(template_id); emit OnTemplateUndefined(template_id); } function _fill_template_metadata(uint256 template_id,string memory name_,string memory desc,uint256 op_price,bool start_enabled,address merchant,address currency) internal{ template_names[template_id] = name_; template_descs[template_id] = desc; operation_prices[template_id] = op_price; template_enabled[template_id] = start_enabled; template_merchants[template_id] = merchant; template_currencies[template_id] = currency; } function _clear_template_metadata(uint256 template_id) internal{ delete template_names[template_id]; delete template_descs[template_id]; delete operation_prices[template_id]; delete template_enabled[template_id]; delete template_merchants[template_id]; delete template_currencies[template_id]; } function _udpate_template_name(uint256 template_id,string memory name_) internal{ require(bytes(template_names[template_id]).length > 0,"NO_TPL_DEFINED"); require(bytes(name_).length > 0,"NO_TPL_NAME"); template_names[template_id] = name_; } function _update_template_desc(uint256 template_id,string memory desc) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); template_descs[template_id] = desc; } function _update_operation_price(uint256 template_id,uint256 price) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); operation_prices[template_id] = price; } function _update_template_merchant(uint256 template_id,address merchant) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); require(merchant != address(0),"NULL_ADDRESS"); template_merchants[template_id] = merchant; } function _update_template_currency(uint256 template_id,address currency) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); require(currency != address(0),"NULL_ADDRESS"); template_currencies[template_id] = currency; } function _enable_template(uint256 template_id,bool enabled) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); template_enabled[template_id] = enabled; } function consume_operation_cost(uint256 template_id,uint256 applyCount) internal { require(applyCount > 0,"ZERO_APPLYCOUNT"); uint256 op_price = operation_prices[template_id]; if(op_price == 0) return; address _merchant_addr = get_merchant_address(template_id); require(_merchant_addr != address(0),"NO_MERCHANT_ADDR"); (bool total_op_cost_result,uint256 total_op_cost) = op_price.tryMul(applyCount); require(total_op_cost_result,"OP_COST_OVERFLOW"); address _currency_addr = get_currency_address(template_id); if(_currency_addr != address(0)){ uint256 available_balance = IERC20(_currency_addr).balanceOf(msg.sender); require(available_balance >= total_op_cost,"UNSUFFICIENT_BALANCE"); IERC20(_currency_addr).transferFrom(msg.sender, _merchant_addr, total_op_cost); if(msg.value > 0) payable(msg.sender).transfer(msg.value); } else{ require(msg.value >= total_op_cost,"UNSUFFICIENT_BALANCE"); uint256 remain_value = msg.value - total_op_cost; payable(_merchant_addr).transfer(total_op_cost); payable(msg.sender).transfer(remain_value); } } function isTemplateValid(uint256) internal virtual returns (bool) {return false;} function onUndefineTemplate(uint256) internal virtual {} function get_template_metadata(uint256 template_id) external view virtual override returns (string memory,string memory,uint256,bool,address){ return (template_names[template_id],template_descs[template_id],operation_prices[template_id],template_enabled[template_id],get_merchant_address(template_id)); } function is_template_defined(uint256 template_id) external view virtual override returns (bool){return is_defined(template_id);} function is_template_enabled(uint256 template_id) external view virtual override returns (bool){return template_enabled[template_id];} function get_name() external view virtual override returns (string memory){return name;} function get_description() external view virtual override returns (string memory){return description;} function set_operator(address addr,bool set) external virtual onlyOwner { require(addr != address(0),"Null Address allowed"); _operators[addr] = set; } function as_operator(address addr) public view virtual returns(bool) { return _operators[addr]; } modifier onlyOperator() { _checkIsOperator(); _; } function _check_operator(address addr) internal view virtual returns(bool) { return _operators[addr]; } function _checkIsOperator() internal view virtual { address _sender = _msgSender(); if ((owner() != _sender) && (!_check_operator(_sender))) { revert OperatorAccount(_sender); } } function _is_operatable_erc1155(address addr) internal view returns(bool) { return (addr != address(0)) && addr.supportsInterface(type(IOperatableERC1155Token).interfaceId); } function _is_operatable_erc721(address addr) internal view returns (bool){ return (addr != address(0)) && addr.supportsInterface(type(IOperatableERC721Token).interfaceId); } }
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
@openzeppelin/contracts/access/Ownable2Step.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; import {Ownable} from "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } }
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
@openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
@openzeppelin/contracts/utils/introspection/ERC165Checker.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. */ function getSupportedInterfaces( address account, bytes4[] memory interfaceIds ) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId)); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
@openzeppelin/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
contracts/Interfaces/IOperatableERC1155Token.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IOperatableERC1155Token { //Get Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function contractURI() external view returns (string memory); //Set Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function setContractURI(string memory contractURI_) external; function lastTokenIds() external view returns (uint256); //Return token ids and amount. function ownedTokenOf(address _addr) external view returns(uint256[] memory,uint256[] memory); function canMintForAmount(uint256 tokenId,uint256 tokmentAmount) external view returns(bool); function canMintBulkForAmount(uint256[] memory tokenIds,uint256[] memory tokmentAmounts) external view returns(bool); //Mint nft for some user by contact owner. use for bleeding/crafting or mint NFT from App function mintNFTsFor(address _addr,uint256[] memory tokenIds,uint256[] memory amounts) external; //Burn nft for some user by contact owner. use for crafting or burn NFT from App function burnNFTsFor(address _addr,uint256[] memory tokenIds,uint256[] memory amounts) external; //Mint nft for some user by contact owner. use for bleeding/crafting or mint NFT from App function mintNFTFor(address _addr,uint256 tokenId,uint256 amount) external; //Burn nft for some user by contact owner. use for crafting or burn NFT from App function burnNFTFor(address _addr,uint256 tokenId,uint256 amount) external; //Get total supply of Token function totalSupply(uint256 tokenId) external view returns(uint256); //Token id is defined or not function isTokenDefined(uint256 token_id) external view returns (bool); }
contracts/Interfaces/IOperatableERC721Token.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Interface of use for all of ScrewUp NFT token. */ interface IOperatableERC721Token { //Get Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function contractURI() external view returns (string memory); //Set Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function setContractURI(string memory contractURI_) external; //Get all of items for address. function ownedTokenOf(address _addr) external view returns (uint256[] memory); //Check address is really own item. function isOwnedToken(address _addr,uint256 tokenId) external view returns(bool); //Update token URI for token Id function updateTokenURI(uint256 tokenId,string memory tokenURI) external; //Mint nft (unreveal only) for some user by contact owner. use for bleeding or mint NFT from App function mintNFTsFor(address addr,uint256 amount) external; //Mint nft for some user by contact owner. use for bleeding or mint NFT from App function mintNFTFor(address addr,string memory tokenURI) external; //Mint nft for some user by contact owner. use for bleeding or mint NFT from App function burnNFTFor(address addr,uint256 tokenId) external; //Update display name of token when unreveal. function getUnrevealName() external view returns (string memory); //Update token uri of token when unreveal. function getUnrevealTokenUri() external view returns (string memory); function getUnrevealMetadata() external view returns (string memory,string memory); }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":false},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"description_","internalType":"string"}]},{"type":"error","name":"OperatorAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"OnCraftFormulaUpdated","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Crafts.CraftFormula","indexed":false,"components":[{"type":"tuple[]","name":"inputs","internalType":"struct ERC1155Crafts.CraftInput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Crafts.CraftOutput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bool","name":"multi_token","internalType":"bool"}]}]}],"anonymous":false},{"type":"event","name":"OnCraftFoumulaDefined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Crafts.CraftFormula","indexed":false,"components":[{"type":"tuple[]","name":"inputs","internalType":"struct ERC1155Crafts.CraftInput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Crafts.CraftOutput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bool","name":"multi_token","internalType":"bool"}]}]}],"anonymous":false},{"type":"event","name":"OnTemplateUndefined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"as_operator","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"craft","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"uint256","name":"applyCount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"define_template","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"desc","internalType":"string"},{"type":"uint256","name":"op_price","internalType":"uint256"},{"type":"bool","name":"start_enabled","internalType":"bool"},{"type":"address","name":"merchant","internalType":"address"},{"type":"address","name":"currency","internalType":"address"},{"type":"tuple[]","name":"inputs","internalType":"struct ERC1155Crafts.CraftInput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Crafts.CraftOutput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bool","name":"multi_token","internalType":"bool"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enable_templates","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"bool[]","name":"enables","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_currency_address","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"get_description","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_last_template_id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_merchant_address","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"get_name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"address[]","name":"","internalType":"address[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"bool[]","name":"","internalType":"bool[]"}],"name":"get_template_formula","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"},{"type":"string","name":"","internalType":"string"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"},{"type":"address","name":"","internalType":"address"}],"name":"get_template_metadata","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_defined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_enabled","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_template_defined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_template_enabled","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_currency","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_merchant","inputs":[{"type":"address","name":"merchant","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_operator","inputs":[{"type":"address","name":"addr","internalType":"address"},{"type":"bool","name":"set","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"udpate_template_formula","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"tuple[]","name":"inputs","internalType":"struct ERC1155Crafts.CraftInput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Crafts.CraftOutput[]","components":[{"type":"address","name":"token_address","internalType":"address"},{"type":"uint256","name":"token_id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bool","name":"multi_token","internalType":"bool"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"undefine_templates","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_operation_prices","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"prices","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_currencies","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"address[]","name":"currencies","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_descs","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"string[]","name":"descs","internalType":"string[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_merchants","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"address[]","name":"merchants","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_names","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"string[]","name":"template_names_","internalType":"string[]"}]}]
Contract Creation Code
0x60806040526000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200005357600080fd5b50604051620067a3380380620067a3833981810160405281019062000079919062000402565b818133600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000f15760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000e89190620004cc565b60405180910390fd5b62000102816200017260201b60201c565b50816002908162000114919062000734565b50806003908162000126919062000734565b5033600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050506200081b565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055620001a881620001ab60201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002d8826200028d565b810181811067ffffffffffffffff82111715620002fa57620002f96200029e565b5b80604052505050565b60006200030f6200026f565b90506200031d8282620002cd565b919050565b600067ffffffffffffffff82111562000340576200033f6200029e565b5b6200034b826200028d565b9050602081019050919050565b60005b83811015620003785780820151818401526020810190506200035b565b60008484015250505050565b60006200039b620003958462000322565b62000303565b905082815260208101848484011115620003ba57620003b962000288565b5b620003c784828562000358565b509392505050565b600082601f830112620003e757620003e662000283565b5b8151620003f984826020860162000384565b91505092915050565b600080604083850312156200041c576200041b62000279565b5b600083015167ffffffffffffffff8111156200043d576200043c6200027e565b5b6200044b85828601620003cf565b925050602083015167ffffffffffffffff8111156200046f576200046e6200027e565b5b6200047d85828601620003cf565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004b48262000487565b9050919050565b620004c681620004a7565b82525050565b6000602082019050620004e36000830184620004bb565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200053c57607f821691505b602082108103620005525762000551620004f4565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005bc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057d565b620005c886836200057d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006156200060f6200060984620005e0565b620005ea565b620005e0565b9050919050565b6000819050919050565b6200063183620005f4565b6200064962000640826200061c565b8484546200058a565b825550505050565b600090565b6200066062000651565b6200066d81848462000626565b505050565b5b8181101562000695576200068960008262000656565b60018101905062000673565b5050565b601f821115620006e457620006ae8162000558565b620006b9846200056d565b81016020851015620006c9578190505b620006e1620006d8856200056d565b83018262000672565b50505b505050565b600082821c905092915050565b60006200070960001984600802620006e9565b1980831691505092915050565b6000620007248383620006f6565b9150826002028217905092915050565b6200073f82620004e9565b67ffffffffffffffff8111156200075b576200075a6200029e565b5b62000767825462000523565b6200077482828562000699565b600060209050601f831160018114620007ac576000841562000797578287015190505b620007a3858262000716565b86555062000813565b601f198416620007bc8662000558565b60005b82811015620007e657848901518255600182019150602085019450602081019050620007bf565b8683101562000806578489015162000802601f891682620006f6565b8355505b6001600288020188555050505b505050505050565b615f78806200082b6000396000f3fe6080604052600436106101cd5760003560e01c806376967cbf116100f7578063bb21ac5411610095578063df8e759a11610064578063df8e759a1461067d578063e30c3978146106ba578063e55661bd146106e5578063f2fde38b14610722576101cd565b8063bb21ac54146105ad578063c9e0ac16146105d6578063dd99b73d146105ff578063dda0da0014610640576101cd565b80638da5cb5b116100d15780638da5cb5b146104df578063a3066e431461050a578063b8c7871a14610533578063ba84860814610570576101cd565b806376967cbf1461047457806379ba50971461049d578063839d7f11146104b4576101cd565b8063289137a11161016f5780633f84dc1b1161013e5780633f84dc1b146103e05780635458c28e1461040b5780636586bb7014610434578063715018a61461045d576101cd565b8063289137a11461034757806330546c9b146103635780633a525c291461038c5780633b9ebeec146103b7576101cd565b8063189357ff116101ab578063189357ff1461026157806319df1182146102a45780631a7db56e146102e1578063284293cf1461030a576101cd565b806308319627146101d25780630f6bec9a1461020f5780630fe4215914610238575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f4919061429e565b61074b565b60405161020691906143d3565b60405180910390f35b34801561021b57600080fd5b50610236600480360381019061023191906144b1565b610837565b005b34801561024457600080fd5b5061025f600480360381019061025a9190614529565b6108e5565b005b34801561026d57600080fd5b5061028860048036038101906102839190614569565b6109b7565b60405161029b97969594939291906147d0565b60405180910390f35b3480156102b057600080fd5b506102cb60048036038101906102c69190614569565b61109f565b6040516102d8919061487f565b60405180910390f35b3480156102ed57600080fd5b506103086004803603810190610303919061495d565b6110c9565b005b34801561031657600080fd5b50610331600480360381019061032c9190614569565b611177565b60405161033e919061487f565b60405180910390f35b610361600480360381019061035c91906149d5565b6111a1565b005b34801561036f57600080fd5b5061038a60048036038101906103859190614a15565b611767565b005b34801561039857600080fd5b506103a16117b5565b6040516103ae9190614add565b60405180910390f35b3480156103c357600080fd5b506103de60048036038101906103d99190614bc2565b611847565b005b3480156103ec57600080fd5b506103f56118f5565b60405161040291906143d3565b60405180910390f35b34801561041757600080fd5b50610432600480360381019061042d919061495d565b6118ff565b005b34801561044057600080fd5b5061045b60048036038101906104569190614c3a565b6119ad565b005b34801561046957600080fd5b50610472611ac3565b005b34801561048057600080fd5b5061049b60048036038101906104969190614d48565b611ad7565b005b3480156104a957600080fd5b506104b2611b85565b005b3480156104c057600080fd5b506104c9611c14565b6040516104d69190614add565b60405180910390f35b3480156104eb57600080fd5b506104f4611ca6565b6040516105019190614dcf565b60405180910390f35b34801561051657600080fd5b50610531600480360381019061052c9190614d48565b611ccf565b005b34801561053f57600080fd5b5061055a60048036038101906105559190614569565b611d7d565b604051610567919061487f565b60405180910390f35b34801561057c57600080fd5b5061059760048036038101906105929190614c3a565b611da8565b6040516105a4919061487f565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf9190614c3a565b611dfe565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190614dea565b611f09565b005b34801561060b57600080fd5b5061062660048036038101906106219190614569565b612000565b604051610637959493929190614e75565b60405180910390f35b34801561064c57600080fd5b5061066760048036038101906106629190614569565b612197565b604051610674919061487f565b60405180910390f35b34801561068957600080fd5b506106a4600480360381019061069f9190614569565b6121a9565b6040516106b19190614dcf565b60405180910390f35b3480156106c657600080fd5b506106cf612248565b6040516106dc9190614dcf565b60405180910390f35b3480156106f157600080fd5b5061070c60048036038101906107079190614569565b612272565b6040516107199190614dcf565b60405180910390f35b34801561072e57600080fd5b5061074960048036038101906107449190614c3a565b612311565b005b60006107556123be565b60008061076e6001600d5461244590919063ffffffff16565b9150915080600d81905550816107b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b090614f22565b60405180910390fd5b6107c8818c8c8c8c8c8c612474565b6107d281866125a6565b6107dc81856127e2565b807f892963d5e949a187a39c1e3de2e87d8755ee509d8f974472692abc14e7ee7fa4600e600084815260200190815260200160002060405161081e9190615266565b60405180910390a2809250505098975050505050505050565b61083f612af7565b8051825114610883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087a906152d4565b60405180910390fd5b60005b82518110156108e0576108cd8382815181106108a5576108a46152f4565b5b60200260200101518383815181106108c0576108bf6152f4565b5b6020026020010151612b91565b80806108d890615352565b915050610886565b505050565b6108ed6123be565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361095c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610953906153e6565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60608060608060608060606000600e60008a815260200190815260200160002060405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610aa357838290600052602060002090600302016040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505081526020019060010190610a07565b50505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610b8757838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190610ad0565b50505050815250509050600081600001515167ffffffffffffffff811115610bb257610bb1613e3b565b5b604051908082528060200260200182016040528015610be05781602001602082028036833780820191505090505b509050600082600001515167ffffffffffffffff811115610c0457610c03613e3b565b5b604051908082528060200260200182016040528015610c325781602001602082028036833780820191505090505b509050600083600001515167ffffffffffffffff811115610c5657610c55613e3b565b5b604051908082528060200260200182016040528015610c845781602001602082028036833780820191505090505b50905060005b8460000151518160ff161015610db35784600001518160ff1681518110610cb457610cb36152f4565b5b602002602001015160000151848260ff1681518110610cd657610cd56152f4565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084600001518160ff1681518110610d2a57610d296152f4565b5b602002602001015160200151838260ff1681518110610d4c57610d4b6152f4565b5b60200260200101818152505084600001518160ff1681518110610d7257610d716152f4565b5b602002602001015160400151828260ff1681518110610d9457610d936152f4565b5b6020026020010181815250508080610dab90615413565b915050610c8a565b50600084602001515167ffffffffffffffff811115610dd557610dd4613e3b565b5b604051908082528060200260200182016040528015610e035781602001602082028036833780820191505090505b509050600085602001515167ffffffffffffffff811115610e2757610e26613e3b565b5b604051908082528060200260200182016040528015610e555781602001602082028036833780820191505090505b509050600086602001515167ffffffffffffffff811115610e7957610e78613e3b565b5b604051908082528060200260200182016040528015610ea75781602001602082028036833780820191505090505b509050600087602001515167ffffffffffffffff811115610ecb57610eca613e3b565b5b604051908082528060200260200182016040528015610ef95781602001602082028036833780820191505090505b50905060005b8860200151518160ff1610156110765788602001518160ff1681518110610f2957610f286152f4565b5b602002602001015160000151858260ff1681518110610f4b57610f4a6152f4565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505088602001518160ff1681518110610f9f57610f9e6152f4565b5b602002602001015160200151848260ff1681518110610fc157610fc06152f4565b5b60200260200101818152505088602001518160ff1681518110610fe757610fe66152f4565b5b602002602001015160400151838260ff1681518110611009576110086152f4565b5b60200260200101818152505088602001518160ff168151811061102f5761102e6152f4565b5b602002602001015160600151828260ff1681518110611051576110506152f4565b5b602002602001019015159081151581525050808061106e90615413565b915050610eff565b50868686868686869e509e509e509e509e509e509e505050505050505050919395979092949650565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6110d1612af7565b8051825114611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110c906152d4565b60405180910390fd5b60005b82518110156111725761115f838281518110611137576111366152f4565b5b6020026020010151838381518110611152576111516152f4565b5b6020026020010151612bf5565b808061116a90615352565b915050611118565b505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6111aa8261109f565b6111e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e090615488565b60405180910390fd5b6111f282612d02565b6000600e600084815260200190815260200160002060405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156112d357838290600052602060002090600302016040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505081526020019060010190611237565b50505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156113b757838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190611300565b5050505081525050905060005b8160000151518160ff1610156115275760008061140f8585600001518560ff16815181106113f5576113f46152f4565b5b60200260200101516040015161307690919063ffffffff16565b9150915081611453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144a906154f4565b60405180910390fd5b600084600001518460ff168151811061146f5761146e6152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663cbc7067c3387600001518760ff16815181106114b4576114b36152f4565b5b602002602001015160200151856040518463ffffffff1660e01b81526004016114df93929190615514565b600060405180830381600087803b1580156114f957600080fd5b505af115801561150d573d6000803e3d6000fd5b50505050505050808061151f90615413565b9150506113c4565b5060005b8160200151518160ff161015611757576000806115768585602001518560ff168151811061155c5761155b6152f4565b5b60200260200101516040015161307690919063ffffffff16565b91509150816115ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b1906154f4565b60405180910390fd5b83602001518360ff16815181106115d4576115d36152f4565b5b602002602001015160600151156116a957600084602001518460ff1681518110611601576116006152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff166325f5e8ee3387602001518760ff1681518110611646576116456152f4565b5b602002602001015160200151856040518463ffffffff1660e01b815260040161167193929190615514565b600060405180830381600087803b15801561168b57600080fd5b505af115801561169f573d6000803e3d6000fd5b5050505050611742565b600084602001518460ff16815181106116c5576116c46152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663f0a8587b33846040518363ffffffff1660e01b815260040161170e92919061554b565b600060405180830381600087803b15801561172857600080fd5b505af115801561173c573d6000803e3d6000fd5b50505050505b5050808061174f90615413565b91505061152b565b5061176283836130c9565b505050565b61176f612af7565b60005b81518110156117b15761179e828281518110611791576117906152f4565b5b60200260200101516134cf565b80806117a990615352565b915050611772565b5050565b6060600280546117c4906155a3565b80601f01602080910402602001604051908101604052809291908181526020018280546117f0906155a3565b801561183d5780601f106118125761010080835404028352916020019161183d565b820191906000526020600020905b81548152906001019060200180831161182057829003601f168201915b5050505050905090565b61184f612af7565b8051825114611893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188a906152d4565b60405180910390fd5b60005b82518110156118f0576118dd8382815181106118b5576118b46152f4565b5b60200260200101518383815181106118d0576118cf6152f4565b5b6020026020010151613563565b80806118e890615352565b915050611896565b505050565b6000600d54905090565b611907612af7565b805182511461194b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611942906152d4565b60405180910390fd5b60005b82518110156119a85761199583828151811061196d5761196c6152f4565b5b6020026020010151838381518110611988576119876152f4565b5b60200260200101516135da565b80806119a090615352565b91505061194e565b505050565b6119b5612af7565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015611a405750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b611a7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7690615620565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611acb6123be565b611ad560006136e7565b565b611adf612af7565b8051825114611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a906152d4565b60405180910390fd5b60005b8251811015611b8057611b6d838281518110611b4557611b446152f4565b5b6020026020010151838381518110611b6057611b5f6152f4565b5b6020026020010151613718565b8080611b7890615352565b915050611b26565b505050565b6000611b8f6137e3565b90508073ffffffffffffffffffffffffffffffffffffffff16611bb0612248565b73ffffffffffffffffffffffffffffffffffffffff1614611c0857806040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611bff9190614dcf565b60405180910390fd5b611c11816136e7565b50565b606060038054611c23906155a3565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4f906155a3565b8015611c9c5780601f10611c7157610100808354040283529160200191611c9c565b820191906000526020600020905b815481529060010190602001808311611c7f57829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611cd7612af7565b8051825114611d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d12906152d4565b60405180910390fd5b60005b8251811015611d7857611d65838281518110611d3d57611d3c6152f4565b5b6020026020010151838381518110611d5857611d576152f4565b5b60200260200101516137eb565b8080611d7090615352565b915050611d1e565b505050565b600080600460008481526020019081526020016000208054611d9e906155a3565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611e06612af7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480611e865750611e857f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061568c565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611f116123be565b611f1a83611d7d565b611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f50906156f8565b60405180910390fd5b600e60008481526020019081526020016000206000016000611f7b9190613cb7565b600e60008481526020019081526020016000206001016000611f9d9190613cdb565b611fa783836125a6565b611fb183826127e2565b827fd614303950f3d5e896c3ae8921a4bbfa2a15d6bf330248faaae24dcd59071dff600e6000868152602001908152602001600020604051611ff39190615266565b60405180910390a2505050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff1661206c8a6121a9565b848054612078906155a3565b80601f01602080910402602001604051908101604052809291908181526020018280546120a4906155a3565b80156120f15780601f106120c6576101008083540402835291602001916120f1565b820191906000526020600020905b8154815290600101906020018083116120d457829003601f168201915b50505050509450838054612104906155a3565b80601f0160208091040260200160405190810160405280929190818152602001828054612130906155a3565b801561217d5780601f106121525761010080835404028352916020019161217d565b820191906000526020600020905b81548152906001019060200180831161216057829003601f168201915b505050505093509450945094509450945091939590929450565b60006121a282611d7d565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361223e57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612240565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361230757600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612309565b805b915050919050565b6123196123be565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16612379611ca6565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6123c66137e3565b73ffffffffffffffffffffffffffffffffffffffff166123e4611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614612443576124076137e3565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161243a9190614dcf565b60405180910390fd5b565b600080600083850190508481101561246457600080925092505061246d565b60018192509250505b9250929050565b8560046000898152602001908152602001600020908161249491906158c4565b50846005600089815260200190815260200160002090816124b591906158c4565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b60005b81518110156127dd576125d98282815181106125c8576125c76152f4565b5b60200260200101516000015161387d565b612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260f906159e2565b60405180910390fd5b600082828151811061262d5761262c6152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80784848151811061266a576126696152f4565b5b6020026020010151602001516040518263ffffffff1660e01b815260040161269291906143d3565b602060405180830381865afa1580156126af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d39190615a17565b612712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270990615a90565b60405180910390fd5b600e600085815260200190815260200160002060000183838151811061273b5761273a6152f4565b5b6020026020010151908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015550505080806127d590615352565b9150506125a9565b505050565b60005b8151811015612af2576000612817838381518110612806576128056152f4565b5b60200260200101516000015161387d565b90506000612842848481518110612831576128306152f4565b5b602002602001015160000151613907565b9050818061284d5750805b61288c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288390615afc565b60405180910390fd5b811561298e5760008484815181106128a7576128a66152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c8078686815181106128e4576128e36152f4565b5b6020026020010151602001516040518263ffffffff1660e01b815260040161290c91906143d3565b602060405180830381865afa158015612929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294d9190615a17565b61298c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298390615a90565b60405180910390fd5b505b600e600086815260200190815260200160002060010160405180608001604052808686815181106129c2576129c16152f4565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1681526020018686815181106129fc576129fb6152f4565b5b6020026020010151602001518152602001868681518110612a2057612a1f6152f4565b5b6020026020010151604001518152602001841515815250908060018154018082558091505060019003906000526020600020906004020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548160ff021916908315150217905550505050508080612aea90615352565b9150506127e5565b505050565b6000612b016137e3565b90508073ffffffffffffffffffffffffffffffffffffffff16612b22611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614158015612b4c5750612b4a81613991565b155b15612b8e57806040517f8a08cbf5000000000000000000000000000000000000000000000000000000008152600401612b859190614dcf565b60405180910390fd5b50565b612b9a82611d7d565b612bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bd090615b68565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b612bfe82611d7d565b612c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3490615b68565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca390615bd4565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600e600083815260200190815260200160002060000180549050905060005b81811015612e8f576000600e60008581526020019081526020016000206000018281548110612d5557612d546152f4565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008781526020019081526020016000206000018481548110612dcd57612dcc6152f4565b5b9060005260206000209060030201600101546040518263ffffffff1660e01b8152600401612dfb91906143d3565b602060405180830381865afa158015612e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e3c9190615a17565b612e7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7290615a90565b60405180910390fd5b508080612e8790615352565b915050612d23565b506000600e600084815260200190815260200160002060010180549050905060005b81811015613070576000600e60008681526020019081526020016000206001018281548110612ee357612ee26152f4565b5b906000526020600020906004020160030160009054906101000a900460ff169050801561305c576000600e60008781526020019081526020016000206001018381548110612f3457612f336152f4565b5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008981526020019081526020016000206001018581548110612fac57612fab6152f4565b5b9060005260206000209060040201600101546040518263ffffffff1660e01b8152600401612fda91906143d3565b602060405180830381865afa158015612ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301b9190615a17565b61305a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161305190615a90565b60405180910390fd5b505b50808061306890615352565b915050612eb1565b50505050565b6000806000840361308e5760016000915091506130c2565b60008385029050838582816130a6576130a5615bf4565b5b04146130b95760008092509250506130c2565b60018192509250505b9250929050565b6000811161310c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161310390615c6f565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361313257506134cb565b600061313d846121a9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036131ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a590615cdb565b60405180910390fd5b6000806131c4858561307690919063ffffffff16565b9150915081613208576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131ff90615d47565b60405180910390fd5b600061321387612272565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133e25760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016132849190614dcf565b602060405180830381865afa1580156132a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c59190615d7c565b90508281101561330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161330190615df5565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b815260040161334793929190615e15565b6020604051808303816000875af1158015613366573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338a9190615a17565b5060003411156133dc573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156133da573d6000803e3d6000fd5b505b506134c5565b81341015613425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161341c90615df5565b60405180910390fd5b600082346134339190615e4c565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561347b573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156134c2573d6000803e3d6000fd5b50505b50505050505b5050565b6134d881611d7d565b613517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161350e90615b68565b60405180910390fd5b613520816139e7565b61352981613ace565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b78160405161355891906143d3565b60405180910390a150565b61356c82611d7d565b6135ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135a290615b68565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6135e382611d7d565b613622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161361990615b68565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368890615bd4565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905561371581613b07565b50565b6000600460008481526020019081526020016000208054613738906155a3565b90501161377a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377190615b68565b60405180910390fd5b60008151116137be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137b590615ecc565b60405180910390fd5b806004600084815260200190815260200160002090816137de91906158c4565b505050565b600033905090565b6137f482611d7d565b613833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161382a90615b68565b60405180910390fd5b8060056000848152602001908152602001600020908161385391906158c4565b505050565b600061386383613bcb565b801561387557506138748383613c18565b5b905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561390057506138ff7ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561398a57506139897f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b9050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600460008281526020019081526020016000206000613a069190613cff565b600560008281526020019081526020016000206000613a259190613cff565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600e600082815260200190815260200160002060008082016000613af29190613cb7565b600182016000613b029190613cdb565b505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613bf7827f01ffc9a700000000000000000000000000000000000000000000000000000000613c18565b8015613c115750613c0f8263ffffffff60e01b613c18565b155b9050919050565b60008082604051602401613c2c9190615f27565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d91506000519050828015613c9f575060208210155b8015613cab5750600081115b94505050505092915050565b5080546000825560030290600052602060002090810190613cd89190613d3f565b50565b5080546000825560040290600052602060002090810190613cfc9190613d8d565b50565b508054613d0b906155a3565b6000825580601f10613d1d5750613d3c565b601f016020900490600052602060002090810190613d3b9190613def565b5b50565b5b80821115613d8957600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905550600301613d40565b5090565b5b80821115613deb57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201600090556003820160006101000a81549060ff021916905550600401613d8e565b5090565b5b80821115613e08576000816000905550600101613df0565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613e7382613e2a565b810181811067ffffffffffffffff82111715613e9257613e91613e3b565b5b80604052505050565b6000613ea5613e0c565b9050613eb18282613e6a565b919050565b600067ffffffffffffffff821115613ed157613ed0613e3b565b5b613eda82613e2a565b9050602081019050919050565b82818337600083830152505050565b6000613f09613f0484613eb6565b613e9b565b905082815260208101848484011115613f2557613f24613e25565b5b613f30848285613ee7565b509392505050565b600082601f830112613f4d57613f4c613e20565b5b8135613f5d848260208601613ef6565b91505092915050565b6000819050919050565b613f7981613f66565b8114613f8457600080fd5b50565b600081359050613f9681613f70565b92915050565b60008115159050919050565b613fb181613f9c565b8114613fbc57600080fd5b50565b600081359050613fce81613fa8565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613fff82613fd4565b9050919050565b61400f81613ff4565b811461401a57600080fd5b50565b60008135905061402c81614006565b92915050565b600067ffffffffffffffff82111561404d5761404c613e3b565b5b602082029050602081019050919050565b600080fd5b600080fd5b60006060828403121561407e5761407d614063565b5b6140886060613e9b565b905060006140988482850161401d565b60008301525060206140ac84828501613f87565b60208301525060406140c084828501613f87565b60408301525092915050565b60006140df6140da84614032565b613e9b565b905080838252602082019050606084028301858111156141025761410161405e565b5b835b8181101561412b57806141178882614068565b845260208401935050606081019050614104565b5050509392505050565b600082601f83011261414a57614149613e20565b5b813561415a8482602086016140cc565b91505092915050565b600067ffffffffffffffff82111561417e5761417d613e3b565b5b602082029050602081019050919050565b6000608082840312156141a5576141a4614063565b5b6141af6080613e9b565b905060006141bf8482850161401d565b60008301525060206141d384828501613f87565b60208301525060406141e784828501613f87565b60408301525060606141fb84828501613fbf565b60608301525092915050565b600061421a61421584614163565b613e9b565b9050808382526020820190506080840283018581111561423d5761423c61405e565b5b835b818110156142665780614252888261418f565b84526020840193505060808101905061423f565b5050509392505050565b600082601f83011261428557614284613e20565b5b8135614295848260208601614207565b91505092915050565b600080600080600080600080610100898b0312156142bf576142be613e16565b5b600089013567ffffffffffffffff8111156142dd576142dc613e1b565b5b6142e98b828c01613f38565b985050602089013567ffffffffffffffff81111561430a57614309613e1b565b5b6143168b828c01613f38565b97505060406143278b828c01613f87565b96505060606143388b828c01613fbf565b95505060806143498b828c0161401d565b94505060a061435a8b828c0161401d565b93505060c089013567ffffffffffffffff81111561437b5761437a613e1b565b5b6143878b828c01614135565b92505060e089013567ffffffffffffffff8111156143a8576143a7613e1b565b5b6143b48b828c01614270565b9150509295985092959890939650565b6143cd81613f66565b82525050565b60006020820190506143e860008301846143c4565b92915050565b600067ffffffffffffffff82111561440957614408613e3b565b5b602082029050602081019050919050565b600061442d614428846143ee565b613e9b565b905080838252602082019050602084028301858111156144505761444f61405e565b5b835b8181101561447957806144658882613f87565b845260208401935050602081019050614452565b5050509392505050565b600082601f83011261449857614497613e20565b5b81356144a884826020860161441a565b91505092915050565b600080604083850312156144c8576144c7613e16565b5b600083013567ffffffffffffffff8111156144e6576144e5613e1b565b5b6144f285828601614483565b925050602083013567ffffffffffffffff81111561451357614512613e1b565b5b61451f85828601614483565b9150509250929050565b600080604083850312156145405761453f613e16565b5b600061454e8582860161401d565b925050602061455f85828601613fbf565b9150509250929050565b60006020828403121561457f5761457e613e16565b5b600061458d84828501613f87565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6145cb81613ff4565b82525050565b60006145dd83836145c2565b60208301905092915050565b6000602082019050919050565b600061460182614596565b61460b81856145a1565b9350614616836145b2565b8060005b8381101561464757815161462e88826145d1565b9750614639836145e9565b92505060018101905061461a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61468981613f66565b82525050565b600061469b8383614680565b60208301905092915050565b6000602082019050919050565b60006146bf82614654565b6146c9818561465f565b93506146d483614670565b8060005b838110156147055781516146ec888261468f565b97506146f7836146a7565b9250506001810190506146d8565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61474781613f9c565b82525050565b6000614759838361473e565b60208301905092915050565b6000602082019050919050565b600061477d82614712565b614787818561471d565b93506147928361472e565b8060005b838110156147c35781516147aa888261474d565b97506147b583614765565b925050600181019050614796565b5085935050505092915050565b600060e08201905081810360008301526147ea818a6145f6565b905081810360208301526147fe81896146b4565b9050818103604083015261481281886146b4565b9050818103606083015261482681876145f6565b9050818103608083015261483a81866146b4565b905081810360a083015261484e81856146b4565b905081810360c08301526148628184614772565b905098975050505050505050565b61487981613f9c565b82525050565b60006020820190506148946000830184614870565b92915050565b600067ffffffffffffffff8211156148b5576148b4613e3b565b5b602082029050602081019050919050565b60006148d96148d48461489a565b613e9b565b905080838252602082019050602084028301858111156148fc576148fb61405e565b5b835b818110156149255780614911888261401d565b8452602084019350506020810190506148fe565b5050509392505050565b600082601f83011261494457614943613e20565b5b81356149548482602086016148c6565b91505092915050565b6000806040838503121561497457614973613e16565b5b600083013567ffffffffffffffff81111561499257614991613e1b565b5b61499e85828601614483565b925050602083013567ffffffffffffffff8111156149bf576149be613e1b565b5b6149cb8582860161492f565b9150509250929050565b600080604083850312156149ec576149eb613e16565b5b60006149fa85828601613f87565b9250506020614a0b85828601613f87565b9150509250929050565b600060208284031215614a2b57614a2a613e16565b5b600082013567ffffffffffffffff811115614a4957614a48613e1b565b5b614a5584828501614483565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614a98578082015181840152602081019050614a7d565b60008484015250505050565b6000614aaf82614a5e565b614ab98185614a69565b9350614ac9818560208601614a7a565b614ad281613e2a565b840191505092915050565b60006020820190508181036000830152614af78184614aa4565b905092915050565b600067ffffffffffffffff821115614b1a57614b19613e3b565b5b602082029050602081019050919050565b6000614b3e614b3984614aff565b613e9b565b90508083825260208201905060208402830185811115614b6157614b6061405e565b5b835b81811015614b8a5780614b768882613fbf565b845260208401935050602081019050614b63565b5050509392505050565b600082601f830112614ba957614ba8613e20565b5b8135614bb9848260208601614b2b565b91505092915050565b60008060408385031215614bd957614bd8613e16565b5b600083013567ffffffffffffffff811115614bf757614bf6613e1b565b5b614c0385828601614483565b925050602083013567ffffffffffffffff811115614c2457614c23613e1b565b5b614c3085828601614b94565b9150509250929050565b600060208284031215614c5057614c4f613e16565b5b6000614c5e8482850161401d565b91505092915050565b600067ffffffffffffffff821115614c8257614c81613e3b565b5b602082029050602081019050919050565b6000614ca6614ca184614c67565b613e9b565b90508083825260208201905060208402830185811115614cc957614cc861405e565b5b835b81811015614d1057803567ffffffffffffffff811115614cee57614ced613e20565b5b808601614cfb8982613f38565b85526020850194505050602081019050614ccb565b5050509392505050565b600082601f830112614d2f57614d2e613e20565b5b8135614d3f848260208601614c93565b91505092915050565b60008060408385031215614d5f57614d5e613e16565b5b600083013567ffffffffffffffff811115614d7d57614d7c613e1b565b5b614d8985828601614483565b925050602083013567ffffffffffffffff811115614daa57614da9613e1b565b5b614db685828601614d1a565b9150509250929050565b614dc981613ff4565b82525050565b6000602082019050614de46000830184614dc0565b92915050565b600080600060608486031215614e0357614e02613e16565b5b6000614e1186828701613f87565b935050602084013567ffffffffffffffff811115614e3257614e31613e1b565b5b614e3e86828701614135565b925050604084013567ffffffffffffffff811115614e5f57614e5e613e1b565b5b614e6b86828701614270565b9150509250925092565b600060a0820190508181036000830152614e8f8188614aa4565b90508181036020830152614ea38187614aa4565b9050614eb260408301866143c4565b614ebf6060830185614870565b614ecc6080830184614dc0565b9695505050505050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614f0c600f83614a69565b9150614f1782614ed6565b602082019050919050565b60006020820190508181036000830152614f3b81614eff565b9050919050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614fb3614fae83614f73565b614f80565b9050919050565b6000819050919050565b6000614fd7614fd283614f73565b614fba565b9050919050565b606082016000808301549050614ff381614fa0565b61500060008601826145c2565b506001830154905061501181614fc4565b61501e6020860182614680565b506002830154905061502f81614fc4565b61503c6040860182614680565b5050505050565b600061504f8383614fde565b60608301905092915050565b6000600382019050919050565b600061507382614f42565b61507d8185614f4d565b935061508883614f5e565b8060005b838110156150b8578161509f8882615043565b97506150aa8361505b565b92505060018101905061508c565b5085935050505092915050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b600060ff82169050919050565b600061511661511183614f73565b6150f6565b9050919050565b60808201600080830154905061513281614fa0565b61513f60008601826145c2565b506001830154905061515081614fc4565b61515d6020860182614680565b506002830154905061516e81614fc4565b61517b6040860182614680565b506003830154905061518c81615103565b615199606086018261473e565b5050505050565b60006151ac838361511d565b60808301905092915050565b6000600482019050919050565b60006151d0826150c5565b6151da81856150d0565b93506151e5836150e1565b8060005b8381101561521557816151fc88826151a0565b9750615207836151b8565b9250506001810190506151e9565b5085935050505092915050565b6000604083016000808401858303600087015261523f8382615068565b92505060018401858303602087015261525883826151c5565b925050819250505092915050565b600060208201905081810360008301526152808184615222565b905092915050565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b60006152be601283614a69565b91506152c982615288565b602082019050919050565b600060208201905081810360008301526152ed816152b1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061535d82613f66565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361538f5761538e615323565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b60006153d0601483614a69565b91506153db8261539a565b602082019050919050565b600060208201905081810360008301526153ff816153c3565b9050919050565b600060ff82169050919050565b600061541e82615406565b915060ff820361543157615430615323565b5b600182019050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b6000615472601183614a69565b915061547d8261543c565b602082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b7f544f54414c5f4f564552464c4f57000000000000000000000000000000000000600082015250565b60006154de600e83614a69565b91506154e9826154a8565b602082019050919050565b6000602082019050818103600083015261550d816154d1565b9050919050565b60006060820190506155296000830186614dc0565b61553660208301856143c4565b61554360408301846143c4565b949350505050565b60006040820190506155606000830185614dc0565b61556d60208301846143c4565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806155bb57607f821691505b6020821081036155ce576155cd615574565b5b50919050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b600061560a601083614a69565b9150615615826155d4565b602082019050919050565b60006020820190508181036000830152615639816155fd565b9050919050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b6000615676601283614a69565b915061568182615640565b602082019050919050565b600060208201905081810360008301526156a581615669565b9050919050565b7f4e4f545f444546494e4544000000000000000000000000000000000000000000600082015250565b60006156e2600b83614a69565b91506156ed826156ac565b602082019050919050565b60006020820190508181036000830152615711816156d5565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261577a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261573d565b615784868361573d565b95508019841693508086168417925050509392505050565b6000819050919050565b60006157c16157bc6157b784613f66565b61579c565b613f66565b9050919050565b6000819050919050565b6157db836157a6565b6157ef6157e7826157c8565b84845461574a565b825550505050565b600090565b6158046157f7565b61580f8184846157d2565b505050565b5b81811015615833576158286000826157fc565b600181019050615815565b5050565b601f8211156158785761584981615718565b6158528461572d565b81016020851015615861578190505b61587561586d8561572d565b830182615814565b50505b505050565b600082821c905092915050565b600061589b6000198460080261587d565b1980831691505092915050565b60006158b4838361588a565b9150826002028217905092915050565b6158cd82614a5e565b67ffffffffffffffff8111156158e6576158e5613e3b565b5b6158f082546155a3565b6158fb828285615837565b600060209050601f83116001811461592e576000841561591c578287015190505b61592685826158a8565b86555061598e565b601f19841661593c86615718565b60005b828110156159645784890151825560018201915060208501945060208101905061593f565b86831015615981578489015161597d601f89168261588a565b8355505b6001600288020188555050505b505050505050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b60006159cc600b83614a69565b91506159d782615996565b602082019050919050565b600060208201905081810360008301526159fb816159bf565b9050919050565b600081519050615a1181613fa8565b92915050565b600060208284031215615a2d57615a2c613e16565b5b6000615a3b84828501615a02565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615a7a600b83614a69565b9150615a8582615a44565b602082019050919050565b60006020820190508181036000830152615aa981615a6d565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615ae6600b83614a69565b9150615af182615ab0565b602082019050919050565b60006020820190508181036000830152615b1581615ad9565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b6000615b52600e83614a69565b9150615b5d82615b1c565b602082019050919050565b60006020820190508181036000830152615b8181615b45565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b6000615bbe600c83614a69565b9150615bc982615b88565b602082019050919050565b60006020820190508181036000830152615bed81615bb1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615c59600f83614a69565b9150615c6482615c23565b602082019050919050565b60006020820190508181036000830152615c8881615c4c565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b6000615cc5601083614a69565b9150615cd082615c8f565b602082019050919050565b60006020820190508181036000830152615cf481615cb8565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b6000615d31601083614a69565b9150615d3c82615cfb565b602082019050919050565b60006020820190508181036000830152615d6081615d24565b9050919050565b600081519050615d7681613f70565b92915050565b600060208284031215615d9257615d91613e16565b5b6000615da084828501615d67565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b6000615ddf601483614a69565b9150615dea82615da9565b602082019050919050565b60006020820190508181036000830152615e0e81615dd2565b9050919050565b6000606082019050615e2a6000830186614dc0565b615e376020830185614dc0565b615e4460408301846143c4565b949350505050565b6000615e5782613f66565b9150615e6283613f66565b9250828203905081811115615e7a57615e79615323565b5b92915050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b6000615eb6600b83614a69565b9150615ec182615e80565b602082019050919050565b60006020820190508181036000830152615ee581615ea9565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615f2181615eec565b82525050565b6000602082019050615f3c6000830184615f18565b9291505056fea2646970667358221220cb08554b1f337e1e4deee5d7146364d81d8ec0f459305b9284e05b1713f861de64736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f486f706576657273652043726166740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a437261667420466f6d756c6120666f7220486f70657665727365000000000000
Deployed ByteCode
0x6080604052600436106101cd5760003560e01c806376967cbf116100f7578063bb21ac5411610095578063df8e759a11610064578063df8e759a1461067d578063e30c3978146106ba578063e55661bd146106e5578063f2fde38b14610722576101cd565b8063bb21ac54146105ad578063c9e0ac16146105d6578063dd99b73d146105ff578063dda0da0014610640576101cd565b80638da5cb5b116100d15780638da5cb5b146104df578063a3066e431461050a578063b8c7871a14610533578063ba84860814610570576101cd565b806376967cbf1461047457806379ba50971461049d578063839d7f11146104b4576101cd565b8063289137a11161016f5780633f84dc1b1161013e5780633f84dc1b146103e05780635458c28e1461040b5780636586bb7014610434578063715018a61461045d576101cd565b8063289137a11461034757806330546c9b146103635780633a525c291461038c5780633b9ebeec146103b7576101cd565b8063189357ff116101ab578063189357ff1461026157806319df1182146102a45780631a7db56e146102e1578063284293cf1461030a576101cd565b806308319627146101d25780630f6bec9a1461020f5780630fe4215914610238575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f4919061429e565b61074b565b60405161020691906143d3565b60405180910390f35b34801561021b57600080fd5b50610236600480360381019061023191906144b1565b610837565b005b34801561024457600080fd5b5061025f600480360381019061025a9190614529565b6108e5565b005b34801561026d57600080fd5b5061028860048036038101906102839190614569565b6109b7565b60405161029b97969594939291906147d0565b60405180910390f35b3480156102b057600080fd5b506102cb60048036038101906102c69190614569565b61109f565b6040516102d8919061487f565b60405180910390f35b3480156102ed57600080fd5b506103086004803603810190610303919061495d565b6110c9565b005b34801561031657600080fd5b50610331600480360381019061032c9190614569565b611177565b60405161033e919061487f565b60405180910390f35b610361600480360381019061035c91906149d5565b6111a1565b005b34801561036f57600080fd5b5061038a60048036038101906103859190614a15565b611767565b005b34801561039857600080fd5b506103a16117b5565b6040516103ae9190614add565b60405180910390f35b3480156103c357600080fd5b506103de60048036038101906103d99190614bc2565b611847565b005b3480156103ec57600080fd5b506103f56118f5565b60405161040291906143d3565b60405180910390f35b34801561041757600080fd5b50610432600480360381019061042d919061495d565b6118ff565b005b34801561044057600080fd5b5061045b60048036038101906104569190614c3a565b6119ad565b005b34801561046957600080fd5b50610472611ac3565b005b34801561048057600080fd5b5061049b60048036038101906104969190614d48565b611ad7565b005b3480156104a957600080fd5b506104b2611b85565b005b3480156104c057600080fd5b506104c9611c14565b6040516104d69190614add565b60405180910390f35b3480156104eb57600080fd5b506104f4611ca6565b6040516105019190614dcf565b60405180910390f35b34801561051657600080fd5b50610531600480360381019061052c9190614d48565b611ccf565b005b34801561053f57600080fd5b5061055a60048036038101906105559190614569565b611d7d565b604051610567919061487f565b60405180910390f35b34801561057c57600080fd5b5061059760048036038101906105929190614c3a565b611da8565b6040516105a4919061487f565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf9190614c3a565b611dfe565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190614dea565b611f09565b005b34801561060b57600080fd5b5061062660048036038101906106219190614569565b612000565b604051610637959493929190614e75565b60405180910390f35b34801561064c57600080fd5b5061066760048036038101906106629190614569565b612197565b604051610674919061487f565b60405180910390f35b34801561068957600080fd5b506106a4600480360381019061069f9190614569565b6121a9565b6040516106b19190614dcf565b60405180910390f35b3480156106c657600080fd5b506106cf612248565b6040516106dc9190614dcf565b60405180910390f35b3480156106f157600080fd5b5061070c60048036038101906107079190614569565b612272565b6040516107199190614dcf565b60405180910390f35b34801561072e57600080fd5b5061074960048036038101906107449190614c3a565b612311565b005b60006107556123be565b60008061076e6001600d5461244590919063ffffffff16565b9150915080600d81905550816107b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b090614f22565b60405180910390fd5b6107c8818c8c8c8c8c8c612474565b6107d281866125a6565b6107dc81856127e2565b807f892963d5e949a187a39c1e3de2e87d8755ee509d8f974472692abc14e7ee7fa4600e600084815260200190815260200160002060405161081e9190615266565b60405180910390a2809250505098975050505050505050565b61083f612af7565b8051825114610883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087a906152d4565b60405180910390fd5b60005b82518110156108e0576108cd8382815181106108a5576108a46152f4565b5b60200260200101518383815181106108c0576108bf6152f4565b5b6020026020010151612b91565b80806108d890615352565b915050610886565b505050565b6108ed6123be565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361095c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610953906153e6565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60608060608060608060606000600e60008a815260200190815260200160002060405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610aa357838290600052602060002090600302016040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505081526020019060010190610a07565b50505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610b8757838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190610ad0565b50505050815250509050600081600001515167ffffffffffffffff811115610bb257610bb1613e3b565b5b604051908082528060200260200182016040528015610be05781602001602082028036833780820191505090505b509050600082600001515167ffffffffffffffff811115610c0457610c03613e3b565b5b604051908082528060200260200182016040528015610c325781602001602082028036833780820191505090505b509050600083600001515167ffffffffffffffff811115610c5657610c55613e3b565b5b604051908082528060200260200182016040528015610c845781602001602082028036833780820191505090505b50905060005b8460000151518160ff161015610db35784600001518160ff1681518110610cb457610cb36152f4565b5b602002602001015160000151848260ff1681518110610cd657610cd56152f4565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084600001518160ff1681518110610d2a57610d296152f4565b5b602002602001015160200151838260ff1681518110610d4c57610d4b6152f4565b5b60200260200101818152505084600001518160ff1681518110610d7257610d716152f4565b5b602002602001015160400151828260ff1681518110610d9457610d936152f4565b5b6020026020010181815250508080610dab90615413565b915050610c8a565b50600084602001515167ffffffffffffffff811115610dd557610dd4613e3b565b5b604051908082528060200260200182016040528015610e035781602001602082028036833780820191505090505b509050600085602001515167ffffffffffffffff811115610e2757610e26613e3b565b5b604051908082528060200260200182016040528015610e555781602001602082028036833780820191505090505b509050600086602001515167ffffffffffffffff811115610e7957610e78613e3b565b5b604051908082528060200260200182016040528015610ea75781602001602082028036833780820191505090505b509050600087602001515167ffffffffffffffff811115610ecb57610eca613e3b565b5b604051908082528060200260200182016040528015610ef95781602001602082028036833780820191505090505b50905060005b8860200151518160ff1610156110765788602001518160ff1681518110610f2957610f286152f4565b5b602002602001015160000151858260ff1681518110610f4b57610f4a6152f4565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505088602001518160ff1681518110610f9f57610f9e6152f4565b5b602002602001015160200151848260ff1681518110610fc157610fc06152f4565b5b60200260200101818152505088602001518160ff1681518110610fe757610fe66152f4565b5b602002602001015160400151838260ff1681518110611009576110086152f4565b5b60200260200101818152505088602001518160ff168151811061102f5761102e6152f4565b5b602002602001015160600151828260ff1681518110611051576110506152f4565b5b602002602001019015159081151581525050808061106e90615413565b915050610eff565b50868686868686869e509e509e509e509e509e509e505050505050505050919395979092949650565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6110d1612af7565b8051825114611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110c906152d4565b60405180910390fd5b60005b82518110156111725761115f838281518110611137576111366152f4565b5b6020026020010151838381518110611152576111516152f4565b5b6020026020010151612bf5565b808061116a90615352565b915050611118565b505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6111aa8261109f565b6111e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e090615488565b60405180910390fd5b6111f282612d02565b6000600e600084815260200190815260200160002060405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156112d357838290600052602060002090600302016040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505081526020019060010190611237565b50505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156113b757838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190611300565b5050505081525050905060005b8160000151518160ff1610156115275760008061140f8585600001518560ff16815181106113f5576113f46152f4565b5b60200260200101516040015161307690919063ffffffff16565b9150915081611453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144a906154f4565b60405180910390fd5b600084600001518460ff168151811061146f5761146e6152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663cbc7067c3387600001518760ff16815181106114b4576114b36152f4565b5b602002602001015160200151856040518463ffffffff1660e01b81526004016114df93929190615514565b600060405180830381600087803b1580156114f957600080fd5b505af115801561150d573d6000803e3d6000fd5b50505050505050808061151f90615413565b9150506113c4565b5060005b8160200151518160ff161015611757576000806115768585602001518560ff168151811061155c5761155b6152f4565b5b60200260200101516040015161307690919063ffffffff16565b91509150816115ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b1906154f4565b60405180910390fd5b83602001518360ff16815181106115d4576115d36152f4565b5b602002602001015160600151156116a957600084602001518460ff1681518110611601576116006152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff166325f5e8ee3387602001518760ff1681518110611646576116456152f4565b5b602002602001015160200151856040518463ffffffff1660e01b815260040161167193929190615514565b600060405180830381600087803b15801561168b57600080fd5b505af115801561169f573d6000803e3d6000fd5b5050505050611742565b600084602001518460ff16815181106116c5576116c46152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663f0a8587b33846040518363ffffffff1660e01b815260040161170e92919061554b565b600060405180830381600087803b15801561172857600080fd5b505af115801561173c573d6000803e3d6000fd5b50505050505b5050808061174f90615413565b91505061152b565b5061176283836130c9565b505050565b61176f612af7565b60005b81518110156117b15761179e828281518110611791576117906152f4565b5b60200260200101516134cf565b80806117a990615352565b915050611772565b5050565b6060600280546117c4906155a3565b80601f01602080910402602001604051908101604052809291908181526020018280546117f0906155a3565b801561183d5780601f106118125761010080835404028352916020019161183d565b820191906000526020600020905b81548152906001019060200180831161182057829003601f168201915b5050505050905090565b61184f612af7565b8051825114611893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188a906152d4565b60405180910390fd5b60005b82518110156118f0576118dd8382815181106118b5576118b46152f4565b5b60200260200101518383815181106118d0576118cf6152f4565b5b6020026020010151613563565b80806118e890615352565b915050611896565b505050565b6000600d54905090565b611907612af7565b805182511461194b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611942906152d4565b60405180910390fd5b60005b82518110156119a85761199583828151811061196d5761196c6152f4565b5b6020026020010151838381518110611988576119876152f4565b5b60200260200101516135da565b80806119a090615352565b91505061194e565b505050565b6119b5612af7565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015611a405750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b611a7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7690615620565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611acb6123be565b611ad560006136e7565b565b611adf612af7565b8051825114611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a906152d4565b60405180910390fd5b60005b8251811015611b8057611b6d838281518110611b4557611b446152f4565b5b6020026020010151838381518110611b6057611b5f6152f4565b5b6020026020010151613718565b8080611b7890615352565b915050611b26565b505050565b6000611b8f6137e3565b90508073ffffffffffffffffffffffffffffffffffffffff16611bb0612248565b73ffffffffffffffffffffffffffffffffffffffff1614611c0857806040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611bff9190614dcf565b60405180910390fd5b611c11816136e7565b50565b606060038054611c23906155a3565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4f906155a3565b8015611c9c5780601f10611c7157610100808354040283529160200191611c9c565b820191906000526020600020905b815481529060010190602001808311611c7f57829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611cd7612af7565b8051825114611d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d12906152d4565b60405180910390fd5b60005b8251811015611d7857611d65838281518110611d3d57611d3c6152f4565b5b6020026020010151838381518110611d5857611d576152f4565b5b60200260200101516137eb565b8080611d7090615352565b915050611d1e565b505050565b600080600460008481526020019081526020016000208054611d9e906155a3565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611e06612af7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480611e865750611e857f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061568c565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611f116123be565b611f1a83611d7d565b611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f50906156f8565b60405180910390fd5b600e60008481526020019081526020016000206000016000611f7b9190613cb7565b600e60008481526020019081526020016000206001016000611f9d9190613cdb565b611fa783836125a6565b611fb183826127e2565b827fd614303950f3d5e896c3ae8921a4bbfa2a15d6bf330248faaae24dcd59071dff600e6000868152602001908152602001600020604051611ff39190615266565b60405180910390a2505050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff1661206c8a6121a9565b848054612078906155a3565b80601f01602080910402602001604051908101604052809291908181526020018280546120a4906155a3565b80156120f15780601f106120c6576101008083540402835291602001916120f1565b820191906000526020600020905b8154815290600101906020018083116120d457829003601f168201915b50505050509450838054612104906155a3565b80601f0160208091040260200160405190810160405280929190818152602001828054612130906155a3565b801561217d5780601f106121525761010080835404028352916020019161217d565b820191906000526020600020905b81548152906001019060200180831161216057829003601f168201915b505050505093509450945094509450945091939590929450565b60006121a282611d7d565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361223e57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612240565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361230757600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612309565b805b915050919050565b6123196123be565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16612379611ca6565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6123c66137e3565b73ffffffffffffffffffffffffffffffffffffffff166123e4611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614612443576124076137e3565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161243a9190614dcf565b60405180910390fd5b565b600080600083850190508481101561246457600080925092505061246d565b60018192509250505b9250929050565b8560046000898152602001908152602001600020908161249491906158c4565b50846005600089815260200190815260200160002090816124b591906158c4565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b60005b81518110156127dd576125d98282815181106125c8576125c76152f4565b5b60200260200101516000015161387d565b612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260f906159e2565b60405180910390fd5b600082828151811061262d5761262c6152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80784848151811061266a576126696152f4565b5b6020026020010151602001516040518263ffffffff1660e01b815260040161269291906143d3565b602060405180830381865afa1580156126af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d39190615a17565b612712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270990615a90565b60405180910390fd5b600e600085815260200190815260200160002060000183838151811061273b5761273a6152f4565b5b6020026020010151908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015550505080806127d590615352565b9150506125a9565b505050565b60005b8151811015612af2576000612817838381518110612806576128056152f4565b5b60200260200101516000015161387d565b90506000612842848481518110612831576128306152f4565b5b602002602001015160000151613907565b9050818061284d5750805b61288c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288390615afc565b60405180910390fd5b811561298e5760008484815181106128a7576128a66152f4565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c8078686815181106128e4576128e36152f4565b5b6020026020010151602001516040518263ffffffff1660e01b815260040161290c91906143d3565b602060405180830381865afa158015612929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294d9190615a17565b61298c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298390615a90565b60405180910390fd5b505b600e600086815260200190815260200160002060010160405180608001604052808686815181106129c2576129c16152f4565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1681526020018686815181106129fc576129fb6152f4565b5b6020026020010151602001518152602001868681518110612a2057612a1f6152f4565b5b6020026020010151604001518152602001841515815250908060018154018082558091505060019003906000526020600020906004020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548160ff021916908315150217905550505050508080612aea90615352565b9150506127e5565b505050565b6000612b016137e3565b90508073ffffffffffffffffffffffffffffffffffffffff16612b22611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614158015612b4c5750612b4a81613991565b155b15612b8e57806040517f8a08cbf5000000000000000000000000000000000000000000000000000000008152600401612b859190614dcf565b60405180910390fd5b50565b612b9a82611d7d565b612bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bd090615b68565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b612bfe82611d7d565b612c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3490615b68565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca390615bd4565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600e600083815260200190815260200160002060000180549050905060005b81811015612e8f576000600e60008581526020019081526020016000206000018281548110612d5557612d546152f4565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008781526020019081526020016000206000018481548110612dcd57612dcc6152f4565b5b9060005260206000209060030201600101546040518263ffffffff1660e01b8152600401612dfb91906143d3565b602060405180830381865afa158015612e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e3c9190615a17565b612e7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7290615a90565b60405180910390fd5b508080612e8790615352565b915050612d23565b506000600e600084815260200190815260200160002060010180549050905060005b81811015613070576000600e60008681526020019081526020016000206001018281548110612ee357612ee26152f4565b5b906000526020600020906004020160030160009054906101000a900460ff169050801561305c576000600e60008781526020019081526020016000206001018381548110612f3457612f336152f4565b5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008981526020019081526020016000206001018581548110612fac57612fab6152f4565b5b9060005260206000209060040201600101546040518263ffffffff1660e01b8152600401612fda91906143d3565b602060405180830381865afa158015612ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301b9190615a17565b61305a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161305190615a90565b60405180910390fd5b505b50808061306890615352565b915050612eb1565b50505050565b6000806000840361308e5760016000915091506130c2565b60008385029050838582816130a6576130a5615bf4565b5b04146130b95760008092509250506130c2565b60018192509250505b9250929050565b6000811161310c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161310390615c6f565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361313257506134cb565b600061313d846121a9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036131ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a590615cdb565b60405180910390fd5b6000806131c4858561307690919063ffffffff16565b9150915081613208576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131ff90615d47565b60405180910390fd5b600061321387612272565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133e25760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016132849190614dcf565b602060405180830381865afa1580156132a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c59190615d7c565b90508281101561330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161330190615df5565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b815260040161334793929190615e15565b6020604051808303816000875af1158015613366573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338a9190615a17565b5060003411156133dc573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156133da573d6000803e3d6000fd5b505b506134c5565b81341015613425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161341c90615df5565b60405180910390fd5b600082346134339190615e4c565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561347b573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156134c2573d6000803e3d6000fd5b50505b50505050505b5050565b6134d881611d7d565b613517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161350e90615b68565b60405180910390fd5b613520816139e7565b61352981613ace565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b78160405161355891906143d3565b60405180910390a150565b61356c82611d7d565b6135ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135a290615b68565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6135e382611d7d565b613622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161361990615b68565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368890615bd4565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905561371581613b07565b50565b6000600460008481526020019081526020016000208054613738906155a3565b90501161377a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377190615b68565b60405180910390fd5b60008151116137be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137b590615ecc565b60405180910390fd5b806004600084815260200190815260200160002090816137de91906158c4565b505050565b600033905090565b6137f482611d7d565b613833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161382a90615b68565b60405180910390fd5b8060056000848152602001908152602001600020908161385391906158c4565b505050565b600061386383613bcb565b801561387557506138748383613c18565b5b905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561390057506138ff7ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561398a57506139897f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661385890919063ffffffff16565b5b9050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600460008281526020019081526020016000206000613a069190613cff565b600560008281526020019081526020016000206000613a259190613cff565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600e600082815260200190815260200160002060008082016000613af29190613cb7565b600182016000613b029190613cdb565b505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613bf7827f01ffc9a700000000000000000000000000000000000000000000000000000000613c18565b8015613c115750613c0f8263ffffffff60e01b613c18565b155b9050919050565b60008082604051602401613c2c9190615f27565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d91506000519050828015613c9f575060208210155b8015613cab5750600081115b94505050505092915050565b5080546000825560030290600052602060002090810190613cd89190613d3f565b50565b5080546000825560040290600052602060002090810190613cfc9190613d8d565b50565b508054613d0b906155a3565b6000825580601f10613d1d5750613d3c565b601f016020900490600052602060002090810190613d3b9190613def565b5b50565b5b80821115613d8957600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905550600301613d40565b5090565b5b80821115613deb57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201600090556003820160006101000a81549060ff021916905550600401613d8e565b5090565b5b80821115613e08576000816000905550600101613df0565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613e7382613e2a565b810181811067ffffffffffffffff82111715613e9257613e91613e3b565b5b80604052505050565b6000613ea5613e0c565b9050613eb18282613e6a565b919050565b600067ffffffffffffffff821115613ed157613ed0613e3b565b5b613eda82613e2a565b9050602081019050919050565b82818337600083830152505050565b6000613f09613f0484613eb6565b613e9b565b905082815260208101848484011115613f2557613f24613e25565b5b613f30848285613ee7565b509392505050565b600082601f830112613f4d57613f4c613e20565b5b8135613f5d848260208601613ef6565b91505092915050565b6000819050919050565b613f7981613f66565b8114613f8457600080fd5b50565b600081359050613f9681613f70565b92915050565b60008115159050919050565b613fb181613f9c565b8114613fbc57600080fd5b50565b600081359050613fce81613fa8565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613fff82613fd4565b9050919050565b61400f81613ff4565b811461401a57600080fd5b50565b60008135905061402c81614006565b92915050565b600067ffffffffffffffff82111561404d5761404c613e3b565b5b602082029050602081019050919050565b600080fd5b600080fd5b60006060828403121561407e5761407d614063565b5b6140886060613e9b565b905060006140988482850161401d565b60008301525060206140ac84828501613f87565b60208301525060406140c084828501613f87565b60408301525092915050565b60006140df6140da84614032565b613e9b565b905080838252602082019050606084028301858111156141025761410161405e565b5b835b8181101561412b57806141178882614068565b845260208401935050606081019050614104565b5050509392505050565b600082601f83011261414a57614149613e20565b5b813561415a8482602086016140cc565b91505092915050565b600067ffffffffffffffff82111561417e5761417d613e3b565b5b602082029050602081019050919050565b6000608082840312156141a5576141a4614063565b5b6141af6080613e9b565b905060006141bf8482850161401d565b60008301525060206141d384828501613f87565b60208301525060406141e784828501613f87565b60408301525060606141fb84828501613fbf565b60608301525092915050565b600061421a61421584614163565b613e9b565b9050808382526020820190506080840283018581111561423d5761423c61405e565b5b835b818110156142665780614252888261418f565b84526020840193505060808101905061423f565b5050509392505050565b600082601f83011261428557614284613e20565b5b8135614295848260208601614207565b91505092915050565b600080600080600080600080610100898b0312156142bf576142be613e16565b5b600089013567ffffffffffffffff8111156142dd576142dc613e1b565b5b6142e98b828c01613f38565b985050602089013567ffffffffffffffff81111561430a57614309613e1b565b5b6143168b828c01613f38565b97505060406143278b828c01613f87565b96505060606143388b828c01613fbf565b95505060806143498b828c0161401d565b94505060a061435a8b828c0161401d565b93505060c089013567ffffffffffffffff81111561437b5761437a613e1b565b5b6143878b828c01614135565b92505060e089013567ffffffffffffffff8111156143a8576143a7613e1b565b5b6143b48b828c01614270565b9150509295985092959890939650565b6143cd81613f66565b82525050565b60006020820190506143e860008301846143c4565b92915050565b600067ffffffffffffffff82111561440957614408613e3b565b5b602082029050602081019050919050565b600061442d614428846143ee565b613e9b565b905080838252602082019050602084028301858111156144505761444f61405e565b5b835b8181101561447957806144658882613f87565b845260208401935050602081019050614452565b5050509392505050565b600082601f83011261449857614497613e20565b5b81356144a884826020860161441a565b91505092915050565b600080604083850312156144c8576144c7613e16565b5b600083013567ffffffffffffffff8111156144e6576144e5613e1b565b5b6144f285828601614483565b925050602083013567ffffffffffffffff81111561451357614512613e1b565b5b61451f85828601614483565b9150509250929050565b600080604083850312156145405761453f613e16565b5b600061454e8582860161401d565b925050602061455f85828601613fbf565b9150509250929050565b60006020828403121561457f5761457e613e16565b5b600061458d84828501613f87565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6145cb81613ff4565b82525050565b60006145dd83836145c2565b60208301905092915050565b6000602082019050919050565b600061460182614596565b61460b81856145a1565b9350614616836145b2565b8060005b8381101561464757815161462e88826145d1565b9750614639836145e9565b92505060018101905061461a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61468981613f66565b82525050565b600061469b8383614680565b60208301905092915050565b6000602082019050919050565b60006146bf82614654565b6146c9818561465f565b93506146d483614670565b8060005b838110156147055781516146ec888261468f565b97506146f7836146a7565b9250506001810190506146d8565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61474781613f9c565b82525050565b6000614759838361473e565b60208301905092915050565b6000602082019050919050565b600061477d82614712565b614787818561471d565b93506147928361472e565b8060005b838110156147c35781516147aa888261474d565b97506147b583614765565b925050600181019050614796565b5085935050505092915050565b600060e08201905081810360008301526147ea818a6145f6565b905081810360208301526147fe81896146b4565b9050818103604083015261481281886146b4565b9050818103606083015261482681876145f6565b9050818103608083015261483a81866146b4565b905081810360a083015261484e81856146b4565b905081810360c08301526148628184614772565b905098975050505050505050565b61487981613f9c565b82525050565b60006020820190506148946000830184614870565b92915050565b600067ffffffffffffffff8211156148b5576148b4613e3b565b5b602082029050602081019050919050565b60006148d96148d48461489a565b613e9b565b905080838252602082019050602084028301858111156148fc576148fb61405e565b5b835b818110156149255780614911888261401d565b8452602084019350506020810190506148fe565b5050509392505050565b600082601f83011261494457614943613e20565b5b81356149548482602086016148c6565b91505092915050565b6000806040838503121561497457614973613e16565b5b600083013567ffffffffffffffff81111561499257614991613e1b565b5b61499e85828601614483565b925050602083013567ffffffffffffffff8111156149bf576149be613e1b565b5b6149cb8582860161492f565b9150509250929050565b600080604083850312156149ec576149eb613e16565b5b60006149fa85828601613f87565b9250506020614a0b85828601613f87565b9150509250929050565b600060208284031215614a2b57614a2a613e16565b5b600082013567ffffffffffffffff811115614a4957614a48613e1b565b5b614a5584828501614483565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614a98578082015181840152602081019050614a7d565b60008484015250505050565b6000614aaf82614a5e565b614ab98185614a69565b9350614ac9818560208601614a7a565b614ad281613e2a565b840191505092915050565b60006020820190508181036000830152614af78184614aa4565b905092915050565b600067ffffffffffffffff821115614b1a57614b19613e3b565b5b602082029050602081019050919050565b6000614b3e614b3984614aff565b613e9b565b90508083825260208201905060208402830185811115614b6157614b6061405e565b5b835b81811015614b8a5780614b768882613fbf565b845260208401935050602081019050614b63565b5050509392505050565b600082601f830112614ba957614ba8613e20565b5b8135614bb9848260208601614b2b565b91505092915050565b60008060408385031215614bd957614bd8613e16565b5b600083013567ffffffffffffffff811115614bf757614bf6613e1b565b5b614c0385828601614483565b925050602083013567ffffffffffffffff811115614c2457614c23613e1b565b5b614c3085828601614b94565b9150509250929050565b600060208284031215614c5057614c4f613e16565b5b6000614c5e8482850161401d565b91505092915050565b600067ffffffffffffffff821115614c8257614c81613e3b565b5b602082029050602081019050919050565b6000614ca6614ca184614c67565b613e9b565b90508083825260208201905060208402830185811115614cc957614cc861405e565b5b835b81811015614d1057803567ffffffffffffffff811115614cee57614ced613e20565b5b808601614cfb8982613f38565b85526020850194505050602081019050614ccb565b5050509392505050565b600082601f830112614d2f57614d2e613e20565b5b8135614d3f848260208601614c93565b91505092915050565b60008060408385031215614d5f57614d5e613e16565b5b600083013567ffffffffffffffff811115614d7d57614d7c613e1b565b5b614d8985828601614483565b925050602083013567ffffffffffffffff811115614daa57614da9613e1b565b5b614db685828601614d1a565b9150509250929050565b614dc981613ff4565b82525050565b6000602082019050614de46000830184614dc0565b92915050565b600080600060608486031215614e0357614e02613e16565b5b6000614e1186828701613f87565b935050602084013567ffffffffffffffff811115614e3257614e31613e1b565b5b614e3e86828701614135565b925050604084013567ffffffffffffffff811115614e5f57614e5e613e1b565b5b614e6b86828701614270565b9150509250925092565b600060a0820190508181036000830152614e8f8188614aa4565b90508181036020830152614ea38187614aa4565b9050614eb260408301866143c4565b614ebf6060830185614870565b614ecc6080830184614dc0565b9695505050505050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614f0c600f83614a69565b9150614f1782614ed6565b602082019050919050565b60006020820190508181036000830152614f3b81614eff565b9050919050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614fb3614fae83614f73565b614f80565b9050919050565b6000819050919050565b6000614fd7614fd283614f73565b614fba565b9050919050565b606082016000808301549050614ff381614fa0565b61500060008601826145c2565b506001830154905061501181614fc4565b61501e6020860182614680565b506002830154905061502f81614fc4565b61503c6040860182614680565b5050505050565b600061504f8383614fde565b60608301905092915050565b6000600382019050919050565b600061507382614f42565b61507d8185614f4d565b935061508883614f5e565b8060005b838110156150b8578161509f8882615043565b97506150aa8361505b565b92505060018101905061508c565b5085935050505092915050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b600060ff82169050919050565b600061511661511183614f73565b6150f6565b9050919050565b60808201600080830154905061513281614fa0565b61513f60008601826145c2565b506001830154905061515081614fc4565b61515d6020860182614680565b506002830154905061516e81614fc4565b61517b6040860182614680565b506003830154905061518c81615103565b615199606086018261473e565b5050505050565b60006151ac838361511d565b60808301905092915050565b6000600482019050919050565b60006151d0826150c5565b6151da81856150d0565b93506151e5836150e1565b8060005b8381101561521557816151fc88826151a0565b9750615207836151b8565b9250506001810190506151e9565b5085935050505092915050565b6000604083016000808401858303600087015261523f8382615068565b92505060018401858303602087015261525883826151c5565b925050819250505092915050565b600060208201905081810360008301526152808184615222565b905092915050565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b60006152be601283614a69565b91506152c982615288565b602082019050919050565b600060208201905081810360008301526152ed816152b1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061535d82613f66565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361538f5761538e615323565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b60006153d0601483614a69565b91506153db8261539a565b602082019050919050565b600060208201905081810360008301526153ff816153c3565b9050919050565b600060ff82169050919050565b600061541e82615406565b915060ff820361543157615430615323565b5b600182019050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b6000615472601183614a69565b915061547d8261543c565b602082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b7f544f54414c5f4f564552464c4f57000000000000000000000000000000000000600082015250565b60006154de600e83614a69565b91506154e9826154a8565b602082019050919050565b6000602082019050818103600083015261550d816154d1565b9050919050565b60006060820190506155296000830186614dc0565b61553660208301856143c4565b61554360408301846143c4565b949350505050565b60006040820190506155606000830185614dc0565b61556d60208301846143c4565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806155bb57607f821691505b6020821081036155ce576155cd615574565b5b50919050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b600061560a601083614a69565b9150615615826155d4565b602082019050919050565b60006020820190508181036000830152615639816155fd565b9050919050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b6000615676601283614a69565b915061568182615640565b602082019050919050565b600060208201905081810360008301526156a581615669565b9050919050565b7f4e4f545f444546494e4544000000000000000000000000000000000000000000600082015250565b60006156e2600b83614a69565b91506156ed826156ac565b602082019050919050565b60006020820190508181036000830152615711816156d5565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261577a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261573d565b615784868361573d565b95508019841693508086168417925050509392505050565b6000819050919050565b60006157c16157bc6157b784613f66565b61579c565b613f66565b9050919050565b6000819050919050565b6157db836157a6565b6157ef6157e7826157c8565b84845461574a565b825550505050565b600090565b6158046157f7565b61580f8184846157d2565b505050565b5b81811015615833576158286000826157fc565b600181019050615815565b5050565b601f8211156158785761584981615718565b6158528461572d565b81016020851015615861578190505b61587561586d8561572d565b830182615814565b50505b505050565b600082821c905092915050565b600061589b6000198460080261587d565b1980831691505092915050565b60006158b4838361588a565b9150826002028217905092915050565b6158cd82614a5e565b67ffffffffffffffff8111156158e6576158e5613e3b565b5b6158f082546155a3565b6158fb828285615837565b600060209050601f83116001811461592e576000841561591c578287015190505b61592685826158a8565b86555061598e565b601f19841661593c86615718565b60005b828110156159645784890151825560018201915060208501945060208101905061593f565b86831015615981578489015161597d601f89168261588a565b8355505b6001600288020188555050505b505050505050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b60006159cc600b83614a69565b91506159d782615996565b602082019050919050565b600060208201905081810360008301526159fb816159bf565b9050919050565b600081519050615a1181613fa8565b92915050565b600060208284031215615a2d57615a2c613e16565b5b6000615a3b84828501615a02565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615a7a600b83614a69565b9150615a8582615a44565b602082019050919050565b60006020820190508181036000830152615aa981615a6d565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615ae6600b83614a69565b9150615af182615ab0565b602082019050919050565b60006020820190508181036000830152615b1581615ad9565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b6000615b52600e83614a69565b9150615b5d82615b1c565b602082019050919050565b60006020820190508181036000830152615b8181615b45565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b6000615bbe600c83614a69565b9150615bc982615b88565b602082019050919050565b60006020820190508181036000830152615bed81615bb1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615c59600f83614a69565b9150615c6482615c23565b602082019050919050565b60006020820190508181036000830152615c8881615c4c565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b6000615cc5601083614a69565b9150615cd082615c8f565b602082019050919050565b60006020820190508181036000830152615cf481615cb8565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b6000615d31601083614a69565b9150615d3c82615cfb565b602082019050919050565b60006020820190508181036000830152615d6081615d24565b9050919050565b600081519050615d7681613f70565b92915050565b600060208284031215615d9257615d91613e16565b5b6000615da084828501615d67565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b6000615ddf601483614a69565b9150615dea82615da9565b602082019050919050565b60006020820190508181036000830152615e0e81615dd2565b9050919050565b6000606082019050615e2a6000830186614dc0565b615e376020830185614dc0565b615e4460408301846143c4565b949350505050565b6000615e5782613f66565b9150615e6283613f66565b9250828203905081811115615e7a57615e79615323565b5b92915050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b6000615eb6600b83614a69565b9150615ec182615e80565b602082019050919050565b60006020820190508181036000830152615ee581615ea9565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615f2181615eec565b82525050565b6000602082019050615f3c6000830184615f18565b9291505056fea2646970667358221220cb08554b1f337e1e4deee5d7146364d81d8ec0f459305b9284e05b1713f861de64736f6c63430008140033