Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ERC1155Extractors
- Optimization enabled
- false
- Compiler version
- v0.8.20+commit.a1b79de6
- EVM Version
- paris
- Verified at
- 2024-06-01T15:58:07.948636Z
Constructor Arguments
0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000013486f7065766572736520457874726163746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c4578747261637420466f6d756c6120666f7220486f7065766572736500000000
Arg [0] (string) : Hopeverse Extractor
Arg [1] (string) : Extract Fomula for Hopeverse
contracts/Craftable/ERC1155Extractors.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../base/TokenOperatableTemplateContract.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; contract ERC1155Extractors is TokenOperatableTemplateContract { using Math for uint256; using ERC165Checker for address; struct ExtractOutput{ address token_address; uint256 token_id; uint256 amount; bool multi_token; } struct ExtractFormula { address token_address; uint256 token_id; uint256 amount; ExtractOutput[] outputs; } uint256 private _templateIds; mapping(uint256 => ExtractFormula) private templates; event OnExtractFoumulaDefined(uint256 indexed template_id,ExtractFormula formula); event OnExtractFormulaUpdated(uint256 indexed template_id,ExtractFormula 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 _check_data_dimension(address[] memory addrs,uint256[] memory ids,uint256[] memory amounts) internal pure returns(bool){ return (addrs.length > 0) && (addrs.length == ids.length) && (addrs.length == amounts.length); } function _fill_template_input(uint256 tpl_id,address addr,uint256 id,uint256 amount) internal { require(amount > 0,"I_ZRO_AMT"); require(_is_operatable_erc1155(addr),"I_BAD_TOKEN"); IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(addr); require(asErc1155.isTokenDefined(id),"NO_TOKEN_ID"); templates[tpl_id].token_address = addr; templates[tpl_id].token_id = id; templates[tpl_id].amount = amount; } function _fill_template_outputs(uint256 tpl_id,ExtractOutput[] memory outputs) internal { for(uint256 i = 0; i < outputs.length; i++){ require(outputs[i].amount > 0,"O_ZRO_AMT"); bool is_erc1155 = _is_operatable_erc1155(outputs[i].token_address); bool is_erc721 = _is_operatable_erc721(outputs[i].token_address); require(is_erc1155 || is_erc721,"O_BAD_TOKEN"); if(is_erc1155){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(outputs[i].token_address); require(asErc1155.isTokenDefined(outputs[i].token_id),"NO_TOKEN_ID"); } templates[tpl_id].outputs.push(outputs[i]); } } function define_template(string memory name,string memory desc,uint256 op_price, bool start_enabled,address merchant,address currency, address in_address,uint256 in_id,uint256 in_amount, ExtractOutput[] memory outputs) external onlyOwner returns (uint256){ require(bytes(name).length > 0,"NO_NAME"); (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_input(tpl_id,in_address,in_id,in_amount); _fill_template_outputs(tpl_id,outputs); emit OnExtractFoumulaDefined(tpl_id,templates[tpl_id]); return tpl_id; } function udpate_template_formula(uint256 template_id, address in_address,uint256 in_id,uint256 in_amount, ExtractOutput[] memory outputs) external onlyOwner { require(is_defined(template_id),"NOT_DEFINED"); delete templates[template_id].outputs; _fill_template_input(template_id,in_address,in_id,in_amount); _fill_template_outputs(template_id,outputs); emit OnExtractFormulaUpdated(template_id,templates[template_id]); } function extract(uint256 template_id,uint256 applyCount) external payable{ require((applyCount > 0),"ZERO_APPLY_COUNT"); require(is_enabled(template_id),"TEMPLATE_DISABLED"); _check_valid_token(template_id); ExtractFormula memory template = templates[template_id]; (bool in_result,uint256 in_total) = template.amount.tryMul(applyCount); require(in_result,"TOTAL_OVERFLOW"); IOperatableERC1155Token in_asErc1155 = IOperatableERC1155Token(template.token_address); in_asErc1155.burnNFTFor(msg.sender, template.token_id,in_total); for(uint8 i = 0; i < template.outputs.length; i++) { (bool out_result,uint256 out_total) = template.outputs[i].amount.tryMul(applyCount); require(out_result,"TOTAL_OVERFLOW"); if(template.outputs[i].multi_token){ IOperatableERC1155Token out_asErc1155 = IOperatableERC1155Token(template.outputs[i].token_address); out_asErc1155.mintNFTFor(msg.sender, template.outputs[i].token_id,out_total); } else{ IOperatableERC721Token out_asErc721 = IOperatableERC721Token(template.outputs[i].token_address); out_asErc721.mintNFTsFor(msg.sender, out_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,uint256,uint256,address[] memory,uint256[] memory,uint256[] memory,bool[] memory){ ExtractFormula memory template = templates[template_id]; address _input_address = template.token_address; uint256 _input_token_id = template.token_id; uint256 _input_amount = template.amount; uint256 output_count = template.outputs.length; address[] memory _output_addresses = new address[](output_count); uint256[] memory _output_token_ids = new uint256[](output_count); uint256[] memory _output_amounts = new uint256[](output_count); bool[] memory _output_multitokens = new bool[](output_count); for(uint8 i = 0; i < output_count; 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_address,_input_token_id,_input_amount,_output_addresses,_output_token_ids,_output_amounts,_output_multitokens); } function _check_valid_token(uint256 tpl_id) internal view { IOperatableERC1155Token in_asErc1155 = IOperatableERC1155Token(templates[tpl_id].token_address); require(in_asErc1155.isTokenDefined(templates[tpl_id].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 out_asErc1155 = IOperatableERC1155Token(templates[tpl_id].outputs[i].token_address); require(out_asErc1155.isTokenDefined(templates[tpl_id].outputs[i].token_id),"NO_TOKEN_ID"); } } } }
@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); }
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); } }
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":"OnExtractFormulaUpdated","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Extractors.ExtractFormula","indexed":false,"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 ERC1155Extractors.ExtractOutput[]","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":"OnExtractFoumulaDefined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Extractors.ExtractFormula","indexed":false,"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 ERC1155Extractors.ExtractOutput[]","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":"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":"address","name":"in_address","internalType":"address"},{"type":"uint256","name":"in_id","internalType":"uint256"},{"type":"uint256","name":"in_amount","internalType":"uint256"},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Extractors.ExtractOutput[]","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":"payable","outputs":[],"name":"extract","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"uint256","name":"applyCount","internalType":"uint256"}]},{"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":"address","name":"in_address","internalType":"address"},{"type":"uint256","name":"in_id","internalType":"uint256"},{"type":"uint256","name":"in_amount","internalType":"uint256"},{"type":"tuple[]","name":"outputs","internalType":"struct ERC1155Extractors.ExtractOutput[]","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
0x60806040526000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200005357600080fd5b506040516200632138038062006321833981810160405281019062000079919062000402565b818133600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000f15760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000e89190620004cc565b60405180910390fd5b62000102816200017260201b60201c565b50816002908162000114919062000734565b50806003908162000126919062000734565b5033600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050506200081b565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055620001a881620001ab60201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002d8826200028d565b810181811067ffffffffffffffff82111715620002fa57620002f96200029e565b5b80604052505050565b60006200030f6200026f565b90506200031d8282620002cd565b919050565b600067ffffffffffffffff82111562000340576200033f6200029e565b5b6200034b826200028d565b9050602081019050919050565b60005b83811015620003785780820151818401526020810190506200035b565b60008484015250505050565b60006200039b620003958462000322565b62000303565b905082815260208101848484011115620003ba57620003b962000288565b5b620003c784828562000358565b509392505050565b600082601f830112620003e757620003e662000283565b5b8151620003f984826020860162000384565b91505092915050565b600080604083850312156200041c576200041b62000279565b5b600083015167ffffffffffffffff8111156200043d576200043c6200027e565b5b6200044b85828601620003cf565b925050602083015167ffffffffffffffff8111156200046f576200046e6200027e565b5b6200047d85828601620003cf565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004b48262000487565b9050919050565b620004c681620004a7565b82525050565b6000602082019050620004e36000830184620004bb565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200053c57607f821691505b602082108103620005525762000551620004f4565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005bc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057d565b620005c886836200057d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006156200060f6200060984620005e0565b620005ea565b620005e0565b9050919050565b6000819050919050565b6200063183620005f4565b6200064962000640826200061c565b8484546200058a565b825550505050565b600090565b6200066062000651565b6200066d81848462000626565b505050565b5b8181101562000695576200068960008262000656565b60018101905062000673565b5050565b601f821115620006e457620006ae8162000558565b620006b9846200056d565b81016020851015620006c9578190505b620006e1620006d8856200056d565b83018262000672565b50505b505050565b600082821c905092915050565b60006200070960001984600802620006e9565b1980831691505092915050565b6000620007248383620006f6565b9150826002028217905092915050565b6200073f82620004e9565b67ffffffffffffffff8111156200075b576200075a6200029e565b5b62000767825462000523565b6200077482828562000699565b600060209050601f831160018114620007ac576000841562000797578287015190505b620007a3858262000716565b86555062000813565b601f198416620007bc8662000558565b60005b82811015620007e657848901518255600182019150602085019450602081019050620007bf565b8683101562000806578489015162000802601f891682620006f6565b8355505b6001600288020188555050505b505050505050565b615af6806200082b6000396000f3fe6080604052600436106101cd5760003560e01c806379ba5097116100f7578063bb21ac5411610095578063df8e759a11610064578063df8e759a1461067d578063e30c3978146106ba578063e55661bd146106e5578063f2fde38b14610722576101cd565b8063bb21ac54146105ad578063d86ce789146105d6578063dd99b73d146105ff578063dda0da0014610640576101cd565b80638da5cb5b116100d15780638da5cb5b146104df578063a3066e431461050a578063b8c7871a14610533578063ba84860814610570576101cd565b806379ba5097146104815780638139e0f614610498578063839d7f11146104b4576101cd565b806330546c9b1161016f5780635458c28e1161013e5780635458c28e146103ef5780636586bb7014610418578063715018a61461044157806376967cbf14610458576101cd565b806330546c9b146103475780633a525c29146103705780633b9ebeec1461039b5780633f84dc1b146103c4576101cd565b806319df1182116101ab57806319df1182146102675780631a7db56e146102a4578063284293cf146102cd5780632f0630231461030a576101cd565b80630f6bec9a146101d25780630fe42159146101fb578063189357ff14610224575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f49190613b77565b61074b565b005b34801561020757600080fd5b50610222600480360381019061021d9190613c85565b6107f9565b005b34801561023057600080fd5b5061024b60048036038101906102469190613cc5565b6108cb565b60405161025e9796959493929190613f4a565b60405180910390f35b34801561027357600080fd5b5061028e60048036038101906102899190613cc5565b610d3e565b60405161029b9190613fe4565b60405180910390f35b3480156102b057600080fd5b506102cb60048036038101906102c691906140c2565b610d68565b005b3480156102d957600080fd5b506102f460048036038101906102ef9190613cc5565b610e16565b6040516103019190613fe4565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c919061432f565b610e40565b60405161033e9190614462565b60405180910390f35b34801561035357600080fd5b5061036e6004803603810190610369919061447d565b610f74565b005b34801561037c57600080fd5b50610385610fc2565b6040516103929190614545565b60405180910390f35b3480156103a757600080fd5b506103c260048036038101906103bd919061462a565b611054565b005b3480156103d057600080fd5b506103d9611102565b6040516103e69190614462565b60405180910390f35b3480156103fb57600080fd5b50610416600480360381019061041191906140c2565b61110c565b005b34801561042457600080fd5b5061043f600480360381019061043a91906146a2565b6111ba565b005b34801561044d57600080fd5b506104566112d0565b005b34801561046457600080fd5b5061047f600480360381019061047a91906147b0565b6112e4565b005b34801561048d57600080fd5b50610496611392565b005b6104b260048036038101906104ad9190614828565b611421565b005b3480156104c057600080fd5b506104c9611941565b6040516104d69190614545565b60405180910390f35b3480156104eb57600080fd5b506104f46119d3565b6040516105019190614868565b60405180910390f35b34801561051657600080fd5b50610531600480360381019061052c91906147b0565b6119fc565b005b34801561053f57600080fd5b5061055a60048036038101906105559190613cc5565b611aaa565b6040516105679190613fe4565b60405180910390f35b34801561057c57600080fd5b50610597600480360381019061059291906146a2565b611ad5565b6040516105a49190613fe4565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf91906146a2565b611b2b565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190614883565b611c36565b005b34801561060b57600080fd5b5061062660048036038101906106219190613cc5565b611d0f565b60405161063795949392919061491a565b60405180910390f35b34801561064c57600080fd5b5061066760048036038101906106629190613cc5565b611ea6565b6040516106749190613fe4565b60405180910390f35b34801561068957600080fd5b506106a4600480360381019061069f9190613cc5565b611eb8565b6040516106b19190614868565b60405180910390f35b3480156106c657600080fd5b506106cf611f57565b6040516106dc9190614868565b60405180910390f35b3480156106f157600080fd5b5061070c60048036038101906107079190613cc5565b611f81565b6040516107199190614868565b60405180910390f35b34801561072e57600080fd5b50610749600480360381019061074491906146a2565b612020565b005b6107536120cd565b8051825114610797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078e906149c7565b60405180910390fd5b60005b82518110156107f4576107e18382815181106107b9576107b86149e7565b5b60200260200101518383815181106107d4576107d36149e7565b5b6020026020010151612167565b80806107ec90614a45565b91505061079a565b505050565b6108016121cb565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086790614ad9565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008060006060806060806000600e60008a81526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610a3c57838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190610985565b505050508152505090506000816000015190506000826020015190506000836040015190506000846060015151905060008167ffffffffffffffff811115610a8757610a866139fe565b5b604051908082528060200260200182016040528015610ab55781602001602082028036833780820191505090505b50905060008267ffffffffffffffff811115610ad457610ad36139fe565b5b604051908082528060200260200182016040528015610b025781602001602082028036833780820191505090505b50905060008367ffffffffffffffff811115610b2157610b206139fe565b5b604051908082528060200260200182016040528015610b4f5781602001602082028036833780820191505090505b50905060008467ffffffffffffffff811115610b6e57610b6d6139fe565b5b604051908082528060200260200182016040528015610b9c5781602001602082028036833780820191505090505b50905060005b858160ff161015610d145789606001518160ff1681518110610bc757610bc66149e7565b5b602002602001015160000151858260ff1681518110610be957610be86149e7565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505089606001518160ff1681518110610c3d57610c3c6149e7565b5b602002602001015160200151848260ff1681518110610c5f57610c5e6149e7565b5b60200260200101818152505089606001518160ff1681518110610c8557610c846149e7565b5b602002602001015160400151838260ff1681518110610ca757610ca66149e7565b5b60200260200101818152505089606001518160ff1681518110610ccd57610ccc6149e7565b5b602002602001015160600151828260ff1681518110610cef57610cee6149e7565b5b6020026020010190151590811515815250508080610d0c90614b06565b915050610ba2565b50878787868686869f509f509f509f509f509f509f50505050505050505050919395979092949650565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610d706120cd565b8051825114610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab906149c7565b60405180910390fd5b60005b8251811015610e1157610dfe838281518110610dd657610dd56149e7565b5b6020026020010151838381518110610df157610df06149e7565b5b6020026020010151612252565b8080610e0990614a45565b915050610db7565b505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6000610e4a6121cb565b60008b5111610e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8590614b7b565b60405180910390fd5b600080610ea76001600d5461235f90919063ffffffff16565b9150915080600d8190555081610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990614be7565b60405180910390fd5b610f01818e8e8e8e8e8e61238e565b610f0d818888886124c0565b610f17818561269b565b807f544b036352dc392f037f10719c187304b9313f6d7b98808ff40ecfce8ef0f9e9600e6000848152602001908152602001600020604051610f599190614e54565b60405180910390a280925050509a9950505050505050505050565b610f7c6120cd565b60005b8151811015610fbe57610fab828281518110610f9e57610f9d6149e7565b5b6020026020010151612999565b8080610fb690614a45565b915050610f7f565b5050565b606060028054610fd190614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ffd90614ea5565b801561104a5780601f1061101f5761010080835404028352916020019161104a565b820191906000526020600020905b81548152906001019060200180831161102d57829003601f168201915b5050505050905090565b61105c6120cd565b80518251146110a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611097906149c7565b60405180910390fd5b60005b82518110156110fd576110ea8382815181106110c2576110c16149e7565b5b60200260200101518383815181106110dd576110dc6149e7565b5b6020026020010151612a2d565b80806110f590614a45565b9150506110a3565b505050565b6000600d54905090565b6111146120cd565b8051825114611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f906149c7565b60405180910390fd5b60005b82518110156111b5576111a283828151811061117a576111796149e7565b5b6020026020010151838381518110611195576111946149e7565b5b6020026020010151612aa4565b80806111ad90614a45565b91505061115b565b505050565b6111c26120cd565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415801561124d5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61128c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390614f22565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6112d86121cb565b6112e26000612bb1565b565b6112ec6120cd565b8051825114611330576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611327906149c7565b60405180910390fd5b60005b825181101561138d5761137a838281518110611352576113516149e7565b5b602002602001015183838151811061136d5761136c6149e7565b5b6020026020010151612be2565b808061138590614a45565b915050611333565b505050565b600061139c612cad565b90508073ffffffffffffffffffffffffffffffffffffffff166113bd611f57565b73ffffffffffffffffffffffffffffffffffffffff161461141557806040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161140c9190614868565b60405180910390fd5b61141e81612bb1565b50565b60008111611464576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145b90614f8e565b60405180910390fd5b61146d82610d3e565b6114ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a390614ffa565b60405180910390fd5b6114b582612cb5565b6000600e60008481526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561161b57838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190611564565b5050505081525050905060008061163f848460400151612fa590919063ffffffff16565b9150915081611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167a90615066565b60405180910390fd5b6000836000015190508073ffffffffffffffffffffffffffffffffffffffff1663cbc7067c338660200151856040518463ffffffff1660e01b81526004016116cd93929190615086565b600060405180830381600087803b1580156116e757600080fd5b505af11580156116fb573d6000803e3d6000fd5b5050505060005b8460600151518160ff16101561192e5760008061174d8888606001518560ff1681518110611733576117326149e7565b5b602002602001015160400151612fa590919063ffffffff16565b9150915081611791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178890615066565b60405180910390fd5b86606001518360ff16815181106117ab576117aa6149e7565b5b6020026020010151606001511561188057600087606001518460ff16815181106117d8576117d76149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff166325f5e8ee338a606001518760ff168151811061181d5761181c6149e7565b5b602002602001015160200151856040518463ffffffff1660e01b815260040161184893929190615086565b600060405180830381600087803b15801561186257600080fd5b505af1158015611876573d6000803e3d6000fd5b5050505050611919565b600087606001518460ff168151811061189c5761189b6149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663f0a8587b33846040518363ffffffff1660e01b81526004016118e59291906150bd565b600060405180830381600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b50505050505b5050808061192690614b06565b915050611702565b506119398686612ff8565b505050505050565b60606003805461195090614ea5565b80601f016020809104026020016040519081016040528092919081815260200182805461197c90614ea5565b80156119c95780601f1061199e576101008083540402835291602001916119c9565b820191906000526020600020905b8154815290600101906020018083116119ac57829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a046120cd565b8051825114611a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3f906149c7565b60405180910390fd5b60005b8251811015611aa557611a92838281518110611a6a57611a696149e7565b5b6020026020010151838381518110611a8557611a846149e7565b5b60200260200101516133fe565b8080611a9d90614a45565b915050611a4b565b505050565b600080600460008481526020019081526020016000208054611acb90614ea5565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611b336120cd565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480611bb35750611bb27f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b611bf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be990615132565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611c3e6121cb565b611c4785611aaa565b611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061519e565b60405180910390fd5b600e60008681526020019081526020016000206003016000611ca891906138f1565b611cb4858585856124c0565b611cbe858261269b565b847ff9dc306cb995b9c7f719d16639775625d9c649f81fd40a0f998ec775c09e62d6600e6000888152602001908152602001600020604051611d009190614e54565b60405180910390a25050505050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff16611d7b8a611eb8565b848054611d8790614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054611db390614ea5565b8015611e005780601f10611dd557610100808354040283529160200191611e00565b820191906000526020600020905b815481529060010190602001808311611de357829003601f168201915b50505050509450838054611e1390614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3f90614ea5565b8015611e8c5780601f10611e6157610100808354040283529160200191611e8c565b820191906000526020600020905b815481529060010190602001808311611e6f57829003601f168201915b505050505093509450945094509450945091939590929450565b6000611eb182611aaa565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f4d57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611f4f565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361201657600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612018565b805b915050919050565b6120286121cb565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166120886119d3565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60006120d7612cad565b90508073ffffffffffffffffffffffffffffffffffffffff166120f86119d3565b73ffffffffffffffffffffffffffffffffffffffff1614158015612122575061212081613490565b155b1561216457806040517f8a08cbf500000000000000000000000000000000000000000000000000000000815260040161215b9190614868565b60405180910390fd5b50565b61217082611aaa565b6121af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a69061520a565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b6121d3612cad565b73ffffffffffffffffffffffffffffffffffffffff166121f16119d3565b73ffffffffffffffffffffffffffffffffffffffff161461225057612214612cad565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122479190614868565b60405180910390fd5b565b61225b82611aaa565b61229a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122919061520a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230090615276565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080600083850190508481101561237e576000809250925050612387565b60018192509250505b9250929050565b856004600089815260200190815260200160002090816123ae9190615442565b50846005600089815260200190815260200160002090816123cf9190615442565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b60008111612503576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124fa90615560565b60405180910390fd5b61250c836134e6565b61254b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612542906155cc565b60405180910390fd5b60008390508073ffffffffffffffffffffffffffffffffffffffff1663b419c807846040518263ffffffff1660e01b81526004016125899190614462565b602060405180830381865afa1580156125a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ca9190615601565b612609576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126009061567a565b60405180910390fd5b83600e600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600e60008781526020019081526020016000206001018190555081600e6000878152602001908152602001600020600201819055505050505050565b60005b81518110156129945760008282815181106126bc576126bb6149e7565b5b60200260200101516040015111612708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ff906156e6565b60405180910390fd5b60006127318383815181106127205761271f6149e7565b5b6020026020010151600001516134e6565b9050600061275c84848151811061274b5761274a6149e7565b5b602002602001015160000151613570565b905081806127675750805b6127a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279d90615752565b60405180910390fd5b81156128a85760008484815181106127c1576127c06149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c8078686815181106127fe576127fd6149e7565b5b6020026020010151602001516040518263ffffffff1660e01b81526004016128269190614462565b602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128679190615601565b6128a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289d9061567a565b60405180910390fd5b505b600e60008681526020019081526020016000206003018484815181106128d1576128d06149e7565b5b6020026020010151908060018154018082558091505060019003906000526020600020906004020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555050505050808061298c90614a45565b91505061269e565b505050565b6129a281611aaa565b6129e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d89061520a565b60405180910390fd5b6129ea816135fa565b6129f3816136e1565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b781604051612a229190614462565b60405180910390a150565b612a3682611aaa565b612a75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6c9061520a565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b612aad82611aaa565b612aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae39061520a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b5290615276565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055612bdf81613741565b50565b6000600460008481526020019081526020016000208054612c0290614ea5565b905011612c44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3b9061520a565b60405180910390fd5b6000815111612c88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7f906157be565b60405180910390fd5b80600460008481526020019081526020016000209081612ca89190615442565b505050565b600033905090565b6000600e600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e6000858152602001908152602001600020600101546040518263ffffffff1660e01b8152600401612d3f9190614462565b602060405180830381865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d809190615601565b612dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612db69061567a565b60405180910390fd5b6000600e600084815260200190815260200160002060030180549050905060005b81811015612f9f576000600e60008681526020019081526020016000206003018281548110612e1257612e116149e7565b5b906000526020600020906004020160030160009054906101000a900460ff1690508015612f8b576000600e60008781526020019081526020016000206003018381548110612e6357612e626149e7565b5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008981526020019081526020016000206003018581548110612edb57612eda6149e7565b5b9060005260206000209060040201600101546040518263ffffffff1660e01b8152600401612f099190614462565b602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a9190615601565b612f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f809061567a565b60405180910390fd5b505b508080612f9790614a45565b915050612de0565b50505050565b60008060008403612fbd576001600091509150612ff1565b6000838502905083858281612fd557612fd46157de565b5b0414612fe8576000809250925050612ff1565b60018192509250505b9250929050565b6000811161303b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303290615859565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361306157506133fa565b600061306c84611eb8565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036130dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130d4906158c5565b60405180910390fd5b6000806130f38585612fa590919063ffffffff16565b9150915081613137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312e90615931565b60405180910390fd5b600061314287611f81565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133115760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016131b39190614868565b602060405180830381865afa1580156131d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f49190615966565b905082811015613239576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613230906159df565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b8152600401613276939291906159ff565b6020604051808303816000875af1158015613295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b99190615601565b50600034111561330b573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015613309573d6000803e3d6000fd5b505b506133f4565b81341015613354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161334b906159df565b60405180910390fd5b600082346133629190615a36565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156133aa573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156133f1573d6000803e3d6000fd5b50505b50505050505b5050565b61340782611aaa565b613446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161343d9061520a565b60405180910390fd5b806005600084815260200190815260200160002090816134669190615442565b505050565b600061347683613805565b801561348857506134878383613852565b5b905092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561356957506135687ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156135f357506135f27f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b9050919050565b6004600082815260200190815260200160002060006136199190613915565b6005600082815260200190815260200160002060006136389190613915565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600e6000828152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905560038201600061373c91906138f1565b505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613831827f01ffc9a700000000000000000000000000000000000000000000000000000000613852565b801561384b57506138498263ffffffff60e01b613852565b155b9050919050565b600080826040516024016138669190615aa5565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d915060005190508280156138d9575060208210155b80156138e55750600081115b94505050505092915050565b50805460008255600402906000526020600020908101906139129190613955565b50565b50805461392190614ea5565b6000825580601f106139335750613952565b601f01602090049060005260206000209081019061395191906139b7565b5b50565b5b808211156139b357600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201600090556003820160006101000a81549060ff021916905550600401613956565b5090565b5b808211156139d05760008160009055506001016139b8565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a36826139ed565b810181811067ffffffffffffffff82111715613a5557613a546139fe565b5b80604052505050565b6000613a686139d4565b9050613a748282613a2d565b919050565b600067ffffffffffffffff821115613a9457613a936139fe565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b613abd81613aaa565b8114613ac857600080fd5b50565b600081359050613ada81613ab4565b92915050565b6000613af3613aee84613a79565b613a5e565b90508083825260208201905060208402830185811115613b1657613b15613aa5565b5b835b81811015613b3f5780613b2b8882613acb565b845260208401935050602081019050613b18565b5050509392505050565b600082601f830112613b5e57613b5d6139e8565b5b8135613b6e848260208601613ae0565b91505092915050565b60008060408385031215613b8e57613b8d6139de565b5b600083013567ffffffffffffffff811115613bac57613bab6139e3565b5b613bb885828601613b49565b925050602083013567ffffffffffffffff811115613bd957613bd86139e3565b5b613be585828601613b49565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c1a82613bef565b9050919050565b613c2a81613c0f565b8114613c3557600080fd5b50565b600081359050613c4781613c21565b92915050565b60008115159050919050565b613c6281613c4d565b8114613c6d57600080fd5b50565b600081359050613c7f81613c59565b92915050565b60008060408385031215613c9c57613c9b6139de565b5b6000613caa85828601613c38565b9250506020613cbb85828601613c70565b9150509250929050565b600060208284031215613cdb57613cda6139de565b5b6000613ce984828501613acb565b91505092915050565b613cfb81613c0f565b82525050565b613d0a81613aaa565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613d4581613c0f565b82525050565b6000613d578383613d3c565b60208301905092915050565b6000602082019050919050565b6000613d7b82613d10565b613d858185613d1b565b9350613d9083613d2c565b8060005b83811015613dc1578151613da88882613d4b565b9750613db383613d63565b925050600181019050613d94565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613e0381613aaa565b82525050565b6000613e158383613dfa565b60208301905092915050565b6000602082019050919050565b6000613e3982613dce565b613e438185613dd9565b9350613e4e83613dea565b8060005b83811015613e7f578151613e668882613e09565b9750613e7183613e21565b925050600181019050613e52565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613ec181613c4d565b82525050565b6000613ed38383613eb8565b60208301905092915050565b6000602082019050919050565b6000613ef782613e8c565b613f018185613e97565b9350613f0c83613ea8565b8060005b83811015613f3d578151613f248882613ec7565b9750613f2f83613edf565b925050600181019050613f10565b5085935050505092915050565b600060e082019050613f5f600083018a613cf2565b613f6c6020830189613d01565b613f796040830188613d01565b8181036060830152613f8b8187613d70565b90508181036080830152613f9f8186613e2e565b905081810360a0830152613fb38185613e2e565b905081810360c0830152613fc78184613eec565b905098975050505050505050565b613fde81613c4d565b82525050565b6000602082019050613ff96000830184613fd5565b92915050565b600067ffffffffffffffff82111561401a576140196139fe565b5b602082029050602081019050919050565b600061403e61403984613fff565b613a5e565b9050808382526020820190506020840283018581111561406157614060613aa5565b5b835b8181101561408a57806140768882613c38565b845260208401935050602081019050614063565b5050509392505050565b600082601f8301126140a9576140a86139e8565b5b81356140b984826020860161402b565b91505092915050565b600080604083850312156140d9576140d86139de565b5b600083013567ffffffffffffffff8111156140f7576140f66139e3565b5b61410385828601613b49565b925050602083013567ffffffffffffffff811115614124576141236139e3565b5b61413085828601614094565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561415a576141596139fe565b5b614163826139ed565b9050602081019050919050565b82818337600083830152505050565b600061419261418d8461413f565b613a5e565b9050828152602081018484840111156141ae576141ad61413a565b5b6141b9848285614170565b509392505050565b600082601f8301126141d6576141d56139e8565b5b81356141e684826020860161417f565b91505092915050565b600067ffffffffffffffff82111561420a576142096139fe565b5b602082029050602081019050919050565b600080fd5b6000608082840312156142365761423561421b565b5b6142406080613a5e565b9050600061425084828501613c38565b600083015250602061426484828501613acb565b602083015250604061427884828501613acb565b604083015250606061428c84828501613c70565b60608301525092915050565b60006142ab6142a6846141ef565b613a5e565b905080838252602082019050608084028301858111156142ce576142cd613aa5565b5b835b818110156142f757806142e38882614220565b8452602084019350506080810190506142d0565b5050509392505050565b600082601f830112614316576143156139e8565b5b8135614326848260208601614298565b91505092915050565b6000806000806000806000806000806101408b8d031215614353576143526139de565b5b60008b013567ffffffffffffffff811115614371576143706139e3565b5b61437d8d828e016141c1565b9a505060208b013567ffffffffffffffff81111561439e5761439d6139e3565b5b6143aa8d828e016141c1565b99505060406143bb8d828e01613acb565b98505060606143cc8d828e01613c70565b97505060806143dd8d828e01613c38565b96505060a06143ee8d828e01613c38565b95505060c06143ff8d828e01613c38565b94505060e06144108d828e01613acb565b9350506101006144228d828e01613acb565b9250506101208b013567ffffffffffffffff811115614444576144436139e3565b5b6144508d828e01614301565b9150509295989b9194979a5092959850565b60006020820190506144776000830184613d01565b92915050565b600060208284031215614493576144926139de565b5b600082013567ffffffffffffffff8111156144b1576144b06139e3565b5b6144bd84828501613b49565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156145005780820151818401526020810190506144e5565b60008484015250505050565b6000614517826144c6565b61452181856144d1565b93506145318185602086016144e2565b61453a816139ed565b840191505092915050565b6000602082019050818103600083015261455f818461450c565b905092915050565b600067ffffffffffffffff821115614582576145816139fe565b5b602082029050602081019050919050565b60006145a66145a184614567565b613a5e565b905080838252602082019050602084028301858111156145c9576145c8613aa5565b5b835b818110156145f257806145de8882613c70565b8452602084019350506020810190506145cb565b5050509392505050565b600082601f830112614611576146106139e8565b5b8135614621848260208601614593565b91505092915050565b60008060408385031215614641576146406139de565b5b600083013567ffffffffffffffff81111561465f5761465e6139e3565b5b61466b85828601613b49565b925050602083013567ffffffffffffffff81111561468c5761468b6139e3565b5b614698858286016145fc565b9150509250929050565b6000602082840312156146b8576146b76139de565b5b60006146c684828501613c38565b91505092915050565b600067ffffffffffffffff8211156146ea576146e96139fe565b5b602082029050602081019050919050565b600061470e614709846146cf565b613a5e565b9050808382526020820190506020840283018581111561473157614730613aa5565b5b835b8181101561477857803567ffffffffffffffff811115614756576147556139e8565b5b80860161476389826141c1565b85526020850194505050602081019050614733565b5050509392505050565b600082601f830112614797576147966139e8565b5b81356147a78482602086016146fb565b91505092915050565b600080604083850312156147c7576147c66139de565b5b600083013567ffffffffffffffff8111156147e5576147e46139e3565b5b6147f185828601613b49565b925050602083013567ffffffffffffffff811115614812576148116139e3565b5b61481e85828601614782565b9150509250929050565b6000806040838503121561483f5761483e6139de565b5b600061484d85828601613acb565b925050602061485e85828601613acb565b9150509250929050565b600060208201905061487d6000830184613cf2565b92915050565b600080600080600060a0868803121561489f5761489e6139de565b5b60006148ad88828901613acb565b95505060206148be88828901613c38565b94505060406148cf88828901613acb565b93505060606148e088828901613acb565b925050608086013567ffffffffffffffff811115614901576149006139e3565b5b61490d88828901614301565b9150509295509295909350565b600060a0820190508181036000830152614934818861450c565b90508181036020830152614948818761450c565b90506149576040830186613d01565b6149646060830185613fd5565b6149716080830184613cf2565b9695505050505050565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b60006149b16012836144d1565b91506149bc8261497b565b602082019050919050565b600060208201905081810360008301526149e0816149a4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a5082613aaa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a8257614a81614a16565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b6000614ac36014836144d1565b9150614ace82614a8d565b602082019050919050565b60006020820190508181036000830152614af281614ab6565b9050919050565b600060ff82169050919050565b6000614b1182614af9565b915060ff8203614b2457614b23614a16565b5b600182019050919050565b7f4e4f5f4e414d4500000000000000000000000000000000000000000000000000600082015250565b6000614b656007836144d1565b9150614b7082614b2f565b602082019050919050565b60006020820190508181036000830152614b9481614b58565b9050919050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614bd1600f836144d1565b9150614bdc82614b9b565b602082019050919050565b60006020820190508181036000830152614c0081614bc4565b9050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614c47614c4283614c07565b614c14565b9050919050565b6000819050919050565b6000614c6b614c6683614c07565b614c4e565b9050919050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b600060ff82169050919050565b6000614cc3614cbe83614c07565b614ca3565b9050919050565b608082016000808301549050614cdf81614c34565b614cec6000860182613d3c565b5060018301549050614cfd81614c58565b614d0a6020860182613dfa565b5060028301549050614d1b81614c58565b614d286040860182613dfa565b5060038301549050614d3981614cb0565b614d466060860182613eb8565b5050505050565b6000614d598383614cca565b60808301905092915050565b6000600482019050919050565b6000614d7d82614c72565b614d878185614c7d565b9350614d9283614c8e565b8060005b83811015614dc25781614da98882614d4d565b9750614db483614d65565b925050600181019050614d96565b5085935050505092915050565b6000608083016000808401549050614de681614c34565b614df36000870182613d3c565b5060018401549050614e0481614c58565b614e116020870182613dfa565b5060028401549050614e2281614c58565b614e2f6040870182613dfa565b50600384018583036060870152614e468382614d72565b925050819250505092915050565b60006020820190508181036000830152614e6e8184614dcf565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614ebd57607f821691505b602082108103614ed057614ecf614e76565b5b50919050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b6000614f0c6010836144d1565b9150614f1782614ed6565b602082019050919050565b60006020820190508181036000830152614f3b81614eff565b9050919050565b7f5a45524f5f4150504c595f434f554e5400000000000000000000000000000000600082015250565b6000614f786010836144d1565b9150614f8382614f42565b602082019050919050565b60006020820190508181036000830152614fa781614f6b565b9050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b6000614fe46011836144d1565b9150614fef82614fae565b602082019050919050565b6000602082019050818103600083015261501381614fd7565b9050919050565b7f544f54414c5f4f564552464c4f57000000000000000000000000000000000000600082015250565b6000615050600e836144d1565b915061505b8261501a565b602082019050919050565b6000602082019050818103600083015261507f81615043565b9050919050565b600060608201905061509b6000830186613cf2565b6150a86020830185613d01565b6150b56040830184613d01565b949350505050565b60006040820190506150d26000830185613cf2565b6150df6020830184613d01565b9392505050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b600061511c6012836144d1565b9150615127826150e6565b602082019050919050565b6000602082019050818103600083015261514b8161510f565b9050919050565b7f4e4f545f444546494e4544000000000000000000000000000000000000000000600082015250565b6000615188600b836144d1565b915061519382615152565b602082019050919050565b600060208201905081810360008301526151b78161517b565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b60006151f4600e836144d1565b91506151ff826151be565b602082019050919050565b60006020820190508181036000830152615223816151e7565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b6000615260600c836144d1565b915061526b8261522a565b602082019050919050565b6000602082019050818103600083015261528f81615253565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026152f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826152bb565b61530286836152bb565b95508019841693508086168417925050509392505050565b6000819050919050565b600061533f61533a61533584613aaa565b61531a565b613aaa565b9050919050565b6000819050919050565b61535983615324565b61536d61536582615346565b8484546152c8565b825550505050565b600090565b615382615375565b61538d818484615350565b505050565b5b818110156153b1576153a660008261537a565b600181019050615393565b5050565b601f8211156153f6576153c781615296565b6153d0846152ab565b810160208510156153df578190505b6153f36153eb856152ab565b830182615392565b50505b505050565b600082821c905092915050565b6000615419600019846008026153fb565b1980831691505092915050565b60006154328383615408565b9150826002028217905092915050565b61544b826144c6565b67ffffffffffffffff811115615464576154636139fe565b5b61546e8254614ea5565b6154798282856153b5565b600060209050601f8311600181146154ac576000841561549a578287015190505b6154a48582615426565b86555061550c565b601f1984166154ba86615296565b60005b828110156154e2578489015182556001820191506020850194506020810190506154bd565b868310156154ff57848901516154fb601f891682615408565b8355505b6001600288020188555050505b505050505050565b7f495f5a524f5f414d540000000000000000000000000000000000000000000000600082015250565b600061554a6009836144d1565b915061555582615514565b602082019050919050565b600060208201905081810360008301526155798161553d565b9050919050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b60006155b6600b836144d1565b91506155c182615580565b602082019050919050565b600060208201905081810360008301526155e5816155a9565b9050919050565b6000815190506155fb81613c59565b92915050565b600060208284031215615617576156166139de565b5b6000615625848285016155ec565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615664600b836144d1565b915061566f8261562e565b602082019050919050565b6000602082019050818103600083015261569381615657565b9050919050565b7f4f5f5a524f5f414d540000000000000000000000000000000000000000000000600082015250565b60006156d06009836144d1565b91506156db8261569a565b602082019050919050565b600060208201905081810360008301526156ff816156c3565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b600061573c600b836144d1565b915061574782615706565b602082019050919050565b6000602082019050818103600083015261576b8161572f565b9050919050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b60006157a8600b836144d1565b91506157b382615772565b602082019050919050565b600060208201905081810360008301526157d78161579b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615843600f836144d1565b915061584e8261580d565b602082019050919050565b6000602082019050818103600083015261587281615836565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b60006158af6010836144d1565b91506158ba82615879565b602082019050919050565b600060208201905081810360008301526158de816158a2565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b600061591b6010836144d1565b9150615926826158e5565b602082019050919050565b6000602082019050818103600083015261594a8161590e565b9050919050565b60008151905061596081613ab4565b92915050565b60006020828403121561597c5761597b6139de565b5b600061598a84828501615951565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b60006159c96014836144d1565b91506159d482615993565b602082019050919050565b600060208201905081810360008301526159f8816159bc565b9050919050565b6000606082019050615a146000830186613cf2565b615a216020830185613cf2565b615a2e6040830184613d01565b949350505050565b6000615a4182613aaa565b9150615a4c83613aaa565b9250828203905081811115615a6457615a63614a16565b5b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615a9f81615a6a565b82525050565b6000602082019050615aba6000830184615a96565b9291505056fea2646970667358221220001d66719f5024a678d58593f80ff63aa7ce6e3af38285fb85dedbe9f079019164736f6c63430008140033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000013486f7065766572736520457874726163746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c4578747261637420466f6d756c6120666f7220486f7065766572736500000000
Deployed ByteCode
0x6080604052600436106101cd5760003560e01c806379ba5097116100f7578063bb21ac5411610095578063df8e759a11610064578063df8e759a1461067d578063e30c3978146106ba578063e55661bd146106e5578063f2fde38b14610722576101cd565b8063bb21ac54146105ad578063d86ce789146105d6578063dd99b73d146105ff578063dda0da0014610640576101cd565b80638da5cb5b116100d15780638da5cb5b146104df578063a3066e431461050a578063b8c7871a14610533578063ba84860814610570576101cd565b806379ba5097146104815780638139e0f614610498578063839d7f11146104b4576101cd565b806330546c9b1161016f5780635458c28e1161013e5780635458c28e146103ef5780636586bb7014610418578063715018a61461044157806376967cbf14610458576101cd565b806330546c9b146103475780633a525c29146103705780633b9ebeec1461039b5780633f84dc1b146103c4576101cd565b806319df1182116101ab57806319df1182146102675780631a7db56e146102a4578063284293cf146102cd5780632f0630231461030a576101cd565b80630f6bec9a146101d25780630fe42159146101fb578063189357ff14610224575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f49190613b77565b61074b565b005b34801561020757600080fd5b50610222600480360381019061021d9190613c85565b6107f9565b005b34801561023057600080fd5b5061024b60048036038101906102469190613cc5565b6108cb565b60405161025e9796959493929190613f4a565b60405180910390f35b34801561027357600080fd5b5061028e60048036038101906102899190613cc5565b610d3e565b60405161029b9190613fe4565b60405180910390f35b3480156102b057600080fd5b506102cb60048036038101906102c691906140c2565b610d68565b005b3480156102d957600080fd5b506102f460048036038101906102ef9190613cc5565b610e16565b6040516103019190613fe4565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c919061432f565b610e40565b60405161033e9190614462565b60405180910390f35b34801561035357600080fd5b5061036e6004803603810190610369919061447d565b610f74565b005b34801561037c57600080fd5b50610385610fc2565b6040516103929190614545565b60405180910390f35b3480156103a757600080fd5b506103c260048036038101906103bd919061462a565b611054565b005b3480156103d057600080fd5b506103d9611102565b6040516103e69190614462565b60405180910390f35b3480156103fb57600080fd5b50610416600480360381019061041191906140c2565b61110c565b005b34801561042457600080fd5b5061043f600480360381019061043a91906146a2565b6111ba565b005b34801561044d57600080fd5b506104566112d0565b005b34801561046457600080fd5b5061047f600480360381019061047a91906147b0565b6112e4565b005b34801561048d57600080fd5b50610496611392565b005b6104b260048036038101906104ad9190614828565b611421565b005b3480156104c057600080fd5b506104c9611941565b6040516104d69190614545565b60405180910390f35b3480156104eb57600080fd5b506104f46119d3565b6040516105019190614868565b60405180910390f35b34801561051657600080fd5b50610531600480360381019061052c91906147b0565b6119fc565b005b34801561053f57600080fd5b5061055a60048036038101906105559190613cc5565b611aaa565b6040516105679190613fe4565b60405180910390f35b34801561057c57600080fd5b50610597600480360381019061059291906146a2565b611ad5565b6040516105a49190613fe4565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf91906146a2565b611b2b565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190614883565b611c36565b005b34801561060b57600080fd5b5061062660048036038101906106219190613cc5565b611d0f565b60405161063795949392919061491a565b60405180910390f35b34801561064c57600080fd5b5061066760048036038101906106629190613cc5565b611ea6565b6040516106749190613fe4565b60405180910390f35b34801561068957600080fd5b506106a4600480360381019061069f9190613cc5565b611eb8565b6040516106b19190614868565b60405180910390f35b3480156106c657600080fd5b506106cf611f57565b6040516106dc9190614868565b60405180910390f35b3480156106f157600080fd5b5061070c60048036038101906107079190613cc5565b611f81565b6040516107199190614868565b60405180910390f35b34801561072e57600080fd5b50610749600480360381019061074491906146a2565b612020565b005b6107536120cd565b8051825114610797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078e906149c7565b60405180910390fd5b60005b82518110156107f4576107e18382815181106107b9576107b86149e7565b5b60200260200101518383815181106107d4576107d36149e7565b5b6020026020010151612167565b80806107ec90614a45565b91505061079a565b505050565b6108016121cb565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086790614ad9565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008060006060806060806000600e60008a81526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610a3c57838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190610985565b505050508152505090506000816000015190506000826020015190506000836040015190506000846060015151905060008167ffffffffffffffff811115610a8757610a866139fe565b5b604051908082528060200260200182016040528015610ab55781602001602082028036833780820191505090505b50905060008267ffffffffffffffff811115610ad457610ad36139fe565b5b604051908082528060200260200182016040528015610b025781602001602082028036833780820191505090505b50905060008367ffffffffffffffff811115610b2157610b206139fe565b5b604051908082528060200260200182016040528015610b4f5781602001602082028036833780820191505090505b50905060008467ffffffffffffffff811115610b6e57610b6d6139fe565b5b604051908082528060200260200182016040528015610b9c5781602001602082028036833780820191505090505b50905060005b858160ff161015610d145789606001518160ff1681518110610bc757610bc66149e7565b5b602002602001015160000151858260ff1681518110610be957610be86149e7565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505089606001518160ff1681518110610c3d57610c3c6149e7565b5b602002602001015160200151848260ff1681518110610c5f57610c5e6149e7565b5b60200260200101818152505089606001518160ff1681518110610c8557610c846149e7565b5b602002602001015160400151838260ff1681518110610ca757610ca66149e7565b5b60200260200101818152505089606001518160ff1681518110610ccd57610ccc6149e7565b5b602002602001015160600151828260ff1681518110610cef57610cee6149e7565b5b6020026020010190151590811515815250508080610d0c90614b06565b915050610ba2565b50878787868686869f509f509f509f509f509f509f50505050505050505050919395979092949650565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610d706120cd565b8051825114610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab906149c7565b60405180910390fd5b60005b8251811015610e1157610dfe838281518110610dd657610dd56149e7565b5b6020026020010151838381518110610df157610df06149e7565b5b6020026020010151612252565b8080610e0990614a45565b915050610db7565b505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b6000610e4a6121cb565b60008b5111610e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8590614b7b565b60405180910390fd5b600080610ea76001600d5461235f90919063ffffffff16565b9150915080600d8190555081610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990614be7565b60405180910390fd5b610f01818e8e8e8e8e8e61238e565b610f0d818888886124c0565b610f17818561269b565b807f544b036352dc392f037f10719c187304b9313f6d7b98808ff40ecfce8ef0f9e9600e6000848152602001908152602001600020604051610f599190614e54565b60405180910390a280925050509a9950505050505050505050565b610f7c6120cd565b60005b8151811015610fbe57610fab828281518110610f9e57610f9d6149e7565b5b6020026020010151612999565b8080610fb690614a45565b915050610f7f565b5050565b606060028054610fd190614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ffd90614ea5565b801561104a5780601f1061101f5761010080835404028352916020019161104a565b820191906000526020600020905b81548152906001019060200180831161102d57829003601f168201915b5050505050905090565b61105c6120cd565b80518251146110a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611097906149c7565b60405180910390fd5b60005b82518110156110fd576110ea8382815181106110c2576110c16149e7565b5b60200260200101518383815181106110dd576110dc6149e7565b5b6020026020010151612a2d565b80806110f590614a45565b9150506110a3565b505050565b6000600d54905090565b6111146120cd565b8051825114611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f906149c7565b60405180910390fd5b60005b82518110156111b5576111a283828151811061117a576111796149e7565b5b6020026020010151838381518110611195576111946149e7565b5b6020026020010151612aa4565b80806111ad90614a45565b91505061115b565b505050565b6111c26120cd565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415801561124d5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61128c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390614f22565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6112d86121cb565b6112e26000612bb1565b565b6112ec6120cd565b8051825114611330576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611327906149c7565b60405180910390fd5b60005b825181101561138d5761137a838281518110611352576113516149e7565b5b602002602001015183838151811061136d5761136c6149e7565b5b6020026020010151612be2565b808061138590614a45565b915050611333565b505050565b600061139c612cad565b90508073ffffffffffffffffffffffffffffffffffffffff166113bd611f57565b73ffffffffffffffffffffffffffffffffffffffff161461141557806040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161140c9190614868565b60405180910390fd5b61141e81612bb1565b50565b60008111611464576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145b90614f8e565b60405180910390fd5b61146d82610d3e565b6114ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a390614ffa565b60405180910390fd5b6114b582612cb5565b6000600e60008481526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561161b57838290600052602060002090600402016040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff16151515158152505081526020019060010190611564565b5050505081525050905060008061163f848460400151612fa590919063ffffffff16565b9150915081611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167a90615066565b60405180910390fd5b6000836000015190508073ffffffffffffffffffffffffffffffffffffffff1663cbc7067c338660200151856040518463ffffffff1660e01b81526004016116cd93929190615086565b600060405180830381600087803b1580156116e757600080fd5b505af11580156116fb573d6000803e3d6000fd5b5050505060005b8460600151518160ff16101561192e5760008061174d8888606001518560ff1681518110611733576117326149e7565b5b602002602001015160400151612fa590919063ffffffff16565b9150915081611791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178890615066565b60405180910390fd5b86606001518360ff16815181106117ab576117aa6149e7565b5b6020026020010151606001511561188057600087606001518460ff16815181106117d8576117d76149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff166325f5e8ee338a606001518760ff168151811061181d5761181c6149e7565b5b602002602001015160200151856040518463ffffffff1660e01b815260040161184893929190615086565b600060405180830381600087803b15801561186257600080fd5b505af1158015611876573d6000803e3d6000fd5b5050505050611919565b600087606001518460ff168151811061189c5761189b6149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663f0a8587b33846040518363ffffffff1660e01b81526004016118e59291906150bd565b600060405180830381600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b50505050505b5050808061192690614b06565b915050611702565b506119398686612ff8565b505050505050565b60606003805461195090614ea5565b80601f016020809104026020016040519081016040528092919081815260200182805461197c90614ea5565b80156119c95780601f1061199e576101008083540402835291602001916119c9565b820191906000526020600020905b8154815290600101906020018083116119ac57829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a046120cd565b8051825114611a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3f906149c7565b60405180910390fd5b60005b8251811015611aa557611a92838281518110611a6a57611a696149e7565b5b6020026020010151838381518110611a8557611a846149e7565b5b60200260200101516133fe565b8080611a9d90614a45565b915050611a4b565b505050565b600080600460008481526020019081526020016000208054611acb90614ea5565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611b336120cd565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480611bb35750611bb27f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b611bf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be990615132565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611c3e6121cb565b611c4785611aaa565b611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061519e565b60405180910390fd5b600e60008681526020019081526020016000206003016000611ca891906138f1565b611cb4858585856124c0565b611cbe858261269b565b847ff9dc306cb995b9c7f719d16639775625d9c649f81fd40a0f998ec775c09e62d6600e6000888152602001908152602001600020604051611d009190614e54565b60405180910390a25050505050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff16611d7b8a611eb8565b848054611d8790614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054611db390614ea5565b8015611e005780601f10611dd557610100808354040283529160200191611e00565b820191906000526020600020905b815481529060010190602001808311611de357829003601f168201915b50505050509450838054611e1390614ea5565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3f90614ea5565b8015611e8c5780601f10611e6157610100808354040283529160200191611e8c565b820191906000526020600020905b815481529060010190602001808311611e6f57829003601f168201915b505050505093509450945094509450945091939590929450565b6000611eb182611aaa565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f4d57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611f4f565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361201657600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612018565b805b915050919050565b6120286121cb565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166120886119d3565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60006120d7612cad565b90508073ffffffffffffffffffffffffffffffffffffffff166120f86119d3565b73ffffffffffffffffffffffffffffffffffffffff1614158015612122575061212081613490565b155b1561216457806040517f8a08cbf500000000000000000000000000000000000000000000000000000000815260040161215b9190614868565b60405180910390fd5b50565b61217082611aaa565b6121af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a69061520a565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b6121d3612cad565b73ffffffffffffffffffffffffffffffffffffffff166121f16119d3565b73ffffffffffffffffffffffffffffffffffffffff161461225057612214612cad565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122479190614868565b60405180910390fd5b565b61225b82611aaa565b61229a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122919061520a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230090615276565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080600083850190508481101561237e576000809250925050612387565b60018192509250505b9250929050565b856004600089815260200190815260200160002090816123ae9190615442565b50846005600089815260200190815260200160002090816123cf9190615442565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b60008111612503576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124fa90615560565b60405180910390fd5b61250c836134e6565b61254b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612542906155cc565b60405180910390fd5b60008390508073ffffffffffffffffffffffffffffffffffffffff1663b419c807846040518263ffffffff1660e01b81526004016125899190614462565b602060405180830381865afa1580156125a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ca9190615601565b612609576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126009061567a565b60405180910390fd5b83600e600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600e60008781526020019081526020016000206001018190555081600e6000878152602001908152602001600020600201819055505050505050565b60005b81518110156129945760008282815181106126bc576126bb6149e7565b5b60200260200101516040015111612708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ff906156e6565b60405180910390fd5b60006127318383815181106127205761271f6149e7565b5b6020026020010151600001516134e6565b9050600061275c84848151811061274b5761274a6149e7565b5b602002602001015160000151613570565b905081806127675750805b6127a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279d90615752565b60405180910390fd5b81156128a85760008484815181106127c1576127c06149e7565b5b60200260200101516000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c8078686815181106127fe576127fd6149e7565b5b6020026020010151602001516040518263ffffffff1660e01b81526004016128269190614462565b602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128679190615601565b6128a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289d9061567a565b60405180910390fd5b505b600e60008681526020019081526020016000206003018484815181106128d1576128d06149e7565b5b6020026020010151908060018154018082558091505060019003906000526020600020906004020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555050505050808061298c90614a45565b91505061269e565b505050565b6129a281611aaa565b6129e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d89061520a565b60405180910390fd5b6129ea816135fa565b6129f3816136e1565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b781604051612a229190614462565b60405180910390a150565b612a3682611aaa565b612a75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6c9061520a565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b612aad82611aaa565b612aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae39061520a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b5290615276565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055612bdf81613741565b50565b6000600460008481526020019081526020016000208054612c0290614ea5565b905011612c44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3b9061520a565b60405180910390fd5b6000815111612c88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7f906157be565b60405180910390fd5b80600460008481526020019081526020016000209081612ca89190615442565b505050565b600033905090565b6000600e600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e6000858152602001908152602001600020600101546040518263ffffffff1660e01b8152600401612d3f9190614462565b602060405180830381865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d809190615601565b612dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612db69061567a565b60405180910390fd5b6000600e600084815260200190815260200160002060030180549050905060005b81811015612f9f576000600e60008681526020019081526020016000206003018281548110612e1257612e116149e7565b5b906000526020600020906004020160030160009054906101000a900460ff1690508015612f8b576000600e60008781526020019081526020016000206003018381548110612e6357612e626149e7565b5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663b419c807600e60008981526020019081526020016000206003018581548110612edb57612eda6149e7565b5b9060005260206000209060040201600101546040518263ffffffff1660e01b8152600401612f099190614462565b602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a9190615601565b612f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f809061567a565b60405180910390fd5b505b508080612f9790614a45565b915050612de0565b50505050565b60008060008403612fbd576001600091509150612ff1565b6000838502905083858281612fd557612fd46157de565b5b0414612fe8576000809250925050612ff1565b60018192509250505b9250929050565b6000811161303b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303290615859565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361306157506133fa565b600061306c84611eb8565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036130dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130d4906158c5565b60405180910390fd5b6000806130f38585612fa590919063ffffffff16565b9150915081613137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312e90615931565b60405180910390fd5b600061314287611f81565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133115760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016131b39190614868565b602060405180830381865afa1580156131d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f49190615966565b905082811015613239576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613230906159df565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b8152600401613276939291906159ff565b6020604051808303816000875af1158015613295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b99190615601565b50600034111561330b573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015613309573d6000803e3d6000fd5b505b506133f4565b81341015613354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161334b906159df565b60405180910390fd5b600082346133629190615a36565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156133aa573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156133f1573d6000803e3d6000fd5b50505b50505050505b5050565b61340782611aaa565b613446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161343d9061520a565b60405180910390fd5b806005600084815260200190815260200160002090816134669190615442565b505050565b600061347683613805565b801561348857506134878383613852565b5b905092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561356957506135687ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156135f357506135f27f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff1661346b90919063ffffffff16565b5b9050919050565b6004600082815260200190815260200160002060006136199190613915565b6005600082815260200190815260200160002060006136389190613915565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600e6000828152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905560038201600061373c91906138f1565b505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613831827f01ffc9a700000000000000000000000000000000000000000000000000000000613852565b801561384b57506138498263ffffffff60e01b613852565b155b9050919050565b600080826040516024016138669190615aa5565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d915060005190508280156138d9575060208210155b80156138e55750600081115b94505050505092915050565b50805460008255600402906000526020600020908101906139129190613955565b50565b50805461392190614ea5565b6000825580601f106139335750613952565b601f01602090049060005260206000209081019061395191906139b7565b5b50565b5b808211156139b357600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201600090556003820160006101000a81549060ff021916905550600401613956565b5090565b5b808211156139d05760008160009055506001016139b8565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a36826139ed565b810181811067ffffffffffffffff82111715613a5557613a546139fe565b5b80604052505050565b6000613a686139d4565b9050613a748282613a2d565b919050565b600067ffffffffffffffff821115613a9457613a936139fe565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b613abd81613aaa565b8114613ac857600080fd5b50565b600081359050613ada81613ab4565b92915050565b6000613af3613aee84613a79565b613a5e565b90508083825260208201905060208402830185811115613b1657613b15613aa5565b5b835b81811015613b3f5780613b2b8882613acb565b845260208401935050602081019050613b18565b5050509392505050565b600082601f830112613b5e57613b5d6139e8565b5b8135613b6e848260208601613ae0565b91505092915050565b60008060408385031215613b8e57613b8d6139de565b5b600083013567ffffffffffffffff811115613bac57613bab6139e3565b5b613bb885828601613b49565b925050602083013567ffffffffffffffff811115613bd957613bd86139e3565b5b613be585828601613b49565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c1a82613bef565b9050919050565b613c2a81613c0f565b8114613c3557600080fd5b50565b600081359050613c4781613c21565b92915050565b60008115159050919050565b613c6281613c4d565b8114613c6d57600080fd5b50565b600081359050613c7f81613c59565b92915050565b60008060408385031215613c9c57613c9b6139de565b5b6000613caa85828601613c38565b9250506020613cbb85828601613c70565b9150509250929050565b600060208284031215613cdb57613cda6139de565b5b6000613ce984828501613acb565b91505092915050565b613cfb81613c0f565b82525050565b613d0a81613aaa565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613d4581613c0f565b82525050565b6000613d578383613d3c565b60208301905092915050565b6000602082019050919050565b6000613d7b82613d10565b613d858185613d1b565b9350613d9083613d2c565b8060005b83811015613dc1578151613da88882613d4b565b9750613db383613d63565b925050600181019050613d94565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613e0381613aaa565b82525050565b6000613e158383613dfa565b60208301905092915050565b6000602082019050919050565b6000613e3982613dce565b613e438185613dd9565b9350613e4e83613dea565b8060005b83811015613e7f578151613e668882613e09565b9750613e7183613e21565b925050600181019050613e52565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613ec181613c4d565b82525050565b6000613ed38383613eb8565b60208301905092915050565b6000602082019050919050565b6000613ef782613e8c565b613f018185613e97565b9350613f0c83613ea8565b8060005b83811015613f3d578151613f248882613ec7565b9750613f2f83613edf565b925050600181019050613f10565b5085935050505092915050565b600060e082019050613f5f600083018a613cf2565b613f6c6020830189613d01565b613f796040830188613d01565b8181036060830152613f8b8187613d70565b90508181036080830152613f9f8186613e2e565b905081810360a0830152613fb38185613e2e565b905081810360c0830152613fc78184613eec565b905098975050505050505050565b613fde81613c4d565b82525050565b6000602082019050613ff96000830184613fd5565b92915050565b600067ffffffffffffffff82111561401a576140196139fe565b5b602082029050602081019050919050565b600061403e61403984613fff565b613a5e565b9050808382526020820190506020840283018581111561406157614060613aa5565b5b835b8181101561408a57806140768882613c38565b845260208401935050602081019050614063565b5050509392505050565b600082601f8301126140a9576140a86139e8565b5b81356140b984826020860161402b565b91505092915050565b600080604083850312156140d9576140d86139de565b5b600083013567ffffffffffffffff8111156140f7576140f66139e3565b5b61410385828601613b49565b925050602083013567ffffffffffffffff811115614124576141236139e3565b5b61413085828601614094565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561415a576141596139fe565b5b614163826139ed565b9050602081019050919050565b82818337600083830152505050565b600061419261418d8461413f565b613a5e565b9050828152602081018484840111156141ae576141ad61413a565b5b6141b9848285614170565b509392505050565b600082601f8301126141d6576141d56139e8565b5b81356141e684826020860161417f565b91505092915050565b600067ffffffffffffffff82111561420a576142096139fe565b5b602082029050602081019050919050565b600080fd5b6000608082840312156142365761423561421b565b5b6142406080613a5e565b9050600061425084828501613c38565b600083015250602061426484828501613acb565b602083015250604061427884828501613acb565b604083015250606061428c84828501613c70565b60608301525092915050565b60006142ab6142a6846141ef565b613a5e565b905080838252602082019050608084028301858111156142ce576142cd613aa5565b5b835b818110156142f757806142e38882614220565b8452602084019350506080810190506142d0565b5050509392505050565b600082601f830112614316576143156139e8565b5b8135614326848260208601614298565b91505092915050565b6000806000806000806000806000806101408b8d031215614353576143526139de565b5b60008b013567ffffffffffffffff811115614371576143706139e3565b5b61437d8d828e016141c1565b9a505060208b013567ffffffffffffffff81111561439e5761439d6139e3565b5b6143aa8d828e016141c1565b99505060406143bb8d828e01613acb565b98505060606143cc8d828e01613c70565b97505060806143dd8d828e01613c38565b96505060a06143ee8d828e01613c38565b95505060c06143ff8d828e01613c38565b94505060e06144108d828e01613acb565b9350506101006144228d828e01613acb565b9250506101208b013567ffffffffffffffff811115614444576144436139e3565b5b6144508d828e01614301565b9150509295989b9194979a5092959850565b60006020820190506144776000830184613d01565b92915050565b600060208284031215614493576144926139de565b5b600082013567ffffffffffffffff8111156144b1576144b06139e3565b5b6144bd84828501613b49565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156145005780820151818401526020810190506144e5565b60008484015250505050565b6000614517826144c6565b61452181856144d1565b93506145318185602086016144e2565b61453a816139ed565b840191505092915050565b6000602082019050818103600083015261455f818461450c565b905092915050565b600067ffffffffffffffff821115614582576145816139fe565b5b602082029050602081019050919050565b60006145a66145a184614567565b613a5e565b905080838252602082019050602084028301858111156145c9576145c8613aa5565b5b835b818110156145f257806145de8882613c70565b8452602084019350506020810190506145cb565b5050509392505050565b600082601f830112614611576146106139e8565b5b8135614621848260208601614593565b91505092915050565b60008060408385031215614641576146406139de565b5b600083013567ffffffffffffffff81111561465f5761465e6139e3565b5b61466b85828601613b49565b925050602083013567ffffffffffffffff81111561468c5761468b6139e3565b5b614698858286016145fc565b9150509250929050565b6000602082840312156146b8576146b76139de565b5b60006146c684828501613c38565b91505092915050565b600067ffffffffffffffff8211156146ea576146e96139fe565b5b602082029050602081019050919050565b600061470e614709846146cf565b613a5e565b9050808382526020820190506020840283018581111561473157614730613aa5565b5b835b8181101561477857803567ffffffffffffffff811115614756576147556139e8565b5b80860161476389826141c1565b85526020850194505050602081019050614733565b5050509392505050565b600082601f830112614797576147966139e8565b5b81356147a78482602086016146fb565b91505092915050565b600080604083850312156147c7576147c66139de565b5b600083013567ffffffffffffffff8111156147e5576147e46139e3565b5b6147f185828601613b49565b925050602083013567ffffffffffffffff811115614812576148116139e3565b5b61481e85828601614782565b9150509250929050565b6000806040838503121561483f5761483e6139de565b5b600061484d85828601613acb565b925050602061485e85828601613acb565b9150509250929050565b600060208201905061487d6000830184613cf2565b92915050565b600080600080600060a0868803121561489f5761489e6139de565b5b60006148ad88828901613acb565b95505060206148be88828901613c38565b94505060406148cf88828901613acb565b93505060606148e088828901613acb565b925050608086013567ffffffffffffffff811115614901576149006139e3565b5b61490d88828901614301565b9150509295509295909350565b600060a0820190508181036000830152614934818861450c565b90508181036020830152614948818761450c565b90506149576040830186613d01565b6149646060830185613fd5565b6149716080830184613cf2565b9695505050505050565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b60006149b16012836144d1565b91506149bc8261497b565b602082019050919050565b600060208201905081810360008301526149e0816149a4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a5082613aaa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a8257614a81614a16565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b6000614ac36014836144d1565b9150614ace82614a8d565b602082019050919050565b60006020820190508181036000830152614af281614ab6565b9050919050565b600060ff82169050919050565b6000614b1182614af9565b915060ff8203614b2457614b23614a16565b5b600182019050919050565b7f4e4f5f4e414d4500000000000000000000000000000000000000000000000000600082015250565b6000614b656007836144d1565b9150614b7082614b2f565b602082019050919050565b60006020820190508181036000830152614b9481614b58565b9050919050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614bd1600f836144d1565b9150614bdc82614b9b565b602082019050919050565b60006020820190508181036000830152614c0081614bc4565b9050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614c47614c4283614c07565b614c14565b9050919050565b6000819050919050565b6000614c6b614c6683614c07565b614c4e565b9050919050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b600060ff82169050919050565b6000614cc3614cbe83614c07565b614ca3565b9050919050565b608082016000808301549050614cdf81614c34565b614cec6000860182613d3c565b5060018301549050614cfd81614c58565b614d0a6020860182613dfa565b5060028301549050614d1b81614c58565b614d286040860182613dfa565b5060038301549050614d3981614cb0565b614d466060860182613eb8565b5050505050565b6000614d598383614cca565b60808301905092915050565b6000600482019050919050565b6000614d7d82614c72565b614d878185614c7d565b9350614d9283614c8e565b8060005b83811015614dc25781614da98882614d4d565b9750614db483614d65565b925050600181019050614d96565b5085935050505092915050565b6000608083016000808401549050614de681614c34565b614df36000870182613d3c565b5060018401549050614e0481614c58565b614e116020870182613dfa565b5060028401549050614e2281614c58565b614e2f6040870182613dfa565b50600384018583036060870152614e468382614d72565b925050819250505092915050565b60006020820190508181036000830152614e6e8184614dcf565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614ebd57607f821691505b602082108103614ed057614ecf614e76565b5b50919050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b6000614f0c6010836144d1565b9150614f1782614ed6565b602082019050919050565b60006020820190508181036000830152614f3b81614eff565b9050919050565b7f5a45524f5f4150504c595f434f554e5400000000000000000000000000000000600082015250565b6000614f786010836144d1565b9150614f8382614f42565b602082019050919050565b60006020820190508181036000830152614fa781614f6b565b9050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b6000614fe46011836144d1565b9150614fef82614fae565b602082019050919050565b6000602082019050818103600083015261501381614fd7565b9050919050565b7f544f54414c5f4f564552464c4f57000000000000000000000000000000000000600082015250565b6000615050600e836144d1565b915061505b8261501a565b602082019050919050565b6000602082019050818103600083015261507f81615043565b9050919050565b600060608201905061509b6000830186613cf2565b6150a86020830185613d01565b6150b56040830184613d01565b949350505050565b60006040820190506150d26000830185613cf2565b6150df6020830184613d01565b9392505050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b600061511c6012836144d1565b9150615127826150e6565b602082019050919050565b6000602082019050818103600083015261514b8161510f565b9050919050565b7f4e4f545f444546494e4544000000000000000000000000000000000000000000600082015250565b6000615188600b836144d1565b915061519382615152565b602082019050919050565b600060208201905081810360008301526151b78161517b565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b60006151f4600e836144d1565b91506151ff826151be565b602082019050919050565b60006020820190508181036000830152615223816151e7565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b6000615260600c836144d1565b915061526b8261522a565b602082019050919050565b6000602082019050818103600083015261528f81615253565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026152f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826152bb565b61530286836152bb565b95508019841693508086168417925050509392505050565b6000819050919050565b600061533f61533a61533584613aaa565b61531a565b613aaa565b9050919050565b6000819050919050565b61535983615324565b61536d61536582615346565b8484546152c8565b825550505050565b600090565b615382615375565b61538d818484615350565b505050565b5b818110156153b1576153a660008261537a565b600181019050615393565b5050565b601f8211156153f6576153c781615296565b6153d0846152ab565b810160208510156153df578190505b6153f36153eb856152ab565b830182615392565b50505b505050565b600082821c905092915050565b6000615419600019846008026153fb565b1980831691505092915050565b60006154328383615408565b9150826002028217905092915050565b61544b826144c6565b67ffffffffffffffff811115615464576154636139fe565b5b61546e8254614ea5565b6154798282856153b5565b600060209050601f8311600181146154ac576000841561549a578287015190505b6154a48582615426565b86555061550c565b601f1984166154ba86615296565b60005b828110156154e2578489015182556001820191506020850194506020810190506154bd565b868310156154ff57848901516154fb601f891682615408565b8355505b6001600288020188555050505b505050505050565b7f495f5a524f5f414d540000000000000000000000000000000000000000000000600082015250565b600061554a6009836144d1565b915061555582615514565b602082019050919050565b600060208201905081810360008301526155798161553d565b9050919050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b60006155b6600b836144d1565b91506155c182615580565b602082019050919050565b600060208201905081810360008301526155e5816155a9565b9050919050565b6000815190506155fb81613c59565b92915050565b600060208284031215615617576156166139de565b5b6000615625848285016155ec565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615664600b836144d1565b915061566f8261562e565b602082019050919050565b6000602082019050818103600083015261569381615657565b9050919050565b7f4f5f5a524f5f414d540000000000000000000000000000000000000000000000600082015250565b60006156d06009836144d1565b91506156db8261569a565b602082019050919050565b600060208201905081810360008301526156ff816156c3565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b600061573c600b836144d1565b915061574782615706565b602082019050919050565b6000602082019050818103600083015261576b8161572f565b9050919050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b60006157a8600b836144d1565b91506157b382615772565b602082019050919050565b600060208201905081810360008301526157d78161579b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615843600f836144d1565b915061584e8261580d565b602082019050919050565b6000602082019050818103600083015261587281615836565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b60006158af6010836144d1565b91506158ba82615879565b602082019050919050565b600060208201905081810360008301526158de816158a2565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b600061591b6010836144d1565b9150615926826158e5565b602082019050919050565b6000602082019050818103600083015261594a8161590e565b9050919050565b60008151905061596081613ab4565b92915050565b60006020828403121561597c5761597b6139de565b5b600061598a84828501615951565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b60006159c96014836144d1565b91506159d482615993565b602082019050919050565b600060208201905081810360008301526159f8816159bc565b9050919050565b6000606082019050615a146000830186613cf2565b615a216020830185613cf2565b615a2e6040830184613d01565b949350505050565b6000615a4182613aaa565b9150615a4c83613aaa565b9250828203905081811115615a6457615a63614a16565b5b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615a9f81615a6a565b82525050565b6000602082019050615aba6000830184615a96565b9291505056fea2646970667358221220001d66719f5024a678d58593f80ff63aa7ce6e3af38285fb85dedbe9f079019164736f6c63430008140033