Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
__Governable_ini... | 16280323 | 741 days ago | IN | 0 ETH | 0.00115915 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Factory
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-05-04 */ // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ abstract contract Proxy { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ fallback () payable external { _fallback(); } receive () payable external { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() virtual internal view returns (address); /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() virtual internal { } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { if(OpenZeppelinUpgradesAddress.isContract(msg.sender) && msg.data.length == 0 && gasleft() <= 2300) // for receive ETH only from other contract return; _willFallback(); _delegate(_implementation()); } } /** * @title BaseUpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ abstract contract BaseUpgradeabilityProxy is Proxy { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation. * @return impl Address of the current implementation */ function _implementation() override internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) internal { require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } } /** * @title BaseAdminUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with an authorization * mechanism for administrative tasks. * All external functions in this contract must be guarded by the * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity * feature proposal that would enable this to be done automatically. */ contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Emitted when the administration has been transferred. * @param previousAdmin Address of the previous admin. * @param newAdmin Address of the new admin. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Modifier to check whether the `msg.sender` is the admin. * If it is, it will run the function. Otherwise, it will delegate the call * to the implementation. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * @return The address of the proxy admin. */ function admin() external ifAdmin returns (address) { return _admin(); } /** * @return The address of the implementation. */ function implementation() external ifAdmin returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * Only the current admin can call this function. * @param newAdmin Address to transfer proxy administration to. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); } /** * @dev Upgrade the backing implementation of the proxy and call a function * on the new implementation. * This is useful to initialize the proxied contract. * @param newImplementation Address of the new implementation. * @param data Data to send as msg.data in the low level call. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. */ function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin { _upgradeTo(newImplementation); (bool success,) = newImplementation.delegatecall(data); require(success); } /** * @return adm The admin slot. */ function _admin() internal view returns (address adm) { bytes32 slot = ADMIN_SLOT; assembly { adm := sload(slot) } } /** * @dev Sets the address of the proxy admin. * @param newAdmin Address of the new proxy admin. */ function _setAdmin(address newAdmin) internal { bytes32 slot = ADMIN_SLOT; assembly { sstore(slot, newAdmin) } } /** * @dev Only fall back when the sender is not the admin. */ function _willFallback() virtual override internal { require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); //super._willFallback(); } } interface IAdminUpgradeabilityProxyView { function admin() external view returns (address); function implementation() external view returns (address); } /** * @title UpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing * implementation and init data. */ abstract contract UpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Contract constructor. * @param _logic Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _logic, bytes memory _data) public payable { assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); _setImplementation(_logic); if(_data.length > 0) { (bool success,) = _logic.delegatecall(_data); require(success); } } //function _willFallback() virtual override internal { //super._willFallback(); //} } /** * @title AdminUpgradeabilityProxy * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for * initializing the implementation, admin, and init data. */ contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy { /** * Contract constructor. * @param _logic address of the initial implementation. * @param _admin Address of the proxy administrator. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _admin, address _logic, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable { assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); _setAdmin(_admin); } function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal { super._willFallback(); } } /** * @title InitializableUpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing * implementation and init data. */ abstract contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Contract initializer. * @param _logic Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function initialize(address _logic, bytes memory _data) public payable { require(_implementation() == address(0)); assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); _setImplementation(_logic); if(_data.length > 0) { (bool success,) = _logic.delegatecall(_data); require(success); } } } /** * @title InitializableAdminUpgradeabilityProxy * @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for * initializing the implementation, admin, and init data. */ contract InitializableAdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, InitializableUpgradeabilityProxy { /** * Contract initializer. * @param _logic address of the initial implementation. * @param _admin Address of the proxy administrator. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function initialize(address _admin, address _logic, bytes memory _data) public payable { require(_implementation() == address(0)); InitializableUpgradeabilityProxy.initialize(_logic, _data); assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); _setAdmin(_admin); } function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal { super._willFallback(); } } interface IProxyFactory { function productImplementation() external view returns (address); function productImplementations(bytes32 name) external view returns (address); } /** * @title ProductProxy * @dev This contract implements a proxy that * it is deploied by ProxyFactory, * and it's implementation is stored in factory. */ contract ProductProxy is Proxy { /** * @dev Storage slot with the address of the ProxyFactory. * This is the keccak-256 hash of "eip1967.proxy.factory" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant FACTORY_SLOT = 0x7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af1; bytes32 internal constant NAME_SLOT = 0x4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a870; // bytes32(uint256(keccak256('eip1967.proxy.name')) - 1) function _name() virtual internal view returns (bytes32 name_) { bytes32 slot = NAME_SLOT; assembly { name_ := sload(slot) } } function _setName(bytes32 name_) internal { bytes32 slot = NAME_SLOT; assembly { sstore(slot, name_) } } /** * @dev Sets the factory address of the ProductProxy. * @param newFactory Address of the new factory. */ function _setFactory(address newFactory) internal { require(OpenZeppelinUpgradesAddress.isContract(newFactory), "Cannot set a factory to a non-contract address"); bytes32 slot = FACTORY_SLOT; assembly { sstore(slot, newFactory) } } /** * @dev Returns the factory. * @return factory_ Address of the factory. */ function _factory() internal view returns (address factory_) { bytes32 slot = FACTORY_SLOT; assembly { factory_ := sload(slot) } } /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() virtual override internal view returns (address) { address factory_ = _factory(); if(OpenZeppelinUpgradesAddress.isContract(factory_)) return IProxyFactory(factory_).productImplementations(_name()); else return address(0); } } /** * @title InitializableProductProxy * @dev Extends ProductProxy with an initializer for initializing * factory and init data. */ contract InitializableProductProxy is ProductProxy { /** * @dev Contract initializer. * @param factory_ Address of the initial factory. * @param data_ Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function __InitializableProductProxy_init(address factory_, bytes32 name_, bytes memory data_) public payable { require(_factory() == address(0)); assert(FACTORY_SLOT == bytes32(uint256(keccak256('eip1967.proxy.factory')) - 1)); assert(NAME_SLOT == bytes32(uint256(keccak256('eip1967.proxy.name')) - 1)); _setFactory(factory_); _setName(name_); if(data_.length > 0) { (bool success,) = _implementation().delegatecall(data_); require(success); } } } /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } /* * @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 GSN 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. */ contract ContextUpgradeSafe is Initializable { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuardUpgradeSafe is Initializable { bool private _notEntered; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { // Storing an initial non-zero value makes deployment a bit more // expensive, but in exchange the refund on every call to nonReentrant // will be lower in amount. Since refunds are capped to a percetange of // the total transaction's gas, it is best to keep them low in cases // like this one, to increase the likelihood of the full refund coming // into effect. _notEntered = true; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_notEntered, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _notEntered = false; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _notEntered = true; } uint256[49] private __gap; } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @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, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function sub0(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a - b : 0; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * Utility library of inline functions on addresses * * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/utils/Address.sol * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version. */ library OpenZeppelinUpgradesAddress { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @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 Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20MinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20UpgradeSafe is Initializable, ContextUpgradeSafe, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name, string memory symbol) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name, symbol); } function __ERC20_init_unchained(string memory name, string memory symbol) internal initializer { _name = name; _symbol = symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); if(sender != _msgSender() && _allowances[sender][_msgSender()] != uint(-1)) _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[44] private __gap; } /** * @dev Extension of {ERC20} that adds a cap to the supply of tokens. */ abstract contract ERC20CappedUpgradeSafe is Initializable, ERC20UpgradeSafe { uint256 private _cap; /** * @dev Sets the value of the `cap`. This value is immutable, it can only be * set once during construction. */ function __ERC20Capped_init(uint256 cap) internal initializer { __Context_init_unchained(); __ERC20Capped_init_unchained(cap); } function __ERC20Capped_init_unchained(uint256 cap) internal initializer { require(cap > 0, "ERC20Capped: cap is 0"); _cap = cap; } /** * @dev Returns the cap on the token's total supply. */ function cap() virtual public view returns (uint256) { return _cap; } /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - minted tokens must not cause the total supply to go over the cap. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // When minting tokens require(totalSupply().add(amount) <= _cap, "ERC20Capped: cap exceeded"); } } uint256[49] private __gap; } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // https://github.com/hamdiallam/Solidity-RLP/blob/master/contracts/RLPReader.sol /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.0 <0.7.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint ptr = self.nextPtr; uint itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) { uint offset = _payloadOffset(item.memPtr); uint memPtr = item.memPtr + offset; uint len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint) { (, uint len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint memPtr, uint len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint result; uint memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(toUint(item)); } function toUint(RLPItem memory item) internal pure returns (uint) { require(item.len > 0 && item.len <= 33); (uint memPtr, uint len) = payloadLocation(item); uint result; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint memPtr, uint len) = payloadLocation(item); bytes memory result = new bytes(len); uint destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint memPtr) private pure returns (uint) { uint itemLen; uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint memPtr) private pure returns (uint) { uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } // https://github.com/bakaoh/solidity-rlp-encode/blob/master/contracts/RLPEncode.sol /** * @title RLPEncode * @dev A simple RLP encoding library. * @author Bakaoh */ library RLPEncode { /* * Internal functions */ /** * @dev RLP encodes a byte string. * @param self The byte string to encode. * @return The RLP encoded string in bytes. */ function encodeBytes(bytes memory self) internal pure returns (bytes memory) { bytes memory encoded; if (self.length == 1 && uint8(self[0]) <= 128) { encoded = self; } else { encoded = concat(encodeLength(self.length, 128), self); } return encoded; } /** * @dev RLP encodes a list of RLP encoded byte byte strings. * @param self The list of RLP encoded byte strings. * @return The RLP encoded list of items in bytes. */ function encodeList(bytes[] memory self) internal pure returns (bytes memory) { bytes memory list = flatten(self); return concat(encodeLength(list.length, 192), list); } /** * @dev RLP encodes a string. * @param self The string to encode. * @return The RLP encoded string in bytes. */ function encodeString(string memory self) internal pure returns (bytes memory) { return encodeBytes(bytes(self)); } /** * @dev RLP encodes an address. * @param self The address to encode. * @return The RLP encoded address in bytes. */ function encodeAddress(address self) internal pure returns (bytes memory) { bytes memory inputBytes; assembly { let m := mload(0x40) mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, self)) mstore(0x40, add(m, 52)) inputBytes := m } return encodeBytes(inputBytes); } /** * @dev RLP encodes a uint. * @param self The uint to encode. * @return The RLP encoded uint in bytes. */ function encodeUint(uint self) internal pure returns (bytes memory) { return encodeBytes(toBinary(self)); } /** * @dev RLP encodes an int. * @param self The int to encode. * @return The RLP encoded int in bytes. */ function encodeInt(int self) internal pure returns (bytes memory) { return encodeUint(uint(self)); } /** * @dev RLP encodes a bool. * @param self The bool to encode. * @return The RLP encoded bool in bytes. */ function encodeBool(bool self) internal pure returns (bytes memory) { bytes memory encoded = new bytes(1); encoded[0] = (self ? bytes1(0x01) : bytes1(0x80)); return encoded; } /* * Private functions */ /** * @dev Encode the first byte, followed by the `len` in binary form if `length` is more than 55. * @param len The length of the string or the payload. * @param offset 128 if item is string, 192 if item is list. * @return RLP encoded bytes. */ function encodeLength(uint len, uint offset) private pure returns (bytes memory) { bytes memory encoded; if (len < 56) { encoded = new bytes(1); encoded[0] = bytes32(len + offset)[31]; } else { uint lenLen; uint i = 1; while (len / i != 0) { lenLen++; i *= 256; } encoded = new bytes(lenLen + 1); encoded[0] = bytes32(lenLen + offset + 55)[31]; for(i = 1; i <= lenLen; i++) { encoded[i] = bytes32((len / (256**(lenLen-i))) % 256)[31]; } } return encoded; } /** * @dev Encode integer in big endian binary form with no leading zeroes. * @notice TODO: This should be optimized with assembly to save gas costs. * @param _x The integer to encode. * @return RLP encoded bytes. */ function toBinary(uint _x) private pure returns (bytes memory) { bytes memory b = new bytes(32); assembly { mstore(add(b, 32), _x) } uint i; for (i = 0; i < 32; i++) { if (b[i] != 0) { break; } } bytes memory res = new bytes(32 - i); for (uint j = 0; j < res.length; j++) { res[j] = b[i++]; } return res; } /** * @dev Copies a piece of memory to another location. * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol. * @param _dest Destination location. * @param _src Source location. * @param _len Length of memory to copy. */ function memcpy(uint _dest, uint _src, uint _len) private pure { uint dest = _dest; uint src = _src; uint len = _len; for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /** * @dev Flattens a list of byte strings into one byte string. * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol. * @param _list List of byte strings to flatten. * @return The flattened byte string. */ function flatten(bytes[] memory _list) private pure returns (bytes memory) { if (_list.length == 0) { return new bytes(0); } uint len; uint i; for (i = 0; i < _list.length; i++) { len += _list[i].length; } bytes memory flattened = new bytes(len); uint flattenedPtr; assembly { flattenedPtr := add(flattened, 0x20) } for(i = 0; i < _list.length; i++) { bytes memory item = _list[i]; uint listPtr; assembly { listPtr := add(item, 0x20)} memcpy(flattenedPtr, listPtr, item.length); flattenedPtr += _list[i].length; } return flattened; } /** * @dev Concatenates two bytes. * @notice From: https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol. * @param _preBytes First byte string. * @param _postBytes Second byte string. * @return Both byte string combined. */ function concat(bytes memory _preBytes, bytes memory _postBytes) private pure returns (bytes memory) { bytes memory tempBytes; assembly { tempBytes := mload(0x40) let length := mload(_preBytes) mstore(tempBytes, length) let mc := add(tempBytes, 0x20) let end := add(mc, length) for { let cc := add(_preBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) mc := end end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) )) } return tempBytes; } } contract Governable is Initializable { address public governor; event GovernorshipTransferred(address indexed previousGovernor, address indexed newGovernor); /** * @dev Contract initializer. * called once by the factory at time of deployment */ function __Governable_init_unchained(address governor_) virtual public initializer { governor = governor_; emit GovernorshipTransferred(address(0), governor); } modifier governance() { require(msg.sender == governor); _; } /** * @dev Allows the current governor to relinquish control of the contract. * @notice Renouncing to governorship will leave the contract without an governor. * It will not be possible to call the functions with the `governance` * modifier anymore. */ function renounceGovernorship() public governance { emit GovernorshipTransferred(governor, address(0)); governor = address(0); } /** * @dev Allows the current governor to transfer control of the contract to a newGovernor. * @param newGovernor The address to transfer governorship to. */ function transferGovernorship(address newGovernor) public governance { _transferGovernorship(newGovernor); } /** * @dev Transfers control of the contract to a newGovernor. * @param newGovernor The address to transfer governorship to. */ function _transferGovernorship(address newGovernor) internal { require(newGovernor != address(0)); emit GovernorshipTransferred(governor, newGovernor); governor = newGovernor; } } contract ConfigurableBase { mapping (bytes32 => uint) internal config; function getConfig(bytes32 key) public view returns (uint) { return config[key]; } function getConfigI(bytes32 key, uint index) public view returns (uint) { return config[bytes32(uint(key) ^ index)]; } function getConfigA(bytes32 key, address addr) public view returns (uint) { return config[bytes32(uint(key) ^ uint(addr))]; } function _setConfig(bytes32 key, uint value) internal { if(config[key] != value) config[key] = value; } function _setConfig(bytes32 key, uint index, uint value) internal { _setConfig(bytes32(uint(key) ^ index), value); } function _setConfig(bytes32 key, address addr, uint value) internal { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } } contract Configurable is Governable, ConfigurableBase { function setConfig(bytes32 key, uint value) external governance { _setConfig(key, value); } function setConfigI(bytes32 key, uint index, uint value) external governance { _setConfig(bytes32(uint(key) ^ index), value); } function setConfigA(bytes32 key, address addr, uint value) public governance { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } } // Inheritancea interface IStakingRewards { // Views function lastTimeRewardApplicable() external view returns (uint256); function rewardPerToken() external view returns (uint256); function rewards(address account) external view returns (uint256); function earned(address account) external view returns (uint256); function getRewardForDuration() external view returns (uint256); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); // Mutative function stake(uint256 amount) external; function withdraw(uint256 amount) external; function getReward() external; function exit() external; } abstract contract RewardsDistributionRecipient { address public rewardsDistribution; function notifyRewardAmount(uint256 reward) virtual external; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); _; } } contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, ReentrancyGuardUpgradeSafe { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ IERC20 public rewardsToken; IERC20 public stakingToken; uint256 public periodFinish = 0; uint256 public rewardRate = 0; // obsoleted uint256 public rewardsDuration = 60 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) override public rewards; uint256 internal _totalSupply; mapping(address => uint256) internal _balances; /* ========== CONSTRUCTOR ========== */ //constructor( function __StakingRewards_init( address _rewardsDistribution, address _rewardsToken, address _stakingToken ) public initializer { __ReentrancyGuard_init_unchained(); __StakingRewards_init_unchained(_rewardsDistribution, _rewardsToken, _stakingToken); } function __StakingRewards_init_unchained(address _rewardsDistribution, address _rewardsToken, address _stakingToken) public initializer { rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); rewardsDistribution = _rewardsDistribution; } /* ========== VIEWS ========== */ function totalSupply() virtual override public view returns (uint256) { return _totalSupply; } function balanceOf(address account) virtual override public view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() override public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() virtual override public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply) ); } function earned(address account) virtual override public view returns (uint256) { return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); } function getRewardForDuration() virtual override external view returns (uint256) { return rewardRate.mul(rewardsDuration); } /* ========== MUTATIVE FUNCTIONS ========== */ function stakeWithPermit(uint256 amount, uint deadline, uint8 v, bytes32 r, bytes32 s) virtual public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); // permit IPermit(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function stake(uint256 amount) virtual override public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) virtual override public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stakingToken.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() virtual override public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() virtual override public { withdraw(_balances[msg.sender]); getReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(uint256 reward) override external onlyRewardsDistribution updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(rewardsDuration); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint balance = rewardsToken.balanceOf(address(this)); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(rewardsDuration); emit RewardAdded(reward); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) virtual { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } /* ========== EVENTS ========== */ event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); } interface IPermit { function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; } contract Constants { bytes32 internal constant _TokenMapped_ = 'TokenMapped'; bytes32 internal constant _MappableToken_ = 'MappableToken'; bytes32 internal constant _MappingToken_ = 'MappingToken'; bytes32 internal constant _fee_ = 'fee'; bytes32 internal constant _feeCreate_ = 'feeCreate'; bytes32 internal constant _feeRegister_ = 'feeRegister'; bytes32 internal constant _feeTo_ = 'feeTo'; bytes32 internal constant _onlyDeployer_ = 'onlyDeployer'; bytes32 internal constant _minSignatures_ = 'minSignatures'; bytes32 internal constant _initQuotaRatio_ = 'initQuotaRatio'; bytes32 internal constant _autoQuotaRatio_ = 'autoQuotaRatio'; bytes32 internal constant _autoQuotaPeriod_ = 'autoQuotaPeriod'; //bytes32 internal constant _uniswapRounter_ = 'uniswapRounter'; function _chainId() internal pure returns (uint id) { assembly { id := chainid() } } } struct Signature { address signatory; uint8 v; bytes32 r; bytes32 s; } abstract contract MappingBase is ContextUpgradeSafe, Constants { using SafeMath for uint; bytes32 public constant RECEIVE_TYPEHASH = keccak256("Receive(uint256 fromChainId,address to,uint256 nonce,uint256 volume,address signatory)"); bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); bytes32 internal _DOMAIN_SEPARATOR; function DOMAIN_SEPARATOR() virtual public view returns (bytes32) { return _DOMAIN_SEPARATOR; } address public factory; uint256 public mainChainId; address public token; address public deployer; mapping (address => uint) internal _authQuotas; // signatory => quota mapping (uint => mapping (address => uint)) public sentCount; // toChainId => to => sentCount mapping (uint => mapping (address => mapping (uint => uint))) public sent; // toChainId => to => nonce => volume mapping (uint => mapping (address => mapping (uint => uint))) public received; // fromChainId => to => nonce => volume mapping (address => uint) public lasttimeUpdateQuotaOf; // signatory => lasttime uint public autoQuotaRatio; uint public autoQuotaPeriod; function setAutoQuota(uint ratio, uint period) virtual external onlyFactory { autoQuotaRatio = ratio; autoQuotaPeriod = period; } modifier onlyFactory { require(msg.sender == factory, 'Only called by Factory'); _; } modifier updateAutoQuota(address signatory) virtual { uint quota = authQuotaOf(signatory); if(_authQuotas[signatory] != quota) { _authQuotas[signatory] = quota; lasttimeUpdateQuotaOf[signatory] = now; } _; } function authQuotaOf(address signatory) virtual public view returns (uint quota) { quota = _authQuotas[signatory]; uint ratio = autoQuotaRatio != 0 ? autoQuotaRatio : Factory(factory).getConfig(_autoQuotaRatio_); uint period = autoQuotaPeriod != 0 ? autoQuotaPeriod : Factory(factory).getConfig(_autoQuotaPeriod_); if(ratio == 0 || period == 0 || period == uint(-1)) return quota; uint quotaCap = cap().mul(ratio).div(1e18); uint delta = quotaCap.mul(now.sub(lasttimeUpdateQuotaOf[signatory])).div(period); return Math.max(quota, Math.min(quotaCap, quota.add(delta))); } function cap() public view virtual returns (uint); function increaseAuthQuotas(address[] memory signatories, uint[] memory increments) virtual external returns (uint[] memory quotas) { require(signatories.length == increments.length, 'two array lenth not equal'); quotas = new uint[](signatories.length); for(uint i=0; i<signatories.length; i++) quotas[i] = increaseAuthQuota(signatories[i], increments[i]); } function increaseAuthQuota(address signatory, uint increment) virtual public updateAutoQuota(signatory) onlyFactory returns (uint quota) { quota = _authQuotas[signatory].add(increment); _authQuotas[signatory] = quota; emit IncreaseAuthQuota(signatory, increment, quota); } event IncreaseAuthQuota(address indexed signatory, uint increment, uint quota); function decreaseAuthQuotas(address[] memory signatories, uint[] memory decrements) virtual external returns (uint[] memory quotas) { require(signatories.length == decrements.length, 'two array lenth not equal'); quotas = new uint[](signatories.length); for(uint i=0; i<signatories.length; i++) quotas[i] = decreaseAuthQuota(signatories[i], decrements[i]); } function decreaseAuthQuota(address signatory, uint decrement) virtual public onlyFactory returns (uint quota) { quota = authQuotaOf(signatory); if(quota < decrement) decrement = quota; return _decreaseAuthQuota(signatory, decrement); } function _decreaseAuthQuota(address signatory, uint decrement) virtual internal updateAutoQuota(signatory) returns (uint quota) { quota = _authQuotas[signatory].sub(decrement); _authQuotas[signatory] = quota; emit DecreaseAuthQuota(signatory, decrement, quota); } event DecreaseAuthQuota(address indexed signatory, uint decrement, uint quota); function needApprove() virtual public pure returns (bool); function send(uint toChainId, address to, uint volume) virtual external payable returns (uint nonce) { return sendFrom(_msgSender(), toChainId, to, volume); } function sendFrom(address from, uint toChainId, address to, uint volume) virtual public payable returns (uint nonce) { _chargeFee(); _sendFrom(from, volume); nonce = sentCount[toChainId][to]++; sent[toChainId][to][nonce] = volume; emit Send(from, toChainId, to, nonce, volume); } event Send(address indexed from, uint indexed toChainId, address indexed to, uint nonce, uint volume); function _sendFrom(address from, uint volume) virtual internal; function receive(uint256 fromChainId, address to, uint256 nonce, uint256 volume, Signature[] memory signatures) virtual external payable { _chargeFee(); require(received[fromChainId][to][nonce] == 0, 'withdrawn already'); uint N = signatures.length; require(N >= Factory(factory).getConfig(_minSignatures_), 'too few signatures'); for(uint i=0; i<N; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 structHash = keccak256(abi.encode(RECEIVE_TYPEHASH, fromChainId, to, nonce, volume, signatures[i].signatory)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", _DOMAIN_SEPARATOR, structHash)); address signatory = ecrecover(digest, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthQuota(signatures[i].signatory, volume); emit Authorize(fromChainId, to, nonce, volume, signatory); } received[fromChainId][to][nonce] = volume; _receive(to, volume); emit Receive(fromChainId, to, nonce, volume); } event Receive(uint256 indexed fromChainId, address indexed to, uint256 indexed nonce, uint256 volume); event Authorize(uint256 fromChainId, address indexed to, uint256 indexed nonce, uint256 volume, address indexed signatory); function _receive(address to, uint256 volume) virtual internal; function _chargeFee() virtual internal { require(msg.value >= Math.min(Factory(factory).getConfig(_fee_), 0.1 ether), 'fee is too low'); address payable feeTo = address(Factory(factory).getConfig(_feeTo_)); if(feeTo == address(0)) feeTo = address(uint160(factory)); feeTo.transfer(msg.value); emit ChargeFee(_msgSender(), feeTo, msg.value); } event ChargeFee(address indexed from, address indexed to, uint value); uint256[47] private __gap; } contract TokenMapped is MappingBase { using SafeERC20 for IERC20; function __TokenMapped_init(address factory_, address token_) external initializer { __Context_init_unchained(); __TokenMapped_init_unchained(factory_, token_); } function __TokenMapped_init_unchained(address factory_, address token_) public initializer { factory = factory_; mainChainId = _chainId(); token = token_; deployer = address(0); _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(ERC20UpgradeSafe(token).name())), _chainId(), address(this))); } function cap() virtual override public view returns (uint) { return IERC20(token).totalSupply(); } function totalMapped() virtual public view returns (uint) { return IERC20(token).balanceOf(address(this)); } function needApprove() virtual override public pure returns (bool) { return true; } function _sendFrom(address from, uint volume) virtual override internal { IERC20(token).safeTransferFrom(from, address(this), volume); } function _receive(address to, uint256 volume) virtual override internal { IERC20(token).safeTransfer(to, volume); } uint256[50] private __gap; } /* contract TokenMapped2 is TokenMapped, StakingRewards, ConfigurableBase { modifier governance { require(_msgSender() == MappingTokenFactory(factory).governor()); _; } function setConfig(bytes32 key, uint value) external governance { _setConfig(key, value); } function setConfigI(bytes32 key, uint index, uint value) external governance { _setConfig(bytes32(uint(key) ^ index), value); } function setConfigA(bytes32 key, address addr, uint value) public governance { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } function rewardDelta() public view returns (uint amt) { if(begin == 0 || begin >= now || lastUpdateTime >= now) return 0; amt = rewardsToken.allowance(rewardsDistribution, address(this)).sub0(rewards[address(0)]); // calc rewardDelta in period if(lep == 3) { // power uint y = period.mul(1 ether).div(lastUpdateTime.add(rewardsDuration).sub(begin)); uint amt1 = amt.mul(1 ether).div(y); uint amt2 = amt1.mul(period).div(now.add(rewardsDuration).sub(begin)); amt = amt.sub(amt2); } else if(lep == 2) { // exponential if(now.sub(lastUpdateTime) < rewardsDuration) amt = amt.mul(now.sub(lastUpdateTime)).div(rewardsDuration); }else if(now < periodFinish) // linear amt = amt.mul(now.sub(lastUpdateTime)).div(periodFinish.sub(lastUpdateTime)); else if(lastUpdateTime >= periodFinish) amt = 0; } function rewardPerToken() virtual override public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( rewardDelta().mul(1e18).div(_totalSupply) ); } modifier updateReward(address account) virtual override { (uint delta, uint d) = (rewardDelta(), 0); rewardPerTokenStored = rewardPerToken(); lastUpdateTime = now; if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } address addr = address(config[_ecoAddr_]); uint ratio = config[_ecoRatio_]; if(addr != address(0) && ratio != 0) { d = delta.mul(ratio).div(1 ether); rewards[addr] = rewards[addr].add(d); } rewards[address(0)] = rewards[address(0)].add(delta).add(d); _; } function getReward() virtual override public { getReward(msg.sender); } function getReward(address payable acct) virtual public nonReentrant updateReward(acct) { require(acct != address(0), 'invalid address'); require(getConfig(_blocklist_, acct) == 0, 'In blocklist'); bool isContract = acct.isContract(); require(!isContract || config[_allowContract_] != 0 || getConfig(_allowlist_, acct) != 0, 'No allowContract'); uint256 reward = rewards[acct]; if (reward > 0) { paid[acct] = paid[acct].add(reward); paid[address(0)] = paid[address(0)].add(reward); rewards[acct] = 0; rewards[address(0)] = rewards[address(0)].sub0(reward); rewardsToken.safeTransferFrom(rewardsDistribution, acct, reward); emit RewardPaid(acct, reward); } } function getRewardForDuration() override external view returns (uint256) { return rewardsToken.allowance(rewardsDistribution, address(this)).sub0(rewards[address(0)]); } } */ abstract contract Permit { // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; function DOMAIN_SEPARATOR() virtual public view returns (bytes32); mapping (address => uint) public nonces; function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, 'permit EXPIRED'); bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, 'permit INVALID_SIGNATURE'); _approve(owner, spender, value); } function _approve(address owner, address spender, uint256 amount) internal virtual; uint256[50] private __gap; } contract MappableToken is Permit, ERC20UpgradeSafe, MappingBase { function __MappableToken_init(address factory_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint256 totalSupply_) external initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); _setupDecimals(decimals_); _mint(deployer_, totalSupply_); __MappableToken_init_unchained(factory_, deployer_); } function __MappableToken_init_unchained(address factory_, address deployer_) public initializer { factory = factory_; mainChainId = _chainId(); token = address(0); deployer = deployer_; _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), _chainId(), address(this))); } function DOMAIN_SEPARATOR() virtual override(Permit, MappingBase) public view returns (bytes32) { return MappingBase.DOMAIN_SEPARATOR(); } function cap() virtual override public view returns (uint) { return totalSupply(); } function totalMapped() virtual public view returns (uint) { return balanceOf(address(this)); } function needApprove() virtual override public pure returns (bool) { return false; } function _approve(address owner, address spender, uint256 amount) virtual override(Permit, ERC20UpgradeSafe) internal { return ERC20UpgradeSafe._approve(owner, spender, amount); } function _sendFrom(address from, uint volume) virtual override internal { transferFrom(from, address(this), volume); } function _receive(address to, uint256 volume) virtual override internal { _transfer(address(this), to, volume); } uint256[50] private __gap; } contract MappingToken is Permit, ERC20CappedUpgradeSafe, MappingBase { function __MappingToken_init(address factory_, uint mainChainId_, address token_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint cap_) external initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); _setupDecimals(decimals_); __ERC20Capped_init_unchained(cap_); __MappingToken_init_unchained(factory_, mainChainId_, token_, deployer_); } function __MappingToken_init_unchained(address factory_, uint mainChainId_, address token_, address deployer_) public initializer { factory = factory_; mainChainId = mainChainId_; token = token_; deployer = (token_ == address(0)) ? deployer_ : address(0); _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), _chainId(), address(this))); } function DOMAIN_SEPARATOR() virtual override(Permit, MappingBase) public view returns (bytes32) { return MappingBase.DOMAIN_SEPARATOR(); } function cap() virtual override(ERC20CappedUpgradeSafe, MappingBase) public view returns (uint) { return ERC20CappedUpgradeSafe.cap(); } function needApprove() virtual override public pure returns (bool) { return false; } function _approve(address owner, address spender, uint256 amount) virtual override(Permit, ERC20UpgradeSafe) internal { return ERC20UpgradeSafe._approve(owner, spender, amount); } function _sendFrom(address from, uint volume) virtual override internal { _burn(from, volume); if(from != _msgSender() && allowance(from, _msgSender()) != uint(-1)) _approve(from, _msgSender(), allowance(from, _msgSender()).sub(volume, "ERC20: transfer volume exceeds allowance")); } function _receive(address to, uint256 volume) virtual override internal { _mint(to, volume); } uint256[50] private __gap; } contract MappingTokenProxy is ProductProxy, Constants { constructor(address factory_, uint mainChainId_, address token_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint cap_) public { //require(_factory() == address(0)); assert(FACTORY_SLOT == bytes32(uint256(keccak256('eip1967.proxy.factory')) - 1)); assert(NAME_SLOT == bytes32(uint256(keccak256('eip1967.proxy.name')) - 1)); _setFactory(factory_); _setName(_MappingToken_); (bool success,) = _implementation().delegatecall(abi.encodeWithSignature('__MappingToken_init(address,uint256,address,address,string,string,uint8,uint256)', factory_, mainChainId_, token_, deployer_, name_, symbol_, decimals_, cap_)); require(success); } } contract Factory is ContextUpgradeSafe, Configurable, Constants { using SafeERC20 for IERC20; using SafeMath for uint; bytes32 public constant REGISTER_TYPEHASH = keccak256("RegisterMapping(uint mainChainId,address token,uint[] chainIds,address[] mappingTokenMappeds,address signatory)"); bytes32 public constant CREATE_TYPEHASH = keccak256("CreateMappingToken(address deployer,uint mainChainId,address token,string name,string symbol,uint8 decimals,uint cap,address signatory)"); bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); bytes32 public DOMAIN_SEPARATOR; mapping (bytes32 => address) public productImplementations; mapping (address => address) public tokenMappeds; // token => tokenMapped mapping (address => address) public mappableTokens; // deployer => mappableTokens mapping (uint256 => mapping (address => address)) public mappingTokens; // mainChainId => token or deployer => mappableTokens mapping (address => bool) public authorties; // only on ethereum mainnet mapping (address => uint) public authCountOf; // signatory => count mapping (address => uint256) internal _mainChainIdTokens; // mappingToken => mainChainId+token mapping (address => mapping (uint => address)) public mappingTokenMappeds; // token => chainId => mappingToken or tokenMapped uint[] public supportChainIds; mapping (string => uint256) internal _certifiedTokens; // symbol => mainChainId+token string[] public certifiedSymbols; address[] public signatories; function __MappingTokenFactory_init(address _governor, address _implTokenMapped, address _implMappableToken, address _implMappingToken, address _feeTo) external initializer { __Governable_init_unchained(_governor); __MappingTokenFactory_init_unchained(_implTokenMapped, _implMappableToken, _implMappingToken, _feeTo); } function __MappingTokenFactory_init_unchained(address _implTokenMapped, address _implMappableToken, address _implMappingToken, address _feeTo) public governance { config[_fee_] = 0.005 ether; config[_feeCreate_] = 0.100 ether; config[_feeRegister_] = 0.200 ether; config[_feeTo_] = uint(_feeTo); config[_onlyDeployer_] = 1; config[_minSignatures_] = 3; config[_initQuotaRatio_] = 0.100 ether; // 10% config[_autoQuotaRatio_] = 0.010 ether; // 1% config[_autoQuotaPeriod_] = 1 days; //config[_uniswapRounter_] = uint(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes('MappingTokenFactory')), _chainId(), address(this))); upgradeProductImplementationsTo_(_implTokenMapped, _implMappableToken, _implMappingToken); emit ProductProxyCodeHash(keccak256(type(InitializableProductProxy).creationCode)); } event ProductProxyCodeHash(bytes32 codeHash); function upgradeProductImplementationsTo_(address _implTokenMapped, address _implMappableToken, address _implMappingToken) public governance { productImplementations[_TokenMapped_] = _implTokenMapped; productImplementations[_MappableToken_] = _implMappableToken; productImplementations[_MappingToken_] = _implMappingToken; } function setSignatories(address[] calldata signatories_) virtual external governance { signatories = signatories_; emit SetSignatories(signatories_); } event SetSignatories(address[] signatories_); function setAuthorty_(address authorty, bool enable) virtual external governance { authorties[authorty] = enable; emit SetAuthorty(authorty, enable); } event SetAuthorty(address indexed authorty, bool indexed enable); function setAutoQuota(address mappingTokenMapped, uint ratio, uint period) virtual external governance { if(mappingTokenMapped == address(0)) { config[_autoQuotaRatio_] = ratio; config[_autoQuotaPeriod_] = period; } else MappingBase(mappingTokenMapped).setAutoQuota(ratio, period); } modifier onlyAuthorty { require(authorties[_msgSender()], 'only authorty'); _; } function _initAuthQuotas(address mappingTokenMapped, uint cap) internal { uint quota = cap.mul(config[_initQuotaRatio_]).div(1e18); uint[] memory quotas = new uint[](signatories.length); for(uint i=0; i<quotas.length; i++) quotas[i] = quota; _increaseAuthQuotas(mappingTokenMapped, signatories, quotas); } function _increaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory increments) virtual internal returns (uint[] memory quotas) { quotas = MappingBase(mappingTokenMapped).increaseAuthQuotas(signatories_, increments); for(uint i=0; i<signatories_.length; i++) emit IncreaseAuthQuota(_msgSender(), mappingTokenMapped, signatories_[i], increments[i], quotas[i]); } function increaseAuthQuotas_(address mappingTokenMapped, uint[] memory increments) virtual external onlyAuthorty returns (uint[] memory quotas) { return _increaseAuthQuotas(mappingTokenMapped, signatories, increments); } function increaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory increments) virtual external onlyAuthorty returns (uint[] memory quotas) { return _increaseAuthQuotas(mappingTokenMapped, signatories_, increments); } function increaseAuthQuota(address mappingTokenMapped, address signatory, uint increment) virtual external onlyAuthorty returns (uint quota) { quota = MappingBase(mappingTokenMapped).increaseAuthQuota(signatory, increment); emit IncreaseAuthQuota(_msgSender(), mappingTokenMapped, signatory, increment, quota); } event IncreaseAuthQuota(address indexed authorty, address indexed mappingTokenMapped, address indexed signatory, uint increment, uint quota); function decreaseAuthQuotas_(address mappingTokenMapped, uint[] memory decrements) virtual external returns (uint[] memory quotas) { return decreaseAuthQuotas(mappingTokenMapped, signatories, decrements); } function decreaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory decrements) virtual public onlyAuthorty returns (uint[] memory quotas) { quotas = MappingBase(mappingTokenMapped).decreaseAuthQuotas(signatories_, decrements); for(uint i=0; i<signatories_.length; i++) emit DecreaseAuthQuota(_msgSender(), mappingTokenMapped, signatories_[i], decrements[i], quotas[i]); } function decreaseAuthQuota(address mappingTokenMapped, address signatory, uint decrement) virtual external onlyAuthorty returns (uint quota) { quota = MappingBase(mappingTokenMapped).decreaseAuthQuota(signatory, decrement); emit DecreaseAuthQuota(_msgSender(), mappingTokenMapped, signatory, decrement, quota); } event DecreaseAuthQuota(address indexed authorty, address indexed mappingTokenMapped, address indexed signatory, uint decrement, uint quota); function increaseAuthCounts_(uint[] memory increments) virtual external returns (uint[] memory counts) { return increaseAuthCounts(signatories, increments); } function increaseAuthCounts(address[] memory signatories_, uint[] memory increments) virtual public returns (uint[] memory counts) { require(signatories_.length == increments.length, 'two array lenth not equal'); counts = new uint[](signatories_.length); for(uint i=0; i<signatories_.length; i++) counts[i] = increaseAuthCount(signatories_[i], increments[i]); } function increaseAuthCount(address signatory, uint increment) virtual public onlyAuthorty returns (uint count) { count = authCountOf[signatory].add(increment); authCountOf[signatory] = count; emit IncreaseAuthQuota(_msgSender(), signatory, increment, count); } event IncreaseAuthQuota(address indexed authorty, address indexed signatory, uint increment, uint quota); function decreaseAuthCounts_(uint[] memory decrements) virtual external returns (uint[] memory counts) { return decreaseAuthCounts(signatories, decrements); } function decreaseAuthCounts(address[] memory signatories_, uint[] memory decrements) virtual public returns (uint[] memory counts) { require(signatories_.length == decrements.length, 'two array lenth not equal'); counts = new uint[](signatories_.length); for(uint i=0; i<signatories_.length; i++) counts[i] = decreaseAuthCount(signatories_[i], decrements[i]); } function decreaseAuthCount(address signatory, uint decrement) virtual public onlyAuthorty returns (uint count) { count = authCountOf[signatory]; if(count < decrement) decrement = count; return _decreaseAuthCount(signatory, decrement); } function _decreaseAuthCount(address signatory, uint decrement) virtual internal returns (uint count) { count = authCountOf[signatory].sub(decrement); authCountOf[signatory] = count; emit DecreaseAuthCount(_msgSender(), signatory, decrement, count); } event DecreaseAuthCount(address indexed authorty, address indexed signatory, uint decrement, uint count); function supportChainCount() public view returns (uint) { return supportChainIds.length; } function mainChainIdTokens(address mappingToken) virtual public view returns(uint mainChainId, address token) { uint256 chainIdToken = _mainChainIdTokens[mappingToken]; mainChainId = chainIdToken >> 160; token = address(chainIdToken); } function chainIdMappingTokenMappeds(address tokenOrMappingToken) virtual external view returns (uint[] memory chainIds, address[] memory mappingTokenMappeds_) { (, address token) = mainChainIdTokens(tokenOrMappingToken); if(token == address(0)) token = tokenOrMappingToken; uint N = 0; for(uint i=0; i<supportChainCount(); i++) if(mappingTokenMappeds[token][supportChainIds[i]] != address(0)) N++; chainIds = new uint[](N); mappingTokenMappeds_ = new address[](N); uint j = 0; for(uint i=0; i<supportChainCount(); i++) { uint chainId = supportChainIds[i]; address mappingTokenMapped = mappingTokenMappeds[token][chainId]; if(mappingTokenMapped != address(0)) { chainIds[j] = chainId; mappingTokenMappeds_[j] = mappingTokenMapped; j++; } } } function isSupportChainId(uint chainId) virtual public view returns (bool) { for(uint i=0; i<supportChainCount(); i++) if(supportChainIds[i] == chainId) return true; return false; } function registerSupportChainId_(uint chainId_) virtual external governance { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(!isSupportChainId(chainId_), 'support chainId already'); supportChainIds.push(chainId_); } function _registerMapping(uint mainChainId, address token, uint[] memory chainIds, address[] memory mappingTokenMappeds_) virtual internal { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(chainIds.length == mappingTokenMappeds_.length, 'two array lenth not equal'); require(isSupportChainId(mainChainId), 'Not support mainChainId'); for(uint i=0; i<chainIds.length; i++) { require(isSupportChainId(chainIds[i]), 'Not support chainId'); require(token == mappingTokenMappeds_[i] || mappingTokenMappeds_[i] == calcMapping(mainChainId, token) || _msgSender() == governor, 'invalid mappingTokenMapped address'); //require(_mainChainIdTokens[mappingTokenMappeds_[i]] == 0 || _mainChainIdTokens[mappingTokenMappeds_[i]] == (mainChainId << 160) | uint(token), 'mainChainIdTokens exist already'); //require(mappingTokenMappeds[token][chainIds[i]] == address(0), 'mappingTokenMappeds exist already'); //if(_mainChainIdTokens[mappingTokenMappeds_[i]] == 0) _mainChainIdTokens[mappingTokenMappeds_[i]] = (mainChainId << 160) | uint(token); mappingTokenMappeds[token][chainIds[i]] = mappingTokenMappeds_[i]; emit RegisterMapping(mainChainId, token, chainIds[i], mappingTokenMappeds_[i]); } } event RegisterMapping(uint mainChainId, address token, uint chainId, address mappingTokenMapped); function registerMapping_(uint mainChainId, address token, uint[] memory chainIds, address[] memory mappingTokenMappeds_) virtual external governance { _registerMapping(mainChainId, token, chainIds, mappingTokenMappeds_); } function registerMapping(uint mainChainId, address token, uint nonce, uint[] memory chainIds, address[] memory mappingTokenMappeds_, Signature[] memory signatures) virtual external payable { _chargeFee(config[_feeRegister_]); require(config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); uint N = signatures.length; require(N >= getConfig(_minSignatures_), 'too few signatures'); for(uint i=0; i<N; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 structHash = keccak256(abi.encode(REGISTER_TYPEHASH, mainChainId, token, keccak256(abi.encodePacked(chainIds)), keccak256(abi.encodePacked(mappingTokenMappeds_)), signatures[i].signatory)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash)); address signatory = ecrecover(digest, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthCount(signatures[i].signatory, 1); emit AuthorizeRegister(mainChainId, token, signatory); } _registerMapping(mainChainId, token, chainIds, mappingTokenMappeds_); } event AuthorizeRegister(uint indexed mainChainId, address indexed token, address indexed signatory); function certifiedCount() external view returns (uint) { return certifiedSymbols.length; } function certifiedTokens(string memory symbol) public view returns (uint mainChainId, address token) { uint256 chainIdToken = _certifiedTokens[symbol]; mainChainId = chainIdToken >> 160; token = address(chainIdToken); } function allCertifiedTokens() external view returns (string[] memory symbols, uint[] memory chainIds, address[] memory tokens) { symbols = certifiedSymbols; uint N = certifiedSymbols.length; chainIds = new uint[](N); tokens = new address[](N); for(uint i=0; i<N; i++) (chainIds[i], tokens[i]) = certifiedTokens(certifiedSymbols[i]); } function registerCertified_(string memory symbol, uint mainChainId, address token) external governance { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(isSupportChainId(mainChainId), 'Not support mainChainId'); require(_certifiedTokens[symbol] == 0, 'Certified added already'); if(mainChainId == _chainId()) require(keccak256(bytes(symbol)) == keccak256(bytes(ERC20UpgradeSafe(token).symbol())), 'symbol different'); _certifiedTokens[symbol] = (mainChainId << 160) | uint(token); certifiedSymbols.push(symbol); emit RegisterCertified(symbol, mainChainId, token); } event RegisterCertified(string indexed symbol, uint indexed mainChainId, address indexed token); //function updateCertified_(string memory symbol, uint mainChainId, address token) external governance { // require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); // require(isSupportChainId(mainChainId), 'Not support mainChainId'); // //require(_certifiedTokens[symbol] == 0, 'Certified added already'); // if(mainChainId == _chainId()) // require(keccak256(bytes(symbol)) == keccak256(bytes(ERC20UpgradeSafe(token).symbol())), 'symbol different'); // _certifiedTokens[symbol] = (mainChainId << 160) | uint(token); // //certifiedSymbols.push(symbol); // emit UpdateCertified(symbol, mainChainId, token); //} //event UpdateCertified(string indexed symbol, uint indexed mainChainId, address indexed token); function calcContract(address deployer, uint nonce) public pure returns (address) { bytes[] memory list = new bytes[](2); list[0] = RLPEncode.encodeAddress(deployer); list[1] = RLPEncode.encodeUint(nonce); return address(uint(keccak256(RLPEncode.encodeList(list)))); } // calculates the CREATE2 address for a pair without making any external calls function calcMapping(uint mainChainId, address tokenOrdeployer) public view returns (address) { return address(uint(keccak256(abi.encodePacked( hex'ff', address(this), keccak256(abi.encodePacked(mainChainId, tokenOrdeployer)), keccak256(type(InitializableProductProxy).creationCode) //hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash )))); } function createTokenMapped(address token, uint nonce) external payable returns (address tokenMapped) { if(_msgSender() != governor) { _chargeFee(config[_feeCreate_]); require(config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); } require(tokenMappeds[token] == address(0), 'TokenMapped created already'); bytes32 salt = keccak256(abi.encodePacked(_chainId(), token)); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { tokenMapped := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(tokenMapped)).__InitializableProductProxy_init(address(this), _TokenMapped_, abi.encodeWithSignature('__TokenMapped_init(address,address)', address(this), token)); tokenMappeds[token] = tokenMapped; _initAuthQuotas(tokenMapped, IERC20(token).totalSupply()); emit CreateTokenMapped(_msgSender(), token, tokenMapped); } event CreateTokenMapped(address indexed deployer, address indexed token, address indexed tokenMapped); function createMappableToken(string memory name, string memory symbol, uint8 decimals, uint totalSupply) external payable returns (address mappableToken) { if(_msgSender() != governor) _chargeFee(config[_feeCreate_]); require(mappableTokens[_msgSender()] == address(0), 'MappableToken created already'); bytes32 salt = keccak256(abi.encodePacked(_chainId(), _msgSender())); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { mappableToken := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(mappableToken)).__InitializableProductProxy_init(address(this), _MappableToken_, abi.encodeWithSignature('__MappableToken_init(address,address,string,string,uint8,uint256)', address(this), _msgSender(), name, symbol, decimals, totalSupply)); mappableTokens[_msgSender()] = mappableToken; _initAuthQuotas(mappableToken, totalSupply); emit CreateMappableToken(_msgSender(), name, symbol, decimals, totalSupply, mappableToken); } event CreateMappableToken(address indexed deployer, string name, string symbol, uint8 decimals, uint totalSupply, address indexed mappableToken); function _createMappingToken(uint mainChainId, address token, address deployer, string memory name, string memory symbol, uint8 decimals, uint cap) internal returns (address mappingToken) { address tokenOrdeployer = (token == address(0)) ? deployer : token; require(mappingTokens[mainChainId][tokenOrdeployer] == address(0), 'MappingToken created already'); bytes32 salt = keccak256(abi.encodePacked(mainChainId, tokenOrdeployer)); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { mappingToken := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(mappingToken)).__InitializableProductProxy_init(address(this), _MappingToken_, abi.encodeWithSignature('__MappingToken_init(address,uint256,address,address,string,string,uint8,uint256)', address(this), mainChainId, token, deployer, name, symbol, decimals, cap)); mappingTokens[mainChainId][tokenOrdeployer] = mappingToken; _initAuthQuotas(mappingToken, cap); emit CreateMappingToken(mainChainId, token, deployer, name, symbol, decimals, cap, mappingToken); } event CreateMappingToken(uint mainChainId, address indexed token, address indexed deployer, string name, string symbol, uint8 decimals, uint cap, address indexed mappingToken); function createMappingToken_(uint mainChainId, address token, address deployer, string memory name, string memory symbol, uint8 decimals, uint cap) public payable governance returns (address mappingToken) { return _createMappingToken(mainChainId, token, deployer, name, symbol, decimals, cap); } function createMappingToken(uint mainChainId, address token, uint nonce, string memory name, string memory symbol, uint8 decimals, uint cap, Signature[] memory signatures) public payable returns (address mappingToken) { _chargeFee(config[_feeCreate_]); require(token == address(0) || config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); require(signatures.length >= config[_minSignatures_], 'too few signatures'); for(uint i=0; i<signatures.length; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 hash = keccak256(abi.encode(CREATE_TYPEHASH, _msgSender(), mainChainId, token, keccak256(bytes(name)), keccak256(bytes(symbol)), decimals, cap, signatures[i].signatory)); hash = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hash)); address signatory = ecrecover(hash, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthCount(signatures[i].signatory, 1); emit AuthorizeCreate(mainChainId, token, _msgSender(), name, symbol, decimals, cap, signatory); } return _createMappingToken(mainChainId, token, _msgSender(), name, symbol, decimals, cap); } event AuthorizeCreate(uint mainChainId, address indexed token, address indexed deployer, string name, string symbol, uint8 decimals, uint cap, address indexed signatory); function _chargeFee(uint fee) virtual internal { require(msg.value >= Math.min(fee, 1 ether), 'fee is too low'); address payable feeTo = address(config[_feeTo_]); if(feeTo == address(0)) feeTo = address(uint160(address(this))); feeTo.transfer(msg.value); emit ChargeFee(_msgSender(), feeTo, msg.value); } event ChargeFee(address indexed from, address indexed to, uint value); uint256[49] private __gap; }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mainChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"}],"name":"AuthorizeCreate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"mainChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"}],"name":"AuthorizeRegister","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ChargeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":true,"internalType":"address","name":"mappableToken","type":"address"}],"name":"CreateMappableToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mainChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"},{"indexed":true,"internalType":"address","name":"mappingToken","type":"address"}],"name":"CreateMappingToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"tokenMapped","type":"address"}],"name":"CreateTokenMapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorty","type":"address"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"decrement","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"DecreaseAuthCount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorty","type":"address"},{"indexed":true,"internalType":"address","name":"mappingTokenMapped","type":"address"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"decrement","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quota","type":"uint256"}],"name":"DecreaseAuthQuota","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"GovernorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorty","type":"address"},{"indexed":true,"internalType":"address","name":"mappingTokenMapped","type":"address"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"increment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quota","type":"uint256"}],"name":"IncreaseAuthQuota","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorty","type":"address"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"increment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quota","type":"uint256"}],"name":"IncreaseAuthQuota","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"codeHash","type":"bytes32"}],"name":"ProductProxyCodeHash","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"symbol","type":"string"},{"indexed":true,"internalType":"uint256","name":"mainChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"RegisterCertified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mainChainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"mappingTokenMapped","type":"address"}],"name":"RegisterMapping","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorty","type":"address"},{"indexed":true,"internalType":"bool","name":"enable","type":"bool"}],"name":"SetAuthorty","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"signatories_","type":"address[]"}],"name":"SetSignatories","type":"event"},{"inputs":[],"name":"CREATE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTER_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"governor_","type":"address"}],"name":"__Governable_init_unchained","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governor","type":"address"},{"internalType":"address","name":"_implTokenMapped","type":"address"},{"internalType":"address","name":"_implMappableToken","type":"address"},{"internalType":"address","name":"_implMappingToken","type":"address"},{"internalType":"address","name":"_feeTo","type":"address"}],"name":"__MappingTokenFactory_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_implTokenMapped","type":"address"},{"internalType":"address","name":"_implMappableToken","type":"address"},{"internalType":"address","name":"_implMappingToken","type":"address"},{"internalType":"address","name":"_feeTo","type":"address"}],"name":"__MappingTokenFactory_init_unchained","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allCertifiedTokens","outputs":[{"internalType":"string[]","name":"symbols","type":"string[]"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authCountOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorties","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"calcContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"tokenOrdeployer","type":"address"}],"name":"calcMapping","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"certifiedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"certifiedSymbols","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"symbol","type":"string"}],"name":"certifiedTokens","outputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOrMappingToken","type":"address"}],"name":"chainIdMappingTokenMappeds","outputs":[{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"address[]","name":"mappingTokenMappeds_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"createMappableToken","outputs":[{"internalType":"address","name":"mappableToken","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"cap","type":"uint256"},{"components":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Signature[]","name":"signatures","type":"tuple[]"}],"name":"createMappingToken","outputs":[{"internalType":"address","name":"mappingToken","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"createMappingToken_","outputs":[{"internalType":"address","name":"mappingToken","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"createTokenMapped","outputs":[{"internalType":"address","name":"tokenMapped","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"decrement","type":"uint256"}],"name":"decreaseAuthCount","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signatories_","type":"address[]"},{"internalType":"uint256[]","name":"decrements","type":"uint256[]"}],"name":"decreaseAuthCounts","outputs":[{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"decrements","type":"uint256[]"}],"name":"decreaseAuthCounts_","outputs":[{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"decrement","type":"uint256"}],"name":"decreaseAuthQuota","outputs":[{"internalType":"uint256","name":"quota","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"address[]","name":"signatories_","type":"address[]"},{"internalType":"uint256[]","name":"decrements","type":"uint256[]"}],"name":"decreaseAuthQuotas","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"uint256[]","name":"decrements","type":"uint256[]"}],"name":"decreaseAuthQuotas_","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getConfig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"}],"name":"getConfigA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getConfigI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"increment","type":"uint256"}],"name":"increaseAuthCount","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signatories_","type":"address[]"},{"internalType":"uint256[]","name":"increments","type":"uint256[]"}],"name":"increaseAuthCounts","outputs":[{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"increments","type":"uint256[]"}],"name":"increaseAuthCounts_","outputs":[{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"increment","type":"uint256"}],"name":"increaseAuthQuota","outputs":[{"internalType":"uint256","name":"quota","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"address[]","name":"signatories_","type":"address[]"},{"internalType":"uint256[]","name":"increments","type":"uint256[]"}],"name":"increaseAuthQuotas","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"uint256[]","name":"increments","type":"uint256[]"}],"name":"increaseAuthQuotas_","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"isSupportChainId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"mappingToken","type":"address"}],"name":"mainChainIdTokens","outputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mappableTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mappingTokenMappeds","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"mappingTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"productImplementations","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"registerCertified_","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"address[]","name":"mappingTokenMappeds_","type":"address[]"},{"components":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Signature[]","name":"signatures","type":"tuple[]"}],"name":"registerMapping","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mainChainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"address[]","name":"mappingTokenMappeds_","type":"address[]"}],"name":"registerMapping_","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId_","type":"uint256"}],"name":"registerSupportChainId_","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorty","type":"address"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"setAuthorty_","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mappingTokenMapped","type":"address"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"}],"name":"setAutoQuota","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setConfigA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setConfigI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signatories_","type":"address[]"}],"name":"setSignatories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"signatories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportChainCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportChainIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenMappeds","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernor","type":"address"}],"name":"transferGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_implTokenMapped","type":"address"},{"internalType":"address","name":"_implMappableToken","type":"address"},{"internalType":"address","name":"_implMappingToken","type":"address"}],"name":"upgradeProductImplementationsTo_","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615fd780620000216000396000f3fe60806040526004361061038c5760003560e01c80636d2f818f116101dc578063aa1f4bf011610102578063ce8c4720116100a0578063df69e0161161006f578063df69e01614610a44578063e6d3bba714610a64578063f0e4efbf14610a84578063feff4a4914610aa45761038c565b8063ce8c4720146109de578063d0dedd27146109fe578063d5e6241014610a11578063db8e81b014610a245761038c565b8063bc9f4700116100dc578063bc9f47001461095e578063c8b956d61461097e578063c8eb8cd41461099e578063cdb9df6b146109be5761038c565b8063aa1f4bf0146108fe578063ae58c3011461091e578063b6aa515b1461093e5761038c565b806381c0c2631161017a5780639d329768116101495780639d3297681461088b5780639f007e68146108ab578063a44eab97146108cb578063a4a637c4146108de5761038c565b806381c0c263146108085780638e8529001461081d57806394b3e8711461084b5780639987cec81461086b5761038c565b8063756dcd13116101b6578063756dcd13146107875780637a418494146107a75780637a47363b146107ba5780637c25e959146107e85761038c565b80636d2f818f146107165780636dd5b69d146107435780636ef6f248146107635761038c565b8063392f6788116102c15780635e48f7551161025f57806365976b221161022e57806365976b22146106ac5780636a5306a3146106c15780636a99cf33146106d65780636b02ba2e146106f65761038c565b80635e48f755146106375780635ef03f0214610657578063648c58441461067757806364cc0d641461068c5761038c565b806348864f551161029b57806348864f55146105c45780634c4043b4146105e45780634ecaecbb14610604578063507b7274146106245761038c565b8063392f6788146105645780633b6d8ebe146105845780633d0e4bc1146105a45761038c565b806311ba17411161032e57806320606b701161030857806320606b70146104fa5780632dcc7d231461050f5780633015cd791461052f5780633644e5151461054f5761038c565b806311ba1741146104a557806315fe96dc146104ba5780631ae83a3e146104da5761038c565b80630a9783971161036a5780630a978397146104165780630b2bcd67146104365780630c340a24146104635780630e6be7bd146104785761038c565b8063021ddb7f1461039157806305a424af146103b35780630a86b2ab146103e9575b600080fd5b34801561039d57600080fd5b506103b16103ac366004614b36565b610ac4565b005b3480156103bf57600080fd5b506103d36103ce366004614a39565b610af5565b6040516103e091906153c1565b60405180910390f35b3480156103f557600080fd5b50610409610404366004614afa565b610b63565b6040516103e09190615404565b34801561042257600080fd5b506103d3610431366004614891565b610b81565b34801561044257600080fd5b50610456610451366004614afa565b610bf1565b6040516103e09190615195565b34801561046f57600080fd5b50610456610c0c565b34801561048457600080fd5b50610498610493366004614afa565b610c1b565b6040516103e091906154ce565b3480156104b157600080fd5b50610409610cc1565b3480156104c657600080fd5b506103b16104d5366004614b6b565b610ce5565b3480156104e657600080fd5b506103d36104f5366004614891565b610d0a565b34801561050657600080fd5b50610409610dbf565b34801561051b57600080fd5b506103b161052a36600461471f565b610de3565b34801561053b57600080fd5b5061045661054a366004614918565b61106e565b34801561055b57600080fd5b506104096110fb565b34801561057057600080fd5b506103d361057f3660046149e3565b611101565b34801561059057600080fd5b5061045661059f366004614918565b6111ca565b3480156105b057600080fd5b506104096105bf3660046146bf565b6111f0565b3480156105d057600080fd5b506103d36105df3660046149e3565b611202565b3480156105f057600080fd5b506104096105ff366004614b12565b6112c4565b34801561061057600080fd5b5061045661061f366004614d44565b6112e0565b610456610632366004614d70565b611306565b34801561064357600080fd5b506103b1610652366004614942565b61133b565b34801561066357600080fd5b506103b1610672366004614cd4565b61142d565b34801561068357600080fd5b50610409611656565b34801561069857600080fd5b506103d36106a736600461481f565b61165c565b3480156106b857600080fd5b506104096117dc565b3480156106cd57600080fd5b506104096117e2565b3480156106e257600080fd5b506103b16106f1366004614e18565b611806565b34801561070257600080fd5b50610409610711366004614b6b565b61182f565b34801561072257600080fd5b50610736610731366004614afa565b611842565b6040516103e091906153f9565b34801561074f57600080fd5b5061040961075e366004614afa565b61188f565b34801561076f57600080fd5b506107786118a1565b6040516103e093929190615338565b34801561079357600080fd5b506104096107a2366004614918565b611b01565b6103b16107b5366004614e94565b611bd9565b3480156107c657600080fd5b506107da6107d53660046146bf565b611faf565b6040516103e09291906153d4565b3480156107f457600080fd5b506103b16108033660046148dd565b612180565b34801561081457600080fd5b506103b16121eb565b34801561082957600080fd5b5061083d6108383660046146bf565b61224c565b6040516103e0929190615955565b34801561085757600080fd5b50610409610866366004614918565b61226c565b34801561087757600080fd5b506103b16108863660046146da565b6122e3565b34801561089757600080fd5b506103d36108a636600461481f565b6123ae565b3480156108b757600080fd5b506103b16108c6366004614975565b612408565b6104566108d9366004614c5b565b612469565b3480156108ea57600080fd5b506104096108f93660046147df565b6126dc565b34801561090a57600080fd5b506107366109193660046146bf565b61280a565b34801561092a57600080fd5b506103b1610939366004614b8c565b61281f565b34801561094a57600080fd5b506103b16109593660046146bf565b612842565b34801561096a57600080fd5b506104566109793660046146bf565b612865565b34801561098a57600080fd5b50610456610999366004614d44565b612880565b3480156109aa57600080fd5b506103b16109b9366004614776565b612908565b3480156109ca57600080fd5b506104566109d9366004614afa565b6129a5565b3480156109ea57600080fd5b506103d36109f9366004614a39565b6129cc565b610456610a0c366004614918565b612a32565b610456610a1f366004614f3b565b612d44565b348015610a3057600080fd5b506103b1610a3f366004614afa565b61312f565b348015610a5057600080fd5b506103b1610a5f3660046146bf565b6131da565b348015610a7057600080fd5b5061083d610a7f366004614bb7565b6132ac565b348015610a9057600080fd5b50610409610a9f3660046147df565b6132e0565b348015610ab057600080fd5b50610456610abf3660046146bf565b6133ff565b6065546001600160a01b03163314610adb57600080fd5b610af06001600160a01b03831684188261341a565b505050565b6060610b5b6073805480602002602001604051908101604052809291908181526020018280548015610b5057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b32575b505050505083611202565b90505b919050565b60708181548110610b7057fe5b600091825260209091200154905081565b6060610be8836073805480602002602001604051908101604052809291908181526020018280548015610bdd57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610bbf575b50505050508461165c565b90505b92915050565b6068602052600090815260409020546001600160a01b031681565b6065546001600160a01b031681565b60728181548110610c2857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015610cb95780601f10610c8e57610100808354040283529160200191610cb9565b820191906000526020600020905b815481529060010190602001808311610c9c57829003601f168201915b505050505081565b7f33a010203279ba8cdbc561bf3370b2ec1e054ec371ce4e4b8320d9446adc3f0b81565b6065546001600160a01b03163314610cfc57600080fd5b610d06828261341a565b5050565b6060606c6000610d18613441565b6001600160a01b0316815260208101919091526040016000205460ff16610d5a5760405162461bcd60e51b8152600401610d51906155e2565b60405180910390fd5b610be8836073805480602002602001604051908101604052809291908181526020018280548015610db457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d96575b505050505084613445565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6065546001600160a01b03163314610dfa57600080fd5b606660209081526611c37937e080007f4c327380d902ed7da19f788f7335cc4d8c07e9fd6f343de3af9a1ada79b852425567016345785d8a0000600080516020615f628339815191528190556702c68af0bb1400007fcb09fe4fbe012b91e8122a356e75d6ebd9689d95739d160b534385000acfae38556001600160a01b0383167f729bca52a6d55a36cde7d479eb9228d7df8a69b2e9ca2a9c0b17e052244a1e17556001600080516020615f828339815191525560037fbdf30eb02993786a017e5b974fa17b03ffb88069f40f6a3ec7b5a425c3870c8f557ffff3d5fe76a3d2f66c91aa6b3a12e77771c67f378774057e5556ee49719608bf55662386f26fc100007f9115d61d3c12f46a36c5d7a0a983a82a7186e72351f5e78acc421865bd29de09556e185d5d1bd45d5bdd1854195c9a5bd9608a1b600052620151807f9716bf7f646bde467b91bc5ee35192843e88e44c4a0a2ed2d4db490e5f884ade556040805180820190915260138152724d617070696e67546f6b656e466163746f727960681b9101527f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8667f9a194e7db753ec1c91747526d41864b25c8c8a85e075a96ced4311634bc477f3610fcd613579565b30604051602001610fe19493929190615458565b60408051601f1981840301815291905280516020909101206067556110078484846122e3565b7f256712d9a452971d973a82f7286706252d44486ae468cf5903694b1581a07fed60405180602001611038906143a4565b6020820181038252601f19601f82011660405250805190602001206040516110609190615404565b60405180910390a150505050565b60408051600280825260608281019093526000929190816020015b60608152602001906001900390816110895790505090506110a98461357d565b816000815181106110b657fe5b60200260200101819052506110ca836135a7565b816001815181106110d757fe5b60200260200101819052506110eb816135ba565b8051602090910120949350505050565b60675481565b606081518351146111245760405162461bcd60e51b8152600401610d51906157d9565b82516001600160401b038111801561113b57600080fd5b50604051908082528060200260200182016040528015611165578160200160208202803683370190505b50905060005b83518110156111c3576111a484828151811061118357fe5b602002602001015184838151811061119757fe5b602002602001015161226c565b8282815181106111b057fe5b602090810291909101015260010161116b565b5092915050565b606f6020908152600092835260408084209091529082529020546001600160a01b031681565b606d6020526000908152604090205481565b606081518351146112255760405162461bcd60e51b8152600401610d51906157d9565b82516001600160401b038111801561123c57600080fd5b50604051908082528060200260200182016040528015611266578160200160208202803683370190505b50905060005b83518110156111c3576112a584828151811061128457fe5b602002602001015184838151811061129857fe5b6020026020010151611b01565b8282815181106112b157fe5b602090810291909101015260010161126c565b6001600160a01b03161860009081526066602052604090205490565b606b6020908152600092835260408084209091529082529020546001600160a01b031681565b6065546000906001600160a01b0316331461132057600080fd5b61132f888888888888886135dd565b98975050505050505050565b6065546001600160a01b0316331461135257600080fd5b6001600160a01b0383166113c85760666020527f9115d61d3c12f46a36c5d7a0a983a82a7186e72351f5e78acc421865bd29de098290556e185d5d1bd45d5bdd1854195c9a5bd9608a1b6000527f9716bf7f646bde467b91bc5ee35192843e88e44c4a0a2ed2d4db490e5f884ade819055610af0565b604051637a4c780160e01b81526001600160a01b03841690637a4c7801906113f690859085906004016159d6565b600060405180830381600087803b15801561141057600080fd5b505af1158015611424573d6000803e3d6000fd5b50505050505050565b6065546001600160a01b0316331461144457600080fd5b61144c613579565b60011480611461575061145d613579565b6003145b61147d5760405162461bcd60e51b8152600401610d51906155ab565b61148682611842565b6114a25760405162461bcd60e51b8152600401610d5190615837565b6071836040516114b29190615106565b9081526020016040518091039020546000146114e05760405162461bcd60e51b8152600401610d51906158dc565b6114e8613579565b82141561159057806001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561152857600080fd5b505afa15801561153c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115649190810190614be9565b805190602001208380519060200120146115905760405162461bcd60e51b8152600401610d51906156cd565b806001600160a01b031660a083901b176071846040516115b09190615106565b9081526040516020918190038201902091909155607280546001810182556000919091528451611607927fdffbd64cc7c1a7eb27984335d9416d51137a03d3fabec7141025c62663253fe1909201918601906143b1565b50806001600160a01b031682846040516116219190615106565b604051908190038120907ff66e0ffd7bef94cf71780cd72520192d584667975baec0a28f68fc5ac01ee65390600090a4505050565b60725490565b6060606c600061166a613441565b6001600160a01b0316815260208101919091526040016000205460ff166116a35760405162461bcd60e51b8152600401610d51906155e2565b60405163512ebe4360e11b81526001600160a01b0385169063a25d7c86906116d19086908690600401615313565b600060405180830381600087803b1580156116eb57600080fd5b505af11580156116ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117279190810190614a6b565b905060005b83518110156117d45783818151811061174157fe5b60200260200101516001600160a01b0316856001600160a01b0316611764613441565b6001600160a01b03167f50215eaf403f70a465a98e402722c2751bdc09c31a6c24993bebe52b36b4c35986858151811061179a57fe5b60200260200101518686815181106117ae57fe5b60200260200101516040516117c49291906159d6565b60405180910390a460010161172c565b509392505050565b60705490565b7fab14dd152d2c116f23ca08cf0d9593a79931b31ec240371035e65929660de44281565b6065546001600160a01b0316331461181d57600080fd5b61182984848484613806565b50505050565b1860009081526066602052604090205490565b6000805b61184e6117dc565b81101561188657826070828154811061186357fe5b9060005260206000200154141561187e576001915050610b5e565b600101611846565b50600092915050565b60009081526066602052604090205490565b60608060606072805480602002602001604051908101604052809291908181526020016000905b828210156119735760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561195f5780601f106119345761010080835404028352916020019161195f565b820191906000526020600020905b81548152906001019060200180831161194257829003601f168201915b5050505050815260200190600101906118c8565b5050607254929550829150506001600160401b038111801561199457600080fd5b506040519080825280602002602001820160405280156119be578160200160208202803683370190505b509250806001600160401b03811180156119d757600080fd5b50604051908082528060200260200182016040528015611a01578160200160208202803683370190505b50915060005b81811015611afa57611ab760728281548110611a1f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611aad5780601f10611a8257610100808354040283529160200191611aad565b820191906000526020600020905b815481529060010190602001808311611a9057829003601f168201915b50505050506132ac565b858381518110611ac357fe5b60200260200101858481518110611ad657fe5b6001600160a01b039093166020938402919091019092019190915252600101611a07565b5050909192565b6000606c6000611b0f613441565b6001600160a01b0316815260208101919091526040016000205460ff16611b485760405162461bcd60e51b8152600401610d51906155e2565b6001600160a01b0383166000908152606d6020526040902054611b6b9083613aa9565b6001600160a01b0384166000818152606d60205260409020829055909150611b91613441565b6001600160a01b03167f368febfff609c2b53c67197b95ab76e156c79bac1f9a83ea429cddad4861c1088484604051611bcb9291906159d6565b60405180910390a392915050565b6a3332b2a932b3b4b9ba32b960a91b60005260666020527fcb09fe4fbe012b91e8122a356e75d6ebd9689d95739d160b534385000acfae3854611c1b90613ace565b6b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f82833981519152541580611c705750611c5b611c55613441565b8561106e565b6001600160a01b0316856001600160a01b0316145b611c8c5760405162461bcd60e51b8152600401610d5190615810565b8051611ca76c6d696e5369676e61747572657360981b61188f565b811015611cc65760405162461bcd60e51b8152600401610d519061557f565b60005b81811015611fa25760005b81811015611d4457838181518110611ce857fe5b6020026020010151600001516001600160a01b0316848381518110611d0957fe5b6020026020010151600001516001600160a01b03161415611d3c5760405162461bcd60e51b8152600401610d5190615668565b600101611cd4565b5060007fab14dd152d2c116f23ca08cf0d9593a79931b31ec240371035e65929660de442898988604051602001611d7b91906150dc565b6040516020818303038152906040528051906020012088604051602001611da2919061509d565b60405160208183030381529060405280519060200120888781518110611dc457fe5b602002602001015160000151604051602001611de59695949392919061547c565b604051602081830303815290604052805190602001209050600060675482604051602001611e14929190615122565b6040516020818303038152906040528051906020012090506000600182878681518110611e3d57fe5b602002602001015160200151888781518110611e5557fe5b602002602001015160400151898881518110611e6d57fe5b60200260200101516060015160405160008152602001604052604051611e9694939291906154b0565b6020604051602081039080840390855afa158015611eb8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611eeb5760405162461bcd60e51b8152600401610d5190615554565b858481518110611ef757fe5b6020026020010151600001516001600160a01b0316816001600160a01b031614611f335760405162461bcd60e51b8152600401610d5190615765565b611f55868581518110611f4257fe5b6020026020010151600001516001613bcf565b50806001600160a01b03168a6001600160a01b03168c7f60ba43d13fb1673027b408104ce0f140ce5da24f7f56ceef35d553285ca38be760405160405180910390a4505050600101611cc9565b5061142487878686613806565b6060806000611fbd8461224c565b9150506001600160a01b038116611fd15750825b6000805b611fdd6117dc565b811015612046576001600160a01b0383166000908152606f60205260408120607080548391908590811061200d57fe5b600091825260208083209091015483528201929092526040019020546001600160a01b03161461203e576001909101905b600101611fd5565b50806001600160401b038111801561205d57600080fd5b50604051908082528060200260200182016040528015612087578160200160208202803683370190505b509350806001600160401b03811180156120a057600080fd5b506040519080825280602002602001820160405280156120ca578160200160208202803683370190505b5092506000805b6120d96117dc565b811015612177576000607082815481106120ef57fe5b60009182526020808320909101546001600160a01b038089168452606f83526040808520838652909352919092205491925016801561216d578188858151811061213557fe5b6020026020010181815250508087858151811061214e57fe5b6001600160a01b03909216602092830291909101909101526001909301925b50506001016120d1565b50505050915091565b6065546001600160a01b0316331461219757600080fd5b6001600160a01b0382166000818152606c6020526040808220805460ff191685151590811790915590519092917fa59b1fd27aedbbb7212d6bf736c8f4cc41f5a3f97eb7edc6820c59c0ec9e553491a35050565b6065546001600160a01b0316331461220257600080fd5b6065546040516000916001600160a01b0316907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908390a3606580546001600160a01b0319169055565b6001600160a01b03166000908152606e602052604090205460a081901c91565b6000606c600061227a613441565b6001600160a01b0316815260208101919091526040016000205460ff166122b35760405162461bcd60e51b8152600401610d51906155e2565b506001600160a01b0382166000908152606d6020526040902054818110156122d9578091505b610be88383613bcf565b6065546001600160a01b031633146122fa57600080fd5b60686020527fc23ad3b8698fdd56cdfe9f7feef345bbc2ef01abc106afb48c4d9ac42cc7bae580546001600160a01b039485166001600160a01b0319918216179091557f15e5ff6e3c2b1d92344ca120709b0f1445ed661c8c399a859311ae0e7b8680ec8054938516938216939093179092556b26b0b83834b733aa37b5b2b760a11b6000527f11d58bfb56a1e79cb4d1fe24b6dd2edf7727005640478b994158cc2367c1aad98054919093169116179055565b6060606c60006123bc613441565b6001600160a01b0316815260208101919091526040016000205460ff166123f55760405162461bcd60e51b8152600401610d51906155e2565b612400848484613445565b949350505050565b6065546001600160a01b0316331461241f57600080fd5b61242b6073838361442f565b507f6a924554e8880f5ab8a47263c81ea1dc06992d445d689eda474f16d29aeddb88828260405161245d9291906152c5565b60405180910390a15050565b6065546000906001600160a01b0316612480613441565b6001600160a01b0316146124bc576866656543726561746560b81b6000526066602052600080516020615f62833981519152546124bc90613ace565b6000606a816124c9613441565b6001600160a01b03908116825260208201929092526040016000205416146125035760405162461bcd60e51b8152600401610d519061551d565b600061250d613579565b612515613441565b604051602001612526929190615175565b604051602081830303815290604052805190602001209050606060405180602001612550906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59250826001600160a01b03166374845865306c26b0b83830b13632aa37b5b2b760991b3061259c613441565b8c8c8c8c6040516024016125b5969594939291906151c3565b60408051601f198184030181529181526020820180516001600160e01b0316636fb9aeb160e11b1790525160e085901b6001600160e01b03191681526126009392919060040161521a565b600060405180830381600087803b15801561261a57600080fd5b505af115801561262e573d6000803e3d6000fd5b5050505082606a600061263f613441565b6001600160a01b039081168252602082019290925260400160002080546001600160a01b0319169290911691909117905561267a8385613c52565b826001600160a01b031661268c613441565b6001600160a01b03167fbd604b121560cfb19ff3df52b010ee7b1601535937fedb6d59c6100fedca2a14898989896040516126ca94939291906154e1565b60405180910390a35050949350505050565b6000606c60006126ea613441565b6001600160a01b0316815260208101919091526040016000205460ff166127235760405162461bcd60e51b8152600401610d51906155e2565b604051633d317ae360e11b81526001600160a01b03851690637a62f5c6906127519086908690600401615241565b602060405180830381600087803b15801561276b57600080fd5b505af115801561277f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a39190614d2c565b9050826001600160a01b0316846001600160a01b03166127c1613441565b6001600160a01b03167f547d6e3483177f508eaa5e1b421336afb2a25e2ccd1e7698dfa1ce909a1ea17485856040516127fb9291906159d6565b60405180910390a49392505050565b606c6020526000908152604090205460ff1681565b6065546001600160a01b0316331461283657600080fd5b610af08383188261341a565b6065546001600160a01b0316331461285957600080fd5b61286281613d8c565b50565b6069602052600090815260409020546001600160a01b031681565b6000308383604051602001612896929190615175565b60405160208183030381529060405280519060200120604051806020016128bc906143a4565b6020820181038252601f19601f82011660405250805190602001206040516020016128e99392919061513d565b60408051601f1981840301815291905280516020909101209392505050565b600054610100900460ff16806129215750612921613dfb565b8061292f575060005460ff16155b61294b5760405162461bcd60e51b8152600401610d519061578b565b600054610100900460ff16158015612976576000805460ff1961ff0019909116610100171660011790555b61297f866131da565b61298b85858585610de3565b801561299d576000805461ff00191690555b505050505050565b607381815481106129b257fe5b6000918252602090912001546001600160a01b0316905081565b6060610b5b6073805480602002602001604051908101604052809291908181526020018280548015612a2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a09575b505050505083611101565b6065546000906001600160a01b0316612a49613441565b6001600160a01b031614612af6576866656543726561746560b81b6000526066602052600080516020615f6283398151915254612a8590613ace565b6b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f82833981519152541580612ada5750612ac5612abf613441565b8361106e565b6001600160a01b0316836001600160a01b0316145b612af65760405162461bcd60e51b8152600401610d5190615810565b6001600160a01b038381166000908152606960205260409020541615612b2e5760405162461bcd60e51b8152600401610d519061586e565b6000612b38613579565b84604051602001612b4a929190615175565b604051602081830303815290604052805190602001209050606060405180602001612b74906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59250826001600160a01b03166374845865306a151bdad95b93585c1c195960aa1b3089604051602401612bc89291906151a9565b60408051601f198184030181529181526020820180516001600160e01b0316631b86b05760e11b1790525160e085901b6001600160e01b0319168152612c139392919060040161521a565b600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050506001600160a01b0385811660008181526069602090815260409182902080546001600160a01b0319169488169490941790935580516318160ddd60e01b81529051612ceb938793926318160ddd9260048083019392829003018186803b158015612cae57600080fd5b505afa158015612cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce69190614d2c565b613c52565b826001600160a01b0316856001600160a01b0316612d07613441565b6001600160a01b03167fc22552ea26b050ed8e679b7aa21b813b9962cae2a3ca57b0b1e5b83845a3f16360405160405180910390a4505092915050565b6866656543726561746560b81b60009081526066602052600080516020615f6283398151915254612d7490613ace565b6001600160a01b0388161580612daf57506b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f8283398151915254155b80612ddb5750612dc6612dc0613441565b8861106e565b6001600160a01b0316886001600160a01b0316145b612df75760405162461bcd60e51b8152600401610d5190615810565b6c6d696e5369676e61747572657360981b60005260666020527fbdf30eb02993786a017e5b974fa17b03ffb88069f40f6a3ec7b5a425c3870c8f5482511015612e525760405162461bcd60e51b8152600401610d519061557f565b60005b825181101561310b5760005b81811015612ed157838181518110612e7557fe5b6020026020010151600001516001600160a01b0316848381518110612e9657fe5b6020026020010151600001516001600160a01b03161415612ec95760405162461bcd60e51b8152600401610d5190615668565b600101612e61565b5060007f33a010203279ba8cdbc561bf3370b2ec1e054ec371ce4e4b8320d9446adc3f0b612efd613441565b8c8c8b805190602001208b805190602001208b8b8b8a81518110612f1d57fe5b602002602001015160000151604051602001612f419998979695949392919061540d565b60405160208183030381529060405280519060200120905060675481604051602001612f6e929190615122565b6040516020818303038152906040528051906020012090506000600182868581518110612f9757fe5b602002602001015160200151878681518110612faf57fe5b602002602001015160400151888781518110612fc757fe5b60200260200101516060015160405160008152602001604052604051612ff094939291906154b0565b6020604051602081039080840390855afa158015613012573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166130455760405162461bcd60e51b8152600401610d5190615554565b84838151811061305157fe5b6020026020010151600001516001600160a01b0316816001600160a01b03161461308d5760405162461bcd60e51b8152600401610d5190615765565b61309c858481518110611f4257fe5b50806001600160a01b03166130af613441565b6001600160a01b03168c6001600160a01b03167f616aa5044dcfe1a7d2a8757dedc57f78a23826b7fdf81436d5f0470e950e49c58f8d8d8d8d6040516130f9959493929190615993565b60405180910390a45050600101612e55565b506131228989613119613441565b898989896135dd565b9998505050505050505050565b6065546001600160a01b0316331461314657600080fd5b61314e613579565b60011480613163575061315f613579565b6003145b61317f5760405162461bcd60e51b8152600401610d51906155ab565b61318881611842565b156131a55760405162461bcd60e51b8152600401610d51906158a5565b607080546001810182556000919091527f8f6b23ffa15f0465e3176e15ca644cf24f86dc1312fe715484e3c4aead5eb78b0155565b600054610100900460ff16806131f357506131f3613dfb565b80613201575060005460ff16155b61321d5760405162461bcd60e51b8152600401610d519061578b565b600054610100900460ff16158015613248576000805460ff1961ff0019909116610100171660011790555b606580546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908290a38015610d06576000805461ff00191690555050565b60008060006071846040516132c19190615106565b9081526040519081900360200190205460a081901c9590945092505050565b6000606c60006132ee613441565b6001600160a01b0316815260208101919091526040016000205460ff166133275760405162461bcd60e51b8152600401610d51906155e2565b604051636489aba560e01b81526001600160a01b03851690636489aba5906133559086908690600401615241565b602060405180830381600087803b15801561336f57600080fd5b505af1158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d2c565b9050826001600160a01b0316846001600160a01b03166133c5613441565b6001600160a01b03167f50215eaf403f70a465a98e402722c2751bdc09c31a6c24993bebe52b36b4c35985856040516127fb9291906159d6565b606a602052600090815260409020546001600160a01b031681565b6000828152606660205260409020548114610d065760009182526066602052604090912055565b3390565b6040516307a1b0ab60e21b81526060906001600160a01b03851690631e86c2ac906134769086908690600401615313565b600060405180830381600087803b15801561349057600080fd5b505af11580156134a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134cc9190810190614a6b565b905060005b83518110156117d4578381815181106134e657fe5b60200260200101516001600160a01b0316856001600160a01b0316613509613441565b6001600160a01b03167f547d6e3483177f508eaa5e1b421336afb2a25e2ccd1e7698dfa1ce909a1ea17486858151811061353f57fe5b602002602001015186868151811061355357fe5b60200260200101516040516135699291906159d6565b60405180910390a46001016134d1565b4690565b60408051600560a21b83186014820152603481019091526060906135a081613e01565b9392505050565b6060610b5b6135b583613e4b565b613e01565b6060806135c683613f53565b90506135a06135d7825160c0614053565b826141ac565b6000806001600160a01b038816156135f557876135f7565b865b60008a8152606b602090815260408083206001600160a01b038086168552925290912054919250161561363c5760405162461bcd60e51b8152600401610d5190615696565b60008982604051602001613651929190615175565b60405160208183030381529060405280519060200120905060606040518060200161367b906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59350836001600160a01b03166374845865306b26b0b83834b733aa37b5b2b760a11b308f8f8f8f8f8f8f6040516024016136dc98979695949392919061525a565b60408051601f198184030181529181526020820180516001600160e01b03166337addc7560e11b1790525160e085901b6001600160e01b03191681526137279392919060040161521a565b600060405180830381600087803b15801561374157600080fd5b505af1158015613755573d6000803e3d6000fd5b50505060008c8152606b602090815260408083206001600160a01b038881168552925290912080546001600160a01b0319169187169190911790555061379b8486613c52565b836001600160a01b0316896001600160a01b03168b6001600160a01b03167f66e6dab65de642df4a6afb3a99e6b803d1520d0a7d5ffdf10b88cdaaf0c5b9988e8c8c8c8c6040516137f0959493929190615993565b60405180910390a4505050979650505050505050565b61380e613579565b60011480613823575061381f613579565b6003145b61383f5760405162461bcd60e51b8152600401610d51906155ab565b80518251146138605760405162461bcd60e51b8152600401610d51906157d9565b61386984611842565b6138855760405162461bcd60e51b8152600401610d5190615837565b60005b8251811015613aa2576138ad8382815181106138a057fe5b6020026020010151611842565b6138c95760405162461bcd60e51b8152600401610d51906156f7565b8181815181106138d557fe5b60200260200101516001600160a01b0316846001600160a01b0316148061392957506139018585612880565b6001600160a01b031682828151811061391657fe5b60200260200101516001600160a01b0316145b8061394e57506065546001600160a01b0316613943613441565b6001600160a01b0316145b61396a5760405162461bcd60e51b8152600401610d5190615913565b836001600160a01b031660a086901b17606e600084848151811061398a57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508181815181106139c257fe5b6020026020010151606f6000866001600160a01b03166001600160a01b0316815260200190815260200160002060008584815181106139fd57fe5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f2bb569421de23a5bd9d854dff71796f10e7973da0031747b01da9c41ea4f5c838585858481518110613a6657fe5b6020026020010151858581518110613a7a57fe5b6020026020010151604051613a92949392919061596c565b60405180910390a1600101613888565b5050505050565b600082820183811015610be85760405162461bcd60e51b8152600401610d5190615609565b613ae081670de0b6b3a7640000614229565b341015613aff5760405162461bcd60e51b8152600401610d5190615640565b64666565546f60d81b60005260666020527f729bca52a6d55a36cde7d479eb9228d7df8a69b2e9ca2a9c0b17e052244a1e17546001600160a01b038116613b435750305b6040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015613b78573d6000803e3d6000fd5b50806001600160a01b0316613b8b613441565b6001600160a01b03167fc0d39cf3434f9dede81e427dbbccd901073df1b746711cb6cb7db1b27ddd692734604051613bc39190615404565b60405180910390a35050565b6001600160a01b0382166000908152606d6020526040812054613bf2908361423f565b6001600160a01b0384166000818152606d60205260409020829055909150613c18613441565b6001600160a01b03167ffb81f5e07d16a904d08894e41cac92dd304a5bc82d13f8030f67df1e7a71f2238484604051611bcb9291906159d6565b6d696e697451756f7461526174696f60901b600090815260666020527ffff3d5fe76a3d2f66c91aa6b3a12e77771c67f378774057e5556ee49719608bf54613caf90670de0b6b3a764000090613ca9908590614281565b906142bb565b6073549091506060906001600160401b0381118015613ccd57600080fd5b50604051908082528060200260200182016040528015613cf7578160200160208202803683370190505b50905060005b8151811015613d265782828281518110613d1357fe5b6020908102919091010152600101613cfd565b50613aa2846073805480602002602001604051908101604052809291908181526020018280548015613d8157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d63575b505050505083613445565b6001600160a01b038116613d9f57600080fd5b6065546040516001600160a01b038084169216907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b303b1590565b60608082516001148015613e2a5750608083600081518110613e1f57fe5b016020015160f81c11155b15613e36575081610b5b565b610be8613e4584516080614053565b846141ac565b60408051602080825281830190925260609182919060208201818036833701905050905082602082015260005b6020811015613eae57818181518110613e8d57fe5b01602001516001600160f81b03191615613ea657613eae565b600101613e78565b6060816020036001600160401b0381118015613ec957600080fd5b506040519080825280601f01601f191660200182016040528015613ef4576020820181803683370190505b50905060005b8151811015613f4a578351600184019385918110613f1457fe5b602001015160f81c60f81b828281518110613f2b57fe5b60200101906001600160f81b031916908160001a905350600101613efa565b50949350505050565b6060815160001415613f745750604080516000815260208101909152610b5e565b6000805b8351811015613fa757838181518110613f8d57fe5b602002602001015151820191508080600101915050613f78565b6060826001600160401b0381118015613fbf57600080fd5b506040519080825280601f01601f191660200182016040528015613fea576020820181803683370190505b50600092509050602081015b8551831015613f4a57606086848151811061400d57fe5b60200260200101519050600060208201905061402b838284516142fd565b87858151811061403757fe5b6020026020010151518301925050508280600101935050613ff6565b60608060388410156140b05760408051600180825281830190925290602082018180368337019050509050838301601f1a60f81b8160008151811061409457fe5b60200101906001600160f81b031916908160001a905350610be8565b600060015b8086816140be57fe5b04156140d357600190910190610100026140b5565b816001016001600160401b03811180156140ec57600080fd5b506040519080825280601f01601f191660200182016040528015614117576020820181803683370190505b509250603782860101601f1a60f81b8360008151811061413357fe5b60200101906001600160f81b031916908160001a905350600190505b8181116141a2576101008183036101000a878161416857fe5b048161417057fe5b06601f1a60f81b83828151811061418357fe5b60200101906001600160f81b031916908160001a90535060010161414f565b5050905092915050565b6060806040519050835180825260208201818101602087015b818310156141dd5780518352602092830192016141c5565b50855184518101855292509050808201602086015b8183101561420a5780518352602092830192016141f2565b508651929092011591909101601f01601f191660405250905092915050565b60008183106142385781610be8565b5090919050565b6000610be883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614341565b60008261429057506000610beb565b8282028284828161429d57fe5b0414610be85760405162461bcd60e51b8152600401610d5190615724565b6000610be883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061436d565b8282825b60208110614320578151835260209283019290910190601f1901614301565b905182516020929092036101000a6000190180199091169116179052505050565b600081848411156143655760405162461bcd60e51b8152600401610d5191906154ce565b505050900390565b6000818361438e5760405162461bcd60e51b8152600401610d5191906154ce565b50600083858161439a57fe5b0495945050505050565b6104d480615a8e83390190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106143f257805160ff191683800117855561441f565b8280016001018555821561441f579182015b8281111561441f578251825591602001919060010190614404565b5061442b92915061448e565b5090565b828054828255906000526020600020908101928215614482579160200282015b828111156144825781546001600160a01b0319166001600160a01b0384351617825560209092019160019091019061444f565b5061442b9291506144a3565b5b8082111561442b576000815560010161448f565b5b8082111561442b5780546001600160a01b03191681556001016144a4565b80356001600160a01b0381168114610beb57600080fd5b600082601f8301126144e9578081fd5b81356144fc6144f782615a0a565b6159e4565b81815291506020808301908481018184028601820187101561451d57600080fd5b60005b848110156145445761453288836144c2565b84529282019290820190600101614520565b505050505092915050565b600082601f83011261455f578081fd5b813561456d6144f782615a0a565b818152915060208083019084810160808085028701830188101561459057600080fd5b6000805b868110156145f55782848b0312156145aa578182fd5b6145b3836159e4565b6145bd8b866144c2565b81526145cb8b8787016146ae565b81870152604085810135908201526060808601359082015286529484019492820192600101614594565b5050505050505092915050565b600082601f830112614612578081fd5b81356146206144f782615a0a565b81815291506020808301908481018184028601820187101561464157600080fd5b60005b8481101561454457813584529282019290820190600101614644565b600082601f830112614670578081fd5b813561467e6144f782615a29565b915080825283602082850101111561469557600080fd5b8060208401602084013760009082016020015292915050565b803560ff81168114610beb57600080fd5b6000602082840312156146d0578081fd5b610be883836144c2565b6000806000606084860312156146ee578182fd5b6146f885856144c2565b925061470785602086016144c2565b915061471685604086016144c2565b90509250925092565b60008060008060808587031215614734578081fd5b61473e86866144c2565b935061474d86602087016144c2565b925061475c86604087016144c2565b915061476b86606087016144c2565b905092959194509250565b600080600080600060a0868803121561478d578081fd5b61479787876144c2565b94506147a687602088016144c2565b93506147b587604088016144c2565b92506147c487606088016144c2565b91506147d387608088016144c2565b90509295509295909350565b6000806000606084860312156147f3578283fd5b83356147fe81615a78565b9250602084013561480e81615a78565b929592945050506040919091013590565b600080600060608486031215614833578081fd5b833561483e81615a78565b925060208401356001600160401b0380821115614859578283fd5b614865878388016144d9565b9350604086013591508082111561487a578283fd5b5061488786828701614602565b9150509250925092565b600080604083850312156148a3578182fd5b6148ad84846144c2565b915060208301356001600160401b038111156148c7578182fd5b6148d385828601614602565b9150509250929050565b600080604083850312156148ef578182fd5b6148f984846144c2565b91506020830135801515811461490d578182fd5b809150509250929050565b6000806040838503121561492a578182fd5b61493484846144c2565b946020939093013593505050565b600080600060608486031215614956578081fd5b61496085856144c2565b95602085013595506040909401359392505050565b60008060208385031215614987578182fd5b82356001600160401b038082111561499d578384fd5b818501915085601f8301126149b0578384fd5b8135818111156149be578485fd5b86602080830285010111156149d1578485fd5b60209290920196919550909350505050565b600080604083850312156149f5578182fd5b82356001600160401b0380821115614a0b578384fd5b614a17868387016144d9565b93506020850135915080821115614a2c578283fd5b506148d385828601614602565b600060208284031215614a4a578081fd5b81356001600160401b03811115614a5f578182fd5b61240084828501614602565b60006020808385031215614a7d578182fd5b82516001600160401b03811115614a92578283fd5b8301601f81018513614aa2578283fd5b8051614ab06144f782615a0a565b8181528381019083850185840285018601891015614acc578687fd5b8694505b83851015614aee578051835260019490940193918501918501614ad0565b50979650505050505050565b600060208284031215614b0b578081fd5b5035919050565b60008060408385031215614b24578182fd5b82359150602083013561490d81615a78565b600080600060608486031215614b4a578081fd5b83359250614b5b85602086016144c2565b9150604084013590509250925092565b60008060408385031215614b7d578182fd5b50508035926020909101359150565b600080600060608486031215614ba0578081fd5b505081359360208301359350604090920135919050565b600060208284031215614bc8578081fd5b81356001600160401b03811115614bdd578182fd5b61240084828501614660565b600060208284031215614bfa578081fd5b81516001600160401b03811115614c0f578182fd5b8201601f81018413614c1f578182fd5b8051614c2d6144f782615a29565b818152856020838501011115614c41578384fd5b614c52826020830160208601615a4c565b95945050505050565b60008060008060808587031215614c70578182fd5b84356001600160401b0380821115614c86578384fd5b614c9288838901614660565b95506020870135915080821115614ca7578384fd5b50614cb487828801614660565b935050614cc486604087016146ae565b9396929550929360600135925050565b600080600060608486031215614ce8578081fd5b83356001600160401b03811115614cfd578182fd5b614d0986828701614660565b935050602084013591506040840135614d2181615a78565b809150509250925092565b600060208284031215614d3d578081fd5b5051919050565b60008060408385031215614d56578182fd5b82359150614d6784602085016144c2565b90509250929050565b600080600080600080600060e0888a031215614d8a578485fd5b87359650614d9b8960208a016144c2565b9550614daa8960408a016144c2565b945060608801356001600160401b0380821115614dc5578384fd5b614dd18b838c01614660565b955060808a0135915080821115614de6578384fd5b50614df38a828b01614660565b935050614e038960a08a016146ae565b915060c0880135905092959891949750929550565b60008060008060808587031215614e2d578182fd5b843593506020850135614e3f81615a78565b925060408501356001600160401b0380821115614e5a578384fd5b614e6688838901614602565b93506060870135915080821115614e7b578283fd5b50614e88878288016144d9565b91505092959194509250565b60008060008060008060c08789031215614eac578384fd5b86359550614ebd88602089016144c2565b94506040870135935060608701356001600160401b0380821115614edf578384fd5b614eeb8a838b01614602565b94506080890135915080821115614f00578384fd5b614f0c8a838b016144d9565b935060a0890135915080821115614f21578283fd5b50614f2e89828a0161454f565b9150509295509295509295565b600080600080600080600080610100898b031215614f57578182fd5b88359750614f688a60208b016144c2565b96506040890135955060608901356001600160401b0380821115614f8a578384fd5b614f968c838d01614660565b965060808b0135915080821115614fab578384fd5b614fb78c838d01614660565b9550614fc68c60a08d016146ae565b945060c08b0135935060e08b0135915080821115614fe2578283fd5b50614fef8b828c0161454f565b9150509295985092959890939650565b6000815180845260208085019450808401835b838110156150375781516001600160a01b031687529582019590820190600101615012565b509495945050505050565b6000815180845260208085019450808401835b8381101561503757815187529582019590820190600101615055565b60008151808452615089816020860160208601615a4c565b601f01601f19169290920160200192915050565b815160009082906020808601845b838110156150d05781516001600160a01b0316855293820193908201906001016150ab565b50929695505050505050565b815160009082906020808601845b838110156150d0578151855293820193908201906001016150ea565b60008251615118818460208701615a4c565b9190910192915050565b61190160f01b81526002810192909252602282015260420190565b6001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b91825260601b6bffffffffffffffffffffffff1916602082015260340190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0387811682528616602082015260c0604082018190526000906151ef90830187615071565b82810360608401526152018187615071565b60ff959095166080840152505060a00152949350505050565b600060018060a01b038516825283602083015260606040830152614c526060830184615071565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038981168252602082018990528781166040830152861660608201526101006080820181905260009061529683820188615071565b905082810360a08401526152aa8187615071565b60ff9590951660c0840152505060e001529695505050505050565b60208082528181018390526000908460408401835b86811015615308578284016001600160a01b036152f782866144c2565b1683529250908301906001016152da565b509695505050505050565b6000604082526153266040830185614fff565b8281036020840152614c528185615042565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561538d57607f1988840301855261537b838351615071565b9486019492509085019060010161535f565b5050858103848701526153a08189615042565b935050505082810360408401526153b78185614fff565b9695505050505050565b600060208252610be86020830184615042565b6000604082526153e76040830185615042565b8281036020840152614c528185614fff565b901515815260200190565b90815260200190565b9889526001600160a01b0397881660208a015260408901969096529386166060880152608087019290925260a086015260ff1660c085015260e0840152166101008201526101200190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b95865260208601949094526001600160a01b039283166040860152606085019190915260808401521660a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610be86020830184615071565b6000608082526154f46080830187615071565b82810360208401526155068187615071565b60ff95909516604084015250506060015292915050565b6020808252601d908201527f4d61707061626c65546f6b656e206372656174656420616c7265616479000000604082015260600190565b602080825260119082015270696e76616c6964207369676e617475726560781b604082015260600190565b602080825260129082015271746f6f20666577207369676e61747572657360701b604082015260600190565b6020808252601f908201527f63616c6c6564206f6e6c79206f6e20657468657265756d206d61696e6e657400604082015260600190565b6020808252600d908201526c6f6e6c7920617574686f72747960981b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600e908201526d66656520697320746f6f206c6f7760901b604082015260600190565b60208082526014908201527372657065746974697665207369676e61746f727960601b604082015260600190565b6020808252601c908201527f4d617070696e67546f6b656e206372656174656420616c726561647900000000604082015260600190565b60208082526010908201526f1cde5b589bdb08191a5999995c995b9d60821b604082015260600190565b602080825260139082015272139bdd081cdd5c1c1bdc9d0818da185a5b9259606a1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600c908201526b1d5b985d5d1a1bdc9a5e995960a21b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526019908201527f74776f206172726179206c656e7468206e6f7420657175616c00000000000000604082015260600190565b6020808252600d908201526c37b7363c903232b83637bcb2b960991b604082015260600190565b60208082526017908201527f4e6f7420737570706f7274206d61696e436861696e4964000000000000000000604082015260600190565b6020808252601b908201527f546f6b656e4d6170706564206372656174656420616c72656164790000000000604082015260600190565b60208082526017908201527f737570706f727420636861696e496420616c7265616479000000000000000000604082015260600190565b60208082526017908201527f43657274696669656420616464656420616c7265616479000000000000000000604082015260600190565b60208082526022908201527f696e76616c6964206d617070696e67546f6b656e4d6170706564206164647265604082015261737360f01b606082015260800190565b9182526001600160a01b0316602082015260400190565b9384526001600160a01b039283166020850152604084019190915216606082015260800190565b600086825260a060208301526159ac60a0830187615071565b82810360408401526159be8187615071565b60ff9590951660608401525050608001529392505050565b918252602082015260400190565b6040518181016001600160401b0381118282101715615a0257600080fd5b604052919050565b60006001600160401b03821115615a1f578081fd5b5060209081020190565b60006001600160401b03821115615a3e578081fd5b50601f01601f191660200190565b60005b83811015615a67578181015183820152602001615a4f565b838111156118295750506000910152565b6001600160a01b038116811461286257600080fdfe608060405234801561001057600080fd5b506104b4806100206000396000f3fe6080604052600436106100225760003560e01c8063748458651461003957610031565b366100315761002f61004c565b005b61002f61004c565b61002f6100473660046102f9565b610091565b6100553361013d565b801561005f575036155b801561006d57506108fc5a11155b156100775761008f565b61007f61008f565b61008f61008a610143565b6101f2565b565b600061009b610216565b6001600160a01b0316146100ae57600080fd5b6100b78361023b565b6100c08261028d565b8051156101385760006100d1610143565b6001600160a01b0316826040516100e891906103a3565b600060405180830381855af49150503d8060008114610123576040519150601f19603f3d011682016040523d82523d6000602084013e610128565b606091505b505090508061013657600080fd5b505b505050565b3b151590565b60008061014e610216565b90506101598161013d565b156101e957806001600160a01b0316630b2bcd676101756102b1565b6040518263ffffffff1660e01b815260040161019191906103dc565b60206040518083038186803b1580156101a957600080fd5b505afa1580156101bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e191906102d6565b9150506101ef565b60009150505b90565b3660008037600080366000845af43d6000803e808015610211573d6000f35b3d6000fd5b7f7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af15490565b6102448161013d565b6102695760405162461bcd60e51b8152600401610260906103e5565b60405180910390fd5b7f7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af155565b7f4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a87055565b7f4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a8705490565b6000602082840312156102e7578081fd5b81516102f281610466565b9392505050565b60008060006060848603121561030d578182fd5b833561031881610466565b925060208401359150604084013567ffffffffffffffff8082111561033b578283fd5b818601915086601f83011261034e578283fd5b81358181111561035c578384fd5b61036f601f8201601f1916602001610433565b9150808252876020828501011115610385578384fd5b61039681602084016020860161045a565b5080925050509250925092565b60008251815b818110156103c357602081860181015185830152016103a9565b818111156103d15782828501525b509190910192915050565b90815260200190565b6020808252602e908201527f43616e6e6f7420736574206120666163746f727920746f2061206e6f6e2d636f60408201526d6e7472616374206164647265737360901b606082015260800190565b60405181810167ffffffffffffffff8111828210171561045257600080fd5b604052919050565b82818337506000910152565b6001600160a01b038116811461047b57600080fd5b5056fea26469706673582212208a83372edb5bd000f176d79a4af74a92896277b28ec799186455f571b908f17164736f6c634300060c00330fd54b93a24feeadd1317d9ce59c55fc0e99641d75b0208a9b2f4b5a0050f08578d01a15a3eb58a539cbe421d51d17e63aef0af9ed019b297a979d8332710bada26469706673582212204bed37698494fa0eba930b7340d3d6f42c3a2216fe8e86a4468ffeb85e285db164736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061038c5760003560e01c80636d2f818f116101dc578063aa1f4bf011610102578063ce8c4720116100a0578063df69e0161161006f578063df69e01614610a44578063e6d3bba714610a64578063f0e4efbf14610a84578063feff4a4914610aa45761038c565b8063ce8c4720146109de578063d0dedd27146109fe578063d5e6241014610a11578063db8e81b014610a245761038c565b8063bc9f4700116100dc578063bc9f47001461095e578063c8b956d61461097e578063c8eb8cd41461099e578063cdb9df6b146109be5761038c565b8063aa1f4bf0146108fe578063ae58c3011461091e578063b6aa515b1461093e5761038c565b806381c0c2631161017a5780639d329768116101495780639d3297681461088b5780639f007e68146108ab578063a44eab97146108cb578063a4a637c4146108de5761038c565b806381c0c263146108085780638e8529001461081d57806394b3e8711461084b5780639987cec81461086b5761038c565b8063756dcd13116101b6578063756dcd13146107875780637a418494146107a75780637a47363b146107ba5780637c25e959146107e85761038c565b80636d2f818f146107165780636dd5b69d146107435780636ef6f248146107635761038c565b8063392f6788116102c15780635e48f7551161025f57806365976b221161022e57806365976b22146106ac5780636a5306a3146106c15780636a99cf33146106d65780636b02ba2e146106f65761038c565b80635e48f755146106375780635ef03f0214610657578063648c58441461067757806364cc0d641461068c5761038c565b806348864f551161029b57806348864f55146105c45780634c4043b4146105e45780634ecaecbb14610604578063507b7274146106245761038c565b8063392f6788146105645780633b6d8ebe146105845780633d0e4bc1146105a45761038c565b806311ba17411161032e57806320606b701161030857806320606b70146104fa5780632dcc7d231461050f5780633015cd791461052f5780633644e5151461054f5761038c565b806311ba1741146104a557806315fe96dc146104ba5780631ae83a3e146104da5761038c565b80630a9783971161036a5780630a978397146104165780630b2bcd67146104365780630c340a24146104635780630e6be7bd146104785761038c565b8063021ddb7f1461039157806305a424af146103b35780630a86b2ab146103e9575b600080fd5b34801561039d57600080fd5b506103b16103ac366004614b36565b610ac4565b005b3480156103bf57600080fd5b506103d36103ce366004614a39565b610af5565b6040516103e091906153c1565b60405180910390f35b3480156103f557600080fd5b50610409610404366004614afa565b610b63565b6040516103e09190615404565b34801561042257600080fd5b506103d3610431366004614891565b610b81565b34801561044257600080fd5b50610456610451366004614afa565b610bf1565b6040516103e09190615195565b34801561046f57600080fd5b50610456610c0c565b34801561048457600080fd5b50610498610493366004614afa565b610c1b565b6040516103e091906154ce565b3480156104b157600080fd5b50610409610cc1565b3480156104c657600080fd5b506103b16104d5366004614b6b565b610ce5565b3480156104e657600080fd5b506103d36104f5366004614891565b610d0a565b34801561050657600080fd5b50610409610dbf565b34801561051b57600080fd5b506103b161052a36600461471f565b610de3565b34801561053b57600080fd5b5061045661054a366004614918565b61106e565b34801561055b57600080fd5b506104096110fb565b34801561057057600080fd5b506103d361057f3660046149e3565b611101565b34801561059057600080fd5b5061045661059f366004614918565b6111ca565b3480156105b057600080fd5b506104096105bf3660046146bf565b6111f0565b3480156105d057600080fd5b506103d36105df3660046149e3565b611202565b3480156105f057600080fd5b506104096105ff366004614b12565b6112c4565b34801561061057600080fd5b5061045661061f366004614d44565b6112e0565b610456610632366004614d70565b611306565b34801561064357600080fd5b506103b1610652366004614942565b61133b565b34801561066357600080fd5b506103b1610672366004614cd4565b61142d565b34801561068357600080fd5b50610409611656565b34801561069857600080fd5b506103d36106a736600461481f565b61165c565b3480156106b857600080fd5b506104096117dc565b3480156106cd57600080fd5b506104096117e2565b3480156106e257600080fd5b506103b16106f1366004614e18565b611806565b34801561070257600080fd5b50610409610711366004614b6b565b61182f565b34801561072257600080fd5b50610736610731366004614afa565b611842565b6040516103e091906153f9565b34801561074f57600080fd5b5061040961075e366004614afa565b61188f565b34801561076f57600080fd5b506107786118a1565b6040516103e093929190615338565b34801561079357600080fd5b506104096107a2366004614918565b611b01565b6103b16107b5366004614e94565b611bd9565b3480156107c657600080fd5b506107da6107d53660046146bf565b611faf565b6040516103e09291906153d4565b3480156107f457600080fd5b506103b16108033660046148dd565b612180565b34801561081457600080fd5b506103b16121eb565b34801561082957600080fd5b5061083d6108383660046146bf565b61224c565b6040516103e0929190615955565b34801561085757600080fd5b50610409610866366004614918565b61226c565b34801561087757600080fd5b506103b16108863660046146da565b6122e3565b34801561089757600080fd5b506103d36108a636600461481f565b6123ae565b3480156108b757600080fd5b506103b16108c6366004614975565b612408565b6104566108d9366004614c5b565b612469565b3480156108ea57600080fd5b506104096108f93660046147df565b6126dc565b34801561090a57600080fd5b506107366109193660046146bf565b61280a565b34801561092a57600080fd5b506103b1610939366004614b8c565b61281f565b34801561094a57600080fd5b506103b16109593660046146bf565b612842565b34801561096a57600080fd5b506104566109793660046146bf565b612865565b34801561098a57600080fd5b50610456610999366004614d44565b612880565b3480156109aa57600080fd5b506103b16109b9366004614776565b612908565b3480156109ca57600080fd5b506104566109d9366004614afa565b6129a5565b3480156109ea57600080fd5b506103d36109f9366004614a39565b6129cc565b610456610a0c366004614918565b612a32565b610456610a1f366004614f3b565b612d44565b348015610a3057600080fd5b506103b1610a3f366004614afa565b61312f565b348015610a5057600080fd5b506103b1610a5f3660046146bf565b6131da565b348015610a7057600080fd5b5061083d610a7f366004614bb7565b6132ac565b348015610a9057600080fd5b50610409610a9f3660046147df565b6132e0565b348015610ab057600080fd5b50610456610abf3660046146bf565b6133ff565b6065546001600160a01b03163314610adb57600080fd5b610af06001600160a01b03831684188261341a565b505050565b6060610b5b6073805480602002602001604051908101604052809291908181526020018280548015610b5057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b32575b505050505083611202565b90505b919050565b60708181548110610b7057fe5b600091825260209091200154905081565b6060610be8836073805480602002602001604051908101604052809291908181526020018280548015610bdd57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610bbf575b50505050508461165c565b90505b92915050565b6068602052600090815260409020546001600160a01b031681565b6065546001600160a01b031681565b60728181548110610c2857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015610cb95780601f10610c8e57610100808354040283529160200191610cb9565b820191906000526020600020905b815481529060010190602001808311610c9c57829003601f168201915b505050505081565b7f33a010203279ba8cdbc561bf3370b2ec1e054ec371ce4e4b8320d9446adc3f0b81565b6065546001600160a01b03163314610cfc57600080fd5b610d06828261341a565b5050565b6060606c6000610d18613441565b6001600160a01b0316815260208101919091526040016000205460ff16610d5a5760405162461bcd60e51b8152600401610d51906155e2565b60405180910390fd5b610be8836073805480602002602001604051908101604052809291908181526020018280548015610db457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d96575b505050505084613445565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6065546001600160a01b03163314610dfa57600080fd5b606660209081526611c37937e080007f4c327380d902ed7da19f788f7335cc4d8c07e9fd6f343de3af9a1ada79b852425567016345785d8a0000600080516020615f628339815191528190556702c68af0bb1400007fcb09fe4fbe012b91e8122a356e75d6ebd9689d95739d160b534385000acfae38556001600160a01b0383167f729bca52a6d55a36cde7d479eb9228d7df8a69b2e9ca2a9c0b17e052244a1e17556001600080516020615f828339815191525560037fbdf30eb02993786a017e5b974fa17b03ffb88069f40f6a3ec7b5a425c3870c8f557ffff3d5fe76a3d2f66c91aa6b3a12e77771c67f378774057e5556ee49719608bf55662386f26fc100007f9115d61d3c12f46a36c5d7a0a983a82a7186e72351f5e78acc421865bd29de09556e185d5d1bd45d5bdd1854195c9a5bd9608a1b600052620151807f9716bf7f646bde467b91bc5ee35192843e88e44c4a0a2ed2d4db490e5f884ade556040805180820190915260138152724d617070696e67546f6b656e466163746f727960681b9101527f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8667f9a194e7db753ec1c91747526d41864b25c8c8a85e075a96ced4311634bc477f3610fcd613579565b30604051602001610fe19493929190615458565b60408051601f1981840301815291905280516020909101206067556110078484846122e3565b7f256712d9a452971d973a82f7286706252d44486ae468cf5903694b1581a07fed60405180602001611038906143a4565b6020820181038252601f19601f82011660405250805190602001206040516110609190615404565b60405180910390a150505050565b60408051600280825260608281019093526000929190816020015b60608152602001906001900390816110895790505090506110a98461357d565b816000815181106110b657fe5b60200260200101819052506110ca836135a7565b816001815181106110d757fe5b60200260200101819052506110eb816135ba565b8051602090910120949350505050565b60675481565b606081518351146111245760405162461bcd60e51b8152600401610d51906157d9565b82516001600160401b038111801561113b57600080fd5b50604051908082528060200260200182016040528015611165578160200160208202803683370190505b50905060005b83518110156111c3576111a484828151811061118357fe5b602002602001015184838151811061119757fe5b602002602001015161226c565b8282815181106111b057fe5b602090810291909101015260010161116b565b5092915050565b606f6020908152600092835260408084209091529082529020546001600160a01b031681565b606d6020526000908152604090205481565b606081518351146112255760405162461bcd60e51b8152600401610d51906157d9565b82516001600160401b038111801561123c57600080fd5b50604051908082528060200260200182016040528015611266578160200160208202803683370190505b50905060005b83518110156111c3576112a584828151811061128457fe5b602002602001015184838151811061129857fe5b6020026020010151611b01565b8282815181106112b157fe5b602090810291909101015260010161126c565b6001600160a01b03161860009081526066602052604090205490565b606b6020908152600092835260408084209091529082529020546001600160a01b031681565b6065546000906001600160a01b0316331461132057600080fd5b61132f888888888888886135dd565b98975050505050505050565b6065546001600160a01b0316331461135257600080fd5b6001600160a01b0383166113c85760666020527f9115d61d3c12f46a36c5d7a0a983a82a7186e72351f5e78acc421865bd29de098290556e185d5d1bd45d5bdd1854195c9a5bd9608a1b6000527f9716bf7f646bde467b91bc5ee35192843e88e44c4a0a2ed2d4db490e5f884ade819055610af0565b604051637a4c780160e01b81526001600160a01b03841690637a4c7801906113f690859085906004016159d6565b600060405180830381600087803b15801561141057600080fd5b505af1158015611424573d6000803e3d6000fd5b50505050505050565b6065546001600160a01b0316331461144457600080fd5b61144c613579565b60011480611461575061145d613579565b6003145b61147d5760405162461bcd60e51b8152600401610d51906155ab565b61148682611842565b6114a25760405162461bcd60e51b8152600401610d5190615837565b6071836040516114b29190615106565b9081526020016040518091039020546000146114e05760405162461bcd60e51b8152600401610d51906158dc565b6114e8613579565b82141561159057806001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561152857600080fd5b505afa15801561153c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115649190810190614be9565b805190602001208380519060200120146115905760405162461bcd60e51b8152600401610d51906156cd565b806001600160a01b031660a083901b176071846040516115b09190615106565b9081526040516020918190038201902091909155607280546001810182556000919091528451611607927fdffbd64cc7c1a7eb27984335d9416d51137a03d3fabec7141025c62663253fe1909201918601906143b1565b50806001600160a01b031682846040516116219190615106565b604051908190038120907ff66e0ffd7bef94cf71780cd72520192d584667975baec0a28f68fc5ac01ee65390600090a4505050565b60725490565b6060606c600061166a613441565b6001600160a01b0316815260208101919091526040016000205460ff166116a35760405162461bcd60e51b8152600401610d51906155e2565b60405163512ebe4360e11b81526001600160a01b0385169063a25d7c86906116d19086908690600401615313565b600060405180830381600087803b1580156116eb57600080fd5b505af11580156116ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117279190810190614a6b565b905060005b83518110156117d45783818151811061174157fe5b60200260200101516001600160a01b0316856001600160a01b0316611764613441565b6001600160a01b03167f50215eaf403f70a465a98e402722c2751bdc09c31a6c24993bebe52b36b4c35986858151811061179a57fe5b60200260200101518686815181106117ae57fe5b60200260200101516040516117c49291906159d6565b60405180910390a460010161172c565b509392505050565b60705490565b7fab14dd152d2c116f23ca08cf0d9593a79931b31ec240371035e65929660de44281565b6065546001600160a01b0316331461181d57600080fd5b61182984848484613806565b50505050565b1860009081526066602052604090205490565b6000805b61184e6117dc565b81101561188657826070828154811061186357fe5b9060005260206000200154141561187e576001915050610b5e565b600101611846565b50600092915050565b60009081526066602052604090205490565b60608060606072805480602002602001604051908101604052809291908181526020016000905b828210156119735760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561195f5780601f106119345761010080835404028352916020019161195f565b820191906000526020600020905b81548152906001019060200180831161194257829003601f168201915b5050505050815260200190600101906118c8565b5050607254929550829150506001600160401b038111801561199457600080fd5b506040519080825280602002602001820160405280156119be578160200160208202803683370190505b509250806001600160401b03811180156119d757600080fd5b50604051908082528060200260200182016040528015611a01578160200160208202803683370190505b50915060005b81811015611afa57611ab760728281548110611a1f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611aad5780601f10611a8257610100808354040283529160200191611aad565b820191906000526020600020905b815481529060010190602001808311611a9057829003601f168201915b50505050506132ac565b858381518110611ac357fe5b60200260200101858481518110611ad657fe5b6001600160a01b039093166020938402919091019092019190915252600101611a07565b5050909192565b6000606c6000611b0f613441565b6001600160a01b0316815260208101919091526040016000205460ff16611b485760405162461bcd60e51b8152600401610d51906155e2565b6001600160a01b0383166000908152606d6020526040902054611b6b9083613aa9565b6001600160a01b0384166000818152606d60205260409020829055909150611b91613441565b6001600160a01b03167f368febfff609c2b53c67197b95ab76e156c79bac1f9a83ea429cddad4861c1088484604051611bcb9291906159d6565b60405180910390a392915050565b6a3332b2a932b3b4b9ba32b960a91b60005260666020527fcb09fe4fbe012b91e8122a356e75d6ebd9689d95739d160b534385000acfae3854611c1b90613ace565b6b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f82833981519152541580611c705750611c5b611c55613441565b8561106e565b6001600160a01b0316856001600160a01b0316145b611c8c5760405162461bcd60e51b8152600401610d5190615810565b8051611ca76c6d696e5369676e61747572657360981b61188f565b811015611cc65760405162461bcd60e51b8152600401610d519061557f565b60005b81811015611fa25760005b81811015611d4457838181518110611ce857fe5b6020026020010151600001516001600160a01b0316848381518110611d0957fe5b6020026020010151600001516001600160a01b03161415611d3c5760405162461bcd60e51b8152600401610d5190615668565b600101611cd4565b5060007fab14dd152d2c116f23ca08cf0d9593a79931b31ec240371035e65929660de442898988604051602001611d7b91906150dc565b6040516020818303038152906040528051906020012088604051602001611da2919061509d565b60405160208183030381529060405280519060200120888781518110611dc457fe5b602002602001015160000151604051602001611de59695949392919061547c565b604051602081830303815290604052805190602001209050600060675482604051602001611e14929190615122565b6040516020818303038152906040528051906020012090506000600182878681518110611e3d57fe5b602002602001015160200151888781518110611e5557fe5b602002602001015160400151898881518110611e6d57fe5b60200260200101516060015160405160008152602001604052604051611e9694939291906154b0565b6020604051602081039080840390855afa158015611eb8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611eeb5760405162461bcd60e51b8152600401610d5190615554565b858481518110611ef757fe5b6020026020010151600001516001600160a01b0316816001600160a01b031614611f335760405162461bcd60e51b8152600401610d5190615765565b611f55868581518110611f4257fe5b6020026020010151600001516001613bcf565b50806001600160a01b03168a6001600160a01b03168c7f60ba43d13fb1673027b408104ce0f140ce5da24f7f56ceef35d553285ca38be760405160405180910390a4505050600101611cc9565b5061142487878686613806565b6060806000611fbd8461224c565b9150506001600160a01b038116611fd15750825b6000805b611fdd6117dc565b811015612046576001600160a01b0383166000908152606f60205260408120607080548391908590811061200d57fe5b600091825260208083209091015483528201929092526040019020546001600160a01b03161461203e576001909101905b600101611fd5565b50806001600160401b038111801561205d57600080fd5b50604051908082528060200260200182016040528015612087578160200160208202803683370190505b509350806001600160401b03811180156120a057600080fd5b506040519080825280602002602001820160405280156120ca578160200160208202803683370190505b5092506000805b6120d96117dc565b811015612177576000607082815481106120ef57fe5b60009182526020808320909101546001600160a01b038089168452606f83526040808520838652909352919092205491925016801561216d578188858151811061213557fe5b6020026020010181815250508087858151811061214e57fe5b6001600160a01b03909216602092830291909101909101526001909301925b50506001016120d1565b50505050915091565b6065546001600160a01b0316331461219757600080fd5b6001600160a01b0382166000818152606c6020526040808220805460ff191685151590811790915590519092917fa59b1fd27aedbbb7212d6bf736c8f4cc41f5a3f97eb7edc6820c59c0ec9e553491a35050565b6065546001600160a01b0316331461220257600080fd5b6065546040516000916001600160a01b0316907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908390a3606580546001600160a01b0319169055565b6001600160a01b03166000908152606e602052604090205460a081901c91565b6000606c600061227a613441565b6001600160a01b0316815260208101919091526040016000205460ff166122b35760405162461bcd60e51b8152600401610d51906155e2565b506001600160a01b0382166000908152606d6020526040902054818110156122d9578091505b610be88383613bcf565b6065546001600160a01b031633146122fa57600080fd5b60686020527fc23ad3b8698fdd56cdfe9f7feef345bbc2ef01abc106afb48c4d9ac42cc7bae580546001600160a01b039485166001600160a01b0319918216179091557f15e5ff6e3c2b1d92344ca120709b0f1445ed661c8c399a859311ae0e7b8680ec8054938516938216939093179092556b26b0b83834b733aa37b5b2b760a11b6000527f11d58bfb56a1e79cb4d1fe24b6dd2edf7727005640478b994158cc2367c1aad98054919093169116179055565b6060606c60006123bc613441565b6001600160a01b0316815260208101919091526040016000205460ff166123f55760405162461bcd60e51b8152600401610d51906155e2565b612400848484613445565b949350505050565b6065546001600160a01b0316331461241f57600080fd5b61242b6073838361442f565b507f6a924554e8880f5ab8a47263c81ea1dc06992d445d689eda474f16d29aeddb88828260405161245d9291906152c5565b60405180910390a15050565b6065546000906001600160a01b0316612480613441565b6001600160a01b0316146124bc576866656543726561746560b81b6000526066602052600080516020615f62833981519152546124bc90613ace565b6000606a816124c9613441565b6001600160a01b03908116825260208201929092526040016000205416146125035760405162461bcd60e51b8152600401610d519061551d565b600061250d613579565b612515613441565b604051602001612526929190615175565b604051602081830303815290604052805190602001209050606060405180602001612550906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59250826001600160a01b03166374845865306c26b0b83830b13632aa37b5b2b760991b3061259c613441565b8c8c8c8c6040516024016125b5969594939291906151c3565b60408051601f198184030181529181526020820180516001600160e01b0316636fb9aeb160e11b1790525160e085901b6001600160e01b03191681526126009392919060040161521a565b600060405180830381600087803b15801561261a57600080fd5b505af115801561262e573d6000803e3d6000fd5b5050505082606a600061263f613441565b6001600160a01b039081168252602082019290925260400160002080546001600160a01b0319169290911691909117905561267a8385613c52565b826001600160a01b031661268c613441565b6001600160a01b03167fbd604b121560cfb19ff3df52b010ee7b1601535937fedb6d59c6100fedca2a14898989896040516126ca94939291906154e1565b60405180910390a35050949350505050565b6000606c60006126ea613441565b6001600160a01b0316815260208101919091526040016000205460ff166127235760405162461bcd60e51b8152600401610d51906155e2565b604051633d317ae360e11b81526001600160a01b03851690637a62f5c6906127519086908690600401615241565b602060405180830381600087803b15801561276b57600080fd5b505af115801561277f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a39190614d2c565b9050826001600160a01b0316846001600160a01b03166127c1613441565b6001600160a01b03167f547d6e3483177f508eaa5e1b421336afb2a25e2ccd1e7698dfa1ce909a1ea17485856040516127fb9291906159d6565b60405180910390a49392505050565b606c6020526000908152604090205460ff1681565b6065546001600160a01b0316331461283657600080fd5b610af08383188261341a565b6065546001600160a01b0316331461285957600080fd5b61286281613d8c565b50565b6069602052600090815260409020546001600160a01b031681565b6000308383604051602001612896929190615175565b60405160208183030381529060405280519060200120604051806020016128bc906143a4565b6020820181038252601f19601f82011660405250805190602001206040516020016128e99392919061513d565b60408051601f1981840301815291905280516020909101209392505050565b600054610100900460ff16806129215750612921613dfb565b8061292f575060005460ff16155b61294b5760405162461bcd60e51b8152600401610d519061578b565b600054610100900460ff16158015612976576000805460ff1961ff0019909116610100171660011790555b61297f866131da565b61298b85858585610de3565b801561299d576000805461ff00191690555b505050505050565b607381815481106129b257fe5b6000918252602090912001546001600160a01b0316905081565b6060610b5b6073805480602002602001604051908101604052809291908181526020018280548015612a2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a09575b505050505083611101565b6065546000906001600160a01b0316612a49613441565b6001600160a01b031614612af6576866656543726561746560b81b6000526066602052600080516020615f6283398151915254612a8590613ace565b6b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f82833981519152541580612ada5750612ac5612abf613441565b8361106e565b6001600160a01b0316836001600160a01b0316145b612af65760405162461bcd60e51b8152600401610d5190615810565b6001600160a01b038381166000908152606960205260409020541615612b2e5760405162461bcd60e51b8152600401610d519061586e565b6000612b38613579565b84604051602001612b4a929190615175565b604051602081830303815290604052805190602001209050606060405180602001612b74906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59250826001600160a01b03166374845865306a151bdad95b93585c1c195960aa1b3089604051602401612bc89291906151a9565b60408051601f198184030181529181526020820180516001600160e01b0316631b86b05760e11b1790525160e085901b6001600160e01b0319168152612c139392919060040161521a565b600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050506001600160a01b0385811660008181526069602090815260409182902080546001600160a01b0319169488169490941790935580516318160ddd60e01b81529051612ceb938793926318160ddd9260048083019392829003018186803b158015612cae57600080fd5b505afa158015612cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce69190614d2c565b613c52565b826001600160a01b0316856001600160a01b0316612d07613441565b6001600160a01b03167fc22552ea26b050ed8e679b7aa21b813b9962cae2a3ca57b0b1e5b83845a3f16360405160405180910390a4505092915050565b6866656543726561746560b81b60009081526066602052600080516020615f6283398151915254612d7490613ace565b6001600160a01b0388161580612daf57506b37b7363ca232b83637bcb2b960a11b6000526066602052600080516020615f8283398151915254155b80612ddb5750612dc6612dc0613441565b8861106e565b6001600160a01b0316886001600160a01b0316145b612df75760405162461bcd60e51b8152600401610d5190615810565b6c6d696e5369676e61747572657360981b60005260666020527fbdf30eb02993786a017e5b974fa17b03ffb88069f40f6a3ec7b5a425c3870c8f5482511015612e525760405162461bcd60e51b8152600401610d519061557f565b60005b825181101561310b5760005b81811015612ed157838181518110612e7557fe5b6020026020010151600001516001600160a01b0316848381518110612e9657fe5b6020026020010151600001516001600160a01b03161415612ec95760405162461bcd60e51b8152600401610d5190615668565b600101612e61565b5060007f33a010203279ba8cdbc561bf3370b2ec1e054ec371ce4e4b8320d9446adc3f0b612efd613441565b8c8c8b805190602001208b805190602001208b8b8b8a81518110612f1d57fe5b602002602001015160000151604051602001612f419998979695949392919061540d565b60405160208183030381529060405280519060200120905060675481604051602001612f6e929190615122565b6040516020818303038152906040528051906020012090506000600182868581518110612f9757fe5b602002602001015160200151878681518110612faf57fe5b602002602001015160400151888781518110612fc757fe5b60200260200101516060015160405160008152602001604052604051612ff094939291906154b0565b6020604051602081039080840390855afa158015613012573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166130455760405162461bcd60e51b8152600401610d5190615554565b84838151811061305157fe5b6020026020010151600001516001600160a01b0316816001600160a01b03161461308d5760405162461bcd60e51b8152600401610d5190615765565b61309c858481518110611f4257fe5b50806001600160a01b03166130af613441565b6001600160a01b03168c6001600160a01b03167f616aa5044dcfe1a7d2a8757dedc57f78a23826b7fdf81436d5f0470e950e49c58f8d8d8d8d6040516130f9959493929190615993565b60405180910390a45050600101612e55565b506131228989613119613441565b898989896135dd565b9998505050505050505050565b6065546001600160a01b0316331461314657600080fd5b61314e613579565b60011480613163575061315f613579565b6003145b61317f5760405162461bcd60e51b8152600401610d51906155ab565b61318881611842565b156131a55760405162461bcd60e51b8152600401610d51906158a5565b607080546001810182556000919091527f8f6b23ffa15f0465e3176e15ca644cf24f86dc1312fe715484e3c4aead5eb78b0155565b600054610100900460ff16806131f357506131f3613dfb565b80613201575060005460ff16155b61321d5760405162461bcd60e51b8152600401610d519061578b565b600054610100900460ff16158015613248576000805460ff1961ff0019909116610100171660011790555b606580546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908290a38015610d06576000805461ff00191690555050565b60008060006071846040516132c19190615106565b9081526040519081900360200190205460a081901c9590945092505050565b6000606c60006132ee613441565b6001600160a01b0316815260208101919091526040016000205460ff166133275760405162461bcd60e51b8152600401610d51906155e2565b604051636489aba560e01b81526001600160a01b03851690636489aba5906133559086908690600401615241565b602060405180830381600087803b15801561336f57600080fd5b505af1158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d2c565b9050826001600160a01b0316846001600160a01b03166133c5613441565b6001600160a01b03167f50215eaf403f70a465a98e402722c2751bdc09c31a6c24993bebe52b36b4c35985856040516127fb9291906159d6565b606a602052600090815260409020546001600160a01b031681565b6000828152606660205260409020548114610d065760009182526066602052604090912055565b3390565b6040516307a1b0ab60e21b81526060906001600160a01b03851690631e86c2ac906134769086908690600401615313565b600060405180830381600087803b15801561349057600080fd5b505af11580156134a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134cc9190810190614a6b565b905060005b83518110156117d4578381815181106134e657fe5b60200260200101516001600160a01b0316856001600160a01b0316613509613441565b6001600160a01b03167f547d6e3483177f508eaa5e1b421336afb2a25e2ccd1e7698dfa1ce909a1ea17486858151811061353f57fe5b602002602001015186868151811061355357fe5b60200260200101516040516135699291906159d6565b60405180910390a46001016134d1565b4690565b60408051600560a21b83186014820152603481019091526060906135a081613e01565b9392505050565b6060610b5b6135b583613e4b565b613e01565b6060806135c683613f53565b90506135a06135d7825160c0614053565b826141ac565b6000806001600160a01b038816156135f557876135f7565b865b60008a8152606b602090815260408083206001600160a01b038086168552925290912054919250161561363c5760405162461bcd60e51b8152600401610d5190615696565b60008982604051602001613651929190615175565b60405160208183030381529060405280519060200120905060606040518060200161367b906143a4565b6020820181038252601f19601f820116604052509050818151602083016000f59350836001600160a01b03166374845865306b26b0b83834b733aa37b5b2b760a11b308f8f8f8f8f8f8f6040516024016136dc98979695949392919061525a565b60408051601f198184030181529181526020820180516001600160e01b03166337addc7560e11b1790525160e085901b6001600160e01b03191681526137279392919060040161521a565b600060405180830381600087803b15801561374157600080fd5b505af1158015613755573d6000803e3d6000fd5b50505060008c8152606b602090815260408083206001600160a01b038881168552925290912080546001600160a01b0319169187169190911790555061379b8486613c52565b836001600160a01b0316896001600160a01b03168b6001600160a01b03167f66e6dab65de642df4a6afb3a99e6b803d1520d0a7d5ffdf10b88cdaaf0c5b9988e8c8c8c8c6040516137f0959493929190615993565b60405180910390a4505050979650505050505050565b61380e613579565b60011480613823575061381f613579565b6003145b61383f5760405162461bcd60e51b8152600401610d51906155ab565b80518251146138605760405162461bcd60e51b8152600401610d51906157d9565b61386984611842565b6138855760405162461bcd60e51b8152600401610d5190615837565b60005b8251811015613aa2576138ad8382815181106138a057fe5b6020026020010151611842565b6138c95760405162461bcd60e51b8152600401610d51906156f7565b8181815181106138d557fe5b60200260200101516001600160a01b0316846001600160a01b0316148061392957506139018585612880565b6001600160a01b031682828151811061391657fe5b60200260200101516001600160a01b0316145b8061394e57506065546001600160a01b0316613943613441565b6001600160a01b0316145b61396a5760405162461bcd60e51b8152600401610d5190615913565b836001600160a01b031660a086901b17606e600084848151811061398a57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508181815181106139c257fe5b6020026020010151606f6000866001600160a01b03166001600160a01b0316815260200190815260200160002060008584815181106139fd57fe5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f2bb569421de23a5bd9d854dff71796f10e7973da0031747b01da9c41ea4f5c838585858481518110613a6657fe5b6020026020010151858581518110613a7a57fe5b6020026020010151604051613a92949392919061596c565b60405180910390a1600101613888565b5050505050565b600082820183811015610be85760405162461bcd60e51b8152600401610d5190615609565b613ae081670de0b6b3a7640000614229565b341015613aff5760405162461bcd60e51b8152600401610d5190615640565b64666565546f60d81b60005260666020527f729bca52a6d55a36cde7d479eb9228d7df8a69b2e9ca2a9c0b17e052244a1e17546001600160a01b038116613b435750305b6040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015613b78573d6000803e3d6000fd5b50806001600160a01b0316613b8b613441565b6001600160a01b03167fc0d39cf3434f9dede81e427dbbccd901073df1b746711cb6cb7db1b27ddd692734604051613bc39190615404565b60405180910390a35050565b6001600160a01b0382166000908152606d6020526040812054613bf2908361423f565b6001600160a01b0384166000818152606d60205260409020829055909150613c18613441565b6001600160a01b03167ffb81f5e07d16a904d08894e41cac92dd304a5bc82d13f8030f67df1e7a71f2238484604051611bcb9291906159d6565b6d696e697451756f7461526174696f60901b600090815260666020527ffff3d5fe76a3d2f66c91aa6b3a12e77771c67f378774057e5556ee49719608bf54613caf90670de0b6b3a764000090613ca9908590614281565b906142bb565b6073549091506060906001600160401b0381118015613ccd57600080fd5b50604051908082528060200260200182016040528015613cf7578160200160208202803683370190505b50905060005b8151811015613d265782828281518110613d1357fe5b6020908102919091010152600101613cfd565b50613aa2846073805480602002602001604051908101604052809291908181526020018280548015613d8157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d63575b505050505083613445565b6001600160a01b038116613d9f57600080fd5b6065546040516001600160a01b038084169216907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b303b1590565b60608082516001148015613e2a5750608083600081518110613e1f57fe5b016020015160f81c11155b15613e36575081610b5b565b610be8613e4584516080614053565b846141ac565b60408051602080825281830190925260609182919060208201818036833701905050905082602082015260005b6020811015613eae57818181518110613e8d57fe5b01602001516001600160f81b03191615613ea657613eae565b600101613e78565b6060816020036001600160401b0381118015613ec957600080fd5b506040519080825280601f01601f191660200182016040528015613ef4576020820181803683370190505b50905060005b8151811015613f4a578351600184019385918110613f1457fe5b602001015160f81c60f81b828281518110613f2b57fe5b60200101906001600160f81b031916908160001a905350600101613efa565b50949350505050565b6060815160001415613f745750604080516000815260208101909152610b5e565b6000805b8351811015613fa757838181518110613f8d57fe5b602002602001015151820191508080600101915050613f78565b6060826001600160401b0381118015613fbf57600080fd5b506040519080825280601f01601f191660200182016040528015613fea576020820181803683370190505b50600092509050602081015b8551831015613f4a57606086848151811061400d57fe5b60200260200101519050600060208201905061402b838284516142fd565b87858151811061403757fe5b6020026020010151518301925050508280600101935050613ff6565b60608060388410156140b05760408051600180825281830190925290602082018180368337019050509050838301601f1a60f81b8160008151811061409457fe5b60200101906001600160f81b031916908160001a905350610be8565b600060015b8086816140be57fe5b04156140d357600190910190610100026140b5565b816001016001600160401b03811180156140ec57600080fd5b506040519080825280601f01601f191660200182016040528015614117576020820181803683370190505b509250603782860101601f1a60f81b8360008151811061413357fe5b60200101906001600160f81b031916908160001a905350600190505b8181116141a2576101008183036101000a878161416857fe5b048161417057fe5b06601f1a60f81b83828151811061418357fe5b60200101906001600160f81b031916908160001a90535060010161414f565b5050905092915050565b6060806040519050835180825260208201818101602087015b818310156141dd5780518352602092830192016141c5565b50855184518101855292509050808201602086015b8183101561420a5780518352602092830192016141f2565b508651929092011591909101601f01601f191660405250905092915050565b60008183106142385781610be8565b5090919050565b6000610be883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614341565b60008261429057506000610beb565b8282028284828161429d57fe5b0414610be85760405162461bcd60e51b8152600401610d5190615724565b6000610be883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061436d565b8282825b60208110614320578151835260209283019290910190601f1901614301565b905182516020929092036101000a6000190180199091169116179052505050565b600081848411156143655760405162461bcd60e51b8152600401610d5191906154ce565b505050900390565b6000818361438e5760405162461bcd60e51b8152600401610d5191906154ce565b50600083858161439a57fe5b0495945050505050565b6104d480615a8e83390190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106143f257805160ff191683800117855561441f565b8280016001018555821561441f579182015b8281111561441f578251825591602001919060010190614404565b5061442b92915061448e565b5090565b828054828255906000526020600020908101928215614482579160200282015b828111156144825781546001600160a01b0319166001600160a01b0384351617825560209092019160019091019061444f565b5061442b9291506144a3565b5b8082111561442b576000815560010161448f565b5b8082111561442b5780546001600160a01b03191681556001016144a4565b80356001600160a01b0381168114610beb57600080fd5b600082601f8301126144e9578081fd5b81356144fc6144f782615a0a565b6159e4565b81815291506020808301908481018184028601820187101561451d57600080fd5b60005b848110156145445761453288836144c2565b84529282019290820190600101614520565b505050505092915050565b600082601f83011261455f578081fd5b813561456d6144f782615a0a565b818152915060208083019084810160808085028701830188101561459057600080fd5b6000805b868110156145f55782848b0312156145aa578182fd5b6145b3836159e4565b6145bd8b866144c2565b81526145cb8b8787016146ae565b81870152604085810135908201526060808601359082015286529484019492820192600101614594565b5050505050505092915050565b600082601f830112614612578081fd5b81356146206144f782615a0a565b81815291506020808301908481018184028601820187101561464157600080fd5b60005b8481101561454457813584529282019290820190600101614644565b600082601f830112614670578081fd5b813561467e6144f782615a29565b915080825283602082850101111561469557600080fd5b8060208401602084013760009082016020015292915050565b803560ff81168114610beb57600080fd5b6000602082840312156146d0578081fd5b610be883836144c2565b6000806000606084860312156146ee578182fd5b6146f885856144c2565b925061470785602086016144c2565b915061471685604086016144c2565b90509250925092565b60008060008060808587031215614734578081fd5b61473e86866144c2565b935061474d86602087016144c2565b925061475c86604087016144c2565b915061476b86606087016144c2565b905092959194509250565b600080600080600060a0868803121561478d578081fd5b61479787876144c2565b94506147a687602088016144c2565b93506147b587604088016144c2565b92506147c487606088016144c2565b91506147d387608088016144c2565b90509295509295909350565b6000806000606084860312156147f3578283fd5b83356147fe81615a78565b9250602084013561480e81615a78565b929592945050506040919091013590565b600080600060608486031215614833578081fd5b833561483e81615a78565b925060208401356001600160401b0380821115614859578283fd5b614865878388016144d9565b9350604086013591508082111561487a578283fd5b5061488786828701614602565b9150509250925092565b600080604083850312156148a3578182fd5b6148ad84846144c2565b915060208301356001600160401b038111156148c7578182fd5b6148d385828601614602565b9150509250929050565b600080604083850312156148ef578182fd5b6148f984846144c2565b91506020830135801515811461490d578182fd5b809150509250929050565b6000806040838503121561492a578182fd5b61493484846144c2565b946020939093013593505050565b600080600060608486031215614956578081fd5b61496085856144c2565b95602085013595506040909401359392505050565b60008060208385031215614987578182fd5b82356001600160401b038082111561499d578384fd5b818501915085601f8301126149b0578384fd5b8135818111156149be578485fd5b86602080830285010111156149d1578485fd5b60209290920196919550909350505050565b600080604083850312156149f5578182fd5b82356001600160401b0380821115614a0b578384fd5b614a17868387016144d9565b93506020850135915080821115614a2c578283fd5b506148d385828601614602565b600060208284031215614a4a578081fd5b81356001600160401b03811115614a5f578182fd5b61240084828501614602565b60006020808385031215614a7d578182fd5b82516001600160401b03811115614a92578283fd5b8301601f81018513614aa2578283fd5b8051614ab06144f782615a0a565b8181528381019083850185840285018601891015614acc578687fd5b8694505b83851015614aee578051835260019490940193918501918501614ad0565b50979650505050505050565b600060208284031215614b0b578081fd5b5035919050565b60008060408385031215614b24578182fd5b82359150602083013561490d81615a78565b600080600060608486031215614b4a578081fd5b83359250614b5b85602086016144c2565b9150604084013590509250925092565b60008060408385031215614b7d578182fd5b50508035926020909101359150565b600080600060608486031215614ba0578081fd5b505081359360208301359350604090920135919050565b600060208284031215614bc8578081fd5b81356001600160401b03811115614bdd578182fd5b61240084828501614660565b600060208284031215614bfa578081fd5b81516001600160401b03811115614c0f578182fd5b8201601f81018413614c1f578182fd5b8051614c2d6144f782615a29565b818152856020838501011115614c41578384fd5b614c52826020830160208601615a4c565b95945050505050565b60008060008060808587031215614c70578182fd5b84356001600160401b0380821115614c86578384fd5b614c9288838901614660565b95506020870135915080821115614ca7578384fd5b50614cb487828801614660565b935050614cc486604087016146ae565b9396929550929360600135925050565b600080600060608486031215614ce8578081fd5b83356001600160401b03811115614cfd578182fd5b614d0986828701614660565b935050602084013591506040840135614d2181615a78565b809150509250925092565b600060208284031215614d3d578081fd5b5051919050565b60008060408385031215614d56578182fd5b82359150614d6784602085016144c2565b90509250929050565b600080600080600080600060e0888a031215614d8a578485fd5b87359650614d9b8960208a016144c2565b9550614daa8960408a016144c2565b945060608801356001600160401b0380821115614dc5578384fd5b614dd18b838c01614660565b955060808a0135915080821115614de6578384fd5b50614df38a828b01614660565b935050614e038960a08a016146ae565b915060c0880135905092959891949750929550565b60008060008060808587031215614e2d578182fd5b843593506020850135614e3f81615a78565b925060408501356001600160401b0380821115614e5a578384fd5b614e6688838901614602565b93506060870135915080821115614e7b578283fd5b50614e88878288016144d9565b91505092959194509250565b60008060008060008060c08789031215614eac578384fd5b86359550614ebd88602089016144c2565b94506040870135935060608701356001600160401b0380821115614edf578384fd5b614eeb8a838b01614602565b94506080890135915080821115614f00578384fd5b614f0c8a838b016144d9565b935060a0890135915080821115614f21578283fd5b50614f2e89828a0161454f565b9150509295509295509295565b600080600080600080600080610100898b031215614f57578182fd5b88359750614f688a60208b016144c2565b96506040890135955060608901356001600160401b0380821115614f8a578384fd5b614f968c838d01614660565b965060808b0135915080821115614fab578384fd5b614fb78c838d01614660565b9550614fc68c60a08d016146ae565b945060c08b0135935060e08b0135915080821115614fe2578283fd5b50614fef8b828c0161454f565b9150509295985092959890939650565b6000815180845260208085019450808401835b838110156150375781516001600160a01b031687529582019590820190600101615012565b509495945050505050565b6000815180845260208085019450808401835b8381101561503757815187529582019590820190600101615055565b60008151808452615089816020860160208601615a4c565b601f01601f19169290920160200192915050565b815160009082906020808601845b838110156150d05781516001600160a01b0316855293820193908201906001016150ab565b50929695505050505050565b815160009082906020808601845b838110156150d0578151855293820193908201906001016150ea565b60008251615118818460208701615a4c565b9190910192915050565b61190160f01b81526002810192909252602282015260420190565b6001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b91825260601b6bffffffffffffffffffffffff1916602082015260340190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0387811682528616602082015260c0604082018190526000906151ef90830187615071565b82810360608401526152018187615071565b60ff959095166080840152505060a00152949350505050565b600060018060a01b038516825283602083015260606040830152614c526060830184615071565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038981168252602082018990528781166040830152861660608201526101006080820181905260009061529683820188615071565b905082810360a08401526152aa8187615071565b60ff9590951660c0840152505060e001529695505050505050565b60208082528181018390526000908460408401835b86811015615308578284016001600160a01b036152f782866144c2565b1683529250908301906001016152da565b509695505050505050565b6000604082526153266040830185614fff565b8281036020840152614c528185615042565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561538d57607f1988840301855261537b838351615071565b9486019492509085019060010161535f565b5050858103848701526153a08189615042565b935050505082810360408401526153b78185614fff565b9695505050505050565b600060208252610be86020830184615042565b6000604082526153e76040830185615042565b8281036020840152614c528185614fff565b901515815260200190565b90815260200190565b9889526001600160a01b0397881660208a015260408901969096529386166060880152608087019290925260a086015260ff1660c085015260e0840152166101008201526101200190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b95865260208601949094526001600160a01b039283166040860152606085019190915260808401521660a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610be86020830184615071565b6000608082526154f46080830187615071565b82810360208401526155068187615071565b60ff95909516604084015250506060015292915050565b6020808252601d908201527f4d61707061626c65546f6b656e206372656174656420616c7265616479000000604082015260600190565b602080825260119082015270696e76616c6964207369676e617475726560781b604082015260600190565b602080825260129082015271746f6f20666577207369676e61747572657360701b604082015260600190565b6020808252601f908201527f63616c6c6564206f6e6c79206f6e20657468657265756d206d61696e6e657400604082015260600190565b6020808252600d908201526c6f6e6c7920617574686f72747960981b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600e908201526d66656520697320746f6f206c6f7760901b604082015260600190565b60208082526014908201527372657065746974697665207369676e61746f727960601b604082015260600190565b6020808252601c908201527f4d617070696e67546f6b656e206372656174656420616c726561647900000000604082015260600190565b60208082526010908201526f1cde5b589bdb08191a5999995c995b9d60821b604082015260600190565b602080825260139082015272139bdd081cdd5c1c1bdc9d0818da185a5b9259606a1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600c908201526b1d5b985d5d1a1bdc9a5e995960a21b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526019908201527f74776f206172726179206c656e7468206e6f7420657175616c00000000000000604082015260600190565b6020808252600d908201526c37b7363c903232b83637bcb2b960991b604082015260600190565b60208082526017908201527f4e6f7420737570706f7274206d61696e436861696e4964000000000000000000604082015260600190565b6020808252601b908201527f546f6b656e4d6170706564206372656174656420616c72656164790000000000604082015260600190565b60208082526017908201527f737570706f727420636861696e496420616c7265616479000000000000000000604082015260600190565b60208082526017908201527f43657274696669656420616464656420616c7265616479000000000000000000604082015260600190565b60208082526022908201527f696e76616c6964206d617070696e67546f6b656e4d6170706564206164647265604082015261737360f01b606082015260800190565b9182526001600160a01b0316602082015260400190565b9384526001600160a01b039283166020850152604084019190915216606082015260800190565b600086825260a060208301526159ac60a0830187615071565b82810360408401526159be8187615071565b60ff9590951660608401525050608001529392505050565b918252602082015260400190565b6040518181016001600160401b0381118282101715615a0257600080fd5b604052919050565b60006001600160401b03821115615a1f578081fd5b5060209081020190565b60006001600160401b03821115615a3e578081fd5b50601f01601f191660200190565b60005b83811015615a67578181015183820152602001615a4f565b838111156118295750506000910152565b6001600160a01b038116811461286257600080fdfe608060405234801561001057600080fd5b506104b4806100206000396000f3fe6080604052600436106100225760003560e01c8063748458651461003957610031565b366100315761002f61004c565b005b61002f61004c565b61002f6100473660046102f9565b610091565b6100553361013d565b801561005f575036155b801561006d57506108fc5a11155b156100775761008f565b61007f61008f565b61008f61008a610143565b6101f2565b565b600061009b610216565b6001600160a01b0316146100ae57600080fd5b6100b78361023b565b6100c08261028d565b8051156101385760006100d1610143565b6001600160a01b0316826040516100e891906103a3565b600060405180830381855af49150503d8060008114610123576040519150601f19603f3d011682016040523d82523d6000602084013e610128565b606091505b505090508061013657600080fd5b505b505050565b3b151590565b60008061014e610216565b90506101598161013d565b156101e957806001600160a01b0316630b2bcd676101756102b1565b6040518263ffffffff1660e01b815260040161019191906103dc565b60206040518083038186803b1580156101a957600080fd5b505afa1580156101bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e191906102d6565b9150506101ef565b60009150505b90565b3660008037600080366000845af43d6000803e808015610211573d6000f35b3d6000fd5b7f7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af15490565b6102448161013d565b6102695760405162461bcd60e51b8152600401610260906103e5565b60405180910390fd5b7f7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af155565b7f4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a87055565b7f4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a8705490565b6000602082840312156102e7578081fd5b81516102f281610466565b9392505050565b60008060006060848603121561030d578182fd5b833561031881610466565b925060208401359150604084013567ffffffffffffffff8082111561033b578283fd5b818601915086601f83011261034e578283fd5b81358181111561035c578384fd5b61036f601f8201601f1916602001610433565b9150808252876020828501011115610385578384fd5b61039681602084016020860161045a565b5080925050509250925092565b60008251815b818110156103c357602081860181015185830152016103a9565b818111156103d15782828501525b509190910192915050565b90815260200190565b6020808252602e908201527f43616e6e6f7420736574206120666163746f727920746f2061206e6f6e2d636f60408201526d6e7472616374206164647265737360901b606082015260800190565b60405181810167ffffffffffffffff8111828210171561045257600080fd5b604052919050565b82818337506000910152565b6001600160a01b038116811461047b57600080fd5b5056fea26469706673582212208a83372edb5bd000f176d79a4af74a92896277b28ec799186455f571b908f17164736f6c634300060c00330fd54b93a24feeadd1317d9ce59c55fc0e99641d75b0208a9b2f4b5a0050f08578d01a15a3eb58a539cbe421d51d17e63aef0af9ed019b297a979d8332710bada26469706673582212204bed37698494fa0eba930b7340d3d6f42c3a2216fe8e86a4468ffeb85e285db164736f6c634300060c0033
Deployed Bytecode Sourcemap
100858:24748:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73553:146;;;;;;;;;;-1:-1:-1;73553:146:0;;;;;:::i;:::-;;:::i;:::-;;108479:172;;;;;;;;;;-1:-1:-1;108479:172:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102357:29;;;;;;;;;;-1:-1:-1;102357:29:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;107310:220::-;;;;;;;;;;-1:-1:-1;107310:220:0;;;;;:::i;:::-;;:::i;101545:58::-;;;;;;;;;;-1:-1:-1;101545:58:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70687:23::-;;;;;;;;;;;;;:::i;102493:32::-;;;;;;;;;;-1:-1:-1;102493:32:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;101171:194::-;;;;;;;;;;;;;:::i;73295:105::-;;;;;;;;;;-1:-1:-1;73295:105:0;;;;;:::i;:::-;;:::i;106299:234::-;;;;;;;;;;-1:-1:-1;106299:234:0;;;;;:::i;:::-;;:::i;101372:126::-;;;;;;;;;;;;;:::i;102923:1171::-;;;;;;;;;;-1:-1:-1;102923:1171:0;;;;;:::i;:::-;;:::i;118378:309::-;;;;;;;;;;-1:-1:-1;118378:309:0;;;;;:::i;:::-;;:::i;101505:31::-;;;;;;;;;;;;;:::i;109668:406::-;;;;;;;;;;-1:-1:-1;109668:406:0;;;;;:::i;:::-;;:::i;102225:73::-;;;;;;;;;;-1:-1:-1;102225:73:0;;;;;:::i;:::-;;:::i;102028:44::-;;;;;;;;;;-1:-1:-1;102028:44:0;;;;;:::i;:::-;;:::i;108657:406::-;;;;;;;;;;-1:-1:-1;108657:406:0;;;;;:::i;:::-;;:::i;72667:139::-;;;;;;;;;;-1:-1:-1;72667:139:0;;;;;:::i;:::-;;:::i;101804:70::-;;;;;;;;;;-1:-1:-1;101804:70:0;;;;;:::i;:::-;;:::i;123137:309::-;;;;;;:::i;:::-;;:::i;105018:346::-;;;;;;;;;;-1:-1:-1;105018:346:0;;;;;:::i;:::-;;:::i;116758:686::-;;;;;;;;;;-1:-1:-1;116758:686:0;;;;;:::i;:::-;;:::i;115974:104::-;;;;;;;;;;;;;:::i;107536:441::-;;;;;;;;;;-1:-1:-1;107536:441:0;;;;;:::i;:::-;;:::i;110780:104::-;;;;;;;;;;;;;:::i;100994:170::-;;;;;;;;;;;;;:::i;114198:237::-;;;;;;;;;;-1:-1:-1;114198:237:0;;;;;:::i;:::-;;:::i;72529:132::-;;;;;;;;;;-1:-1:-1;72529:132:0;;;;;:::i;:::-;;:::i;112160:234::-;;;;;;;;;;-1:-1:-1;112160:234:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;72427:96::-;;;;;;;;;;-1:-1:-1;72427:96:0;;;;;:::i;:::-;;:::i;116353:397::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;109075:292::-;;;;;;;;;;-1:-1:-1;109075:292:0;;;;;:::i;:::-;;:::i;114447:1413::-;;;;;;:::i;:::-;;:::i;111176:972::-;;;;;;;;;;-1:-1:-1;111176:972:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;104761:174::-;;;;;;;;;;-1:-1:-1;104761:174:0;;;;;:::i;:::-;;:::i;71501:151::-;;;;;;;;;;;;;:::i;110896:268::-;;;;;;;;;;-1:-1:-1;110896:268:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;110086:281::-;;;;;;;;;;-1:-1:-1;110086:281:0;;;;;:::i;:::-;;:::i;104153:359::-;;;;;;;;;;-1:-1:-1;104153:359:0;;;;;:::i;:::-;;:::i;106539:265::-;;;;;;;;;;-1:-1:-1;106539:265:0;;;;;:::i;:::-;;:::i;104524:174::-;;;;;;;;;;-1:-1:-1;104524:174:0;;;;;:::i;:::-;;:::i;120460:1122::-;;;;;;:::i;:::-;;:::i;106816:335::-;;;;;;;;;;-1:-1:-1;106816:335:0;;;;;:::i;:::-;;:::i;101939:43::-;;;;;;;;;;-1:-1:-1;101939:43:0;;;;;:::i;:::-;;:::i;73406:141::-;;;;;;;;;;-1:-1:-1;73406:141:0;;;;;:::i;:::-;;:::i;71841:122::-;;;;;;;;;;-1:-1:-1;71841:122:0;;;;;:::i;:::-;;:::i;101610:48::-;;;;;;;;;;-1:-1:-1;101610:48:0;;;;;:::i;:::-;;:::i;118783:482::-;;;;;;;;;;-1:-1:-1;118783:482:0;;;;;:::i;:::-;;:::i;102569:342::-;;;;;;;;;;-1:-1:-1;102569:342:0;;;;;:::i;:::-;;:::i;102532:28::-;;;;;;;;;;-1:-1:-1;102532:28:0;;;;;:::i;:::-;;:::i;109490:172::-;;;;;;;;;;-1:-1:-1;109490:172:0;;;;;:::i;:::-;;:::i;119273:1067::-;;;;;;:::i;:::-;;:::i;123458:1480::-;;;;;;:::i;:::-;;:::i;112406:288::-;;;;;;;;;;-1:-1:-1;112406:288:0;;;;;:::i;:::-;;:::i;70930:183::-;;;;;;;;;;-1:-1:-1;70930:183:0;;;;;:::i;:::-;;:::i;116090:251::-;;;;;;;;;;-1:-1:-1;116090:251:0;;;;;:::i;:::-;;:::i;107989:335::-;;;;;;;;;;-1:-1:-1;107989:335:0;;;;;:::i;:::-;;:::i;101704:50::-;;;;;;;;;;-1:-1:-1;101704:50:0;;;;;:::i;:::-;;:::i;73553:146::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;73641:50:::1;-1:-1:-1::0;;;;;73672:10:0;::::1;73660:22:::0;::::1;73685:5:::0;73641:10:::1;:50::i;:::-;73553:146:::0;;;:::o;108479:172::-;108560:20;108600:43;108619:11;108600:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;108600:43:0;;;;;;;;;;;;;;;;;;;;;108632:10;108600:18;:43::i;:::-;108593:50;;108479:172;;;;:::o;102357:29::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102357:29:0;:::o;107310:220::-;107419:20;107459:63;107478:18;107498:11;107459:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;107459:63:0;;;;;;;;;;;;;;;;;;;;;107511:10;107459:18;:63::i;:::-;107452:70;;107310:220;;;;;:::o;101545:58::-;;;;;;;;;;;;-1:-1:-1;;;;;101545:58:0;;:::o;70687:23::-;;;-1:-1:-1;;;;;70687:23:0;;:::o;102493:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;102493:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102493:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;101171:194::-;101217:148;101171:194;:::o;73295:105::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;73370:22:::1;73381:3;73386:5;73370:10;:22::i;:::-;73295:105:::0;;:::o;106299:234::-;106421:20;105417:10;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;;;;;;;;;106461:64:::1;106481:18;106501:11;106461:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;106461:64:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;106514:10;106461:19;:64::i;101372:126::-:0;101418:80;101372:126;:::o;102923:1171::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;103095:6:::1;:13;::::0;;;103137:11:::1;103095:13:::0;:53;103201:11:::1;-1:-1:-1::0;;;;;;;;;;;103159:53:0;;;103265:11:::1;103223:21:::0;:53;-1:-1:-1;;;;;103329:12:0;::::1;103287:15:::0;:54;103394:1:::1;-1:-1:-1::0;;;;;;;;;;;103352:43:0;103448:1:::1;103406:23:::0;:43;103460:24;:53;103574:11:::1;103532:24:::0;:53;-1:-1:-1;;;103095:13:0::1;103604:25:::0;103646:6:::1;103604:25:::0;:48;103095:13;103835:28;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;103835:28:0;::::1;::::0;101418:80:::1;103825:39:::0;103866:10:::1;:8;:10::i;:::-;103886:4;103797:95;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;103797:95:0;;::::1;::::0;;;;;;103787:106;;103797:95:::1;103787:106:::0;;::::1;::::0;103768:16:::1;:125:::0;103904:89:::1;103937:16:::0;103955:18;103975:17;103904:32:::1;:89::i;:::-;104009:77;104040:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;104030:55;;;;;;104009:77;;;;;;:::i;:::-;;;;;;;;102923:1171:::0;;;;:::o;118378:309::-;118493:14;;;118505:1;118493:14;;;118471:19;118493:14;;;;;;118451:7;;118471:19;118493:14;;;;;;;;;;;;;;;;;;;;;118471:36;;118528:33;118552:8;118528:23;:33::i;:::-;118518:4;118523:1;118518:7;;;;;;;;;;;;;:43;;;;118582:27;118603:5;118582:20;:27::i;:::-;118572:4;118577:1;118572:7;;;;;;;;;;;;;:37;;;;118650:26;118671:4;118650:20;:26::i;:::-;118640:37;;;;;;;;118378:309;-1:-1:-1;;;;118378:309:0:o;101505:31::-;;;;:::o;109668:406::-;109777:20;109841:10;:17;109818:12;:19;:40;109810:78;;;;-1:-1:-1;;;109810:78:0;;;;;;;:::i;:::-;109919:12;:19;-1:-1:-1;;;;;109908:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109908:31:0;;109899:40;;109954:6;109950:116;109966:12;:19;109964:1;:21;109950:116;;;110017:49;110035:12;110048:1;110035:15;;;;;;;;;;;;;;110052:10;110063:1;110052:13;;;;;;;;;;;;;;110017:17;:49::i;:::-;110005:6;110012:1;110005:9;;;;;;;;;;;;;;;;;:61;109987:3;;109950:116;;;;109668:406;;;;:::o;102225:73::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;102225:73:0;;:::o;102028:44::-;;;;;;;;;;;;;:::o;108657:406::-;108766:20;108830:10;:17;108807:12;:19;:40;108799:78;;;;-1:-1:-1;;;108799:78:0;;;;;;;:::i;:::-;108908:12;:19;-1:-1:-1;;;;;108897:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;108897:31:0;;108888:40;;108943:6;108939:116;108955:12;:19;108953:1;:21;108939:116;;;109006:49;109024:12;109037:1;109024:15;;;;;;;;;;;;;;109041:10;109052:1;109041:13;;;;;;;;;;;;;;109006:17;:49::i;:::-;108994:6;109001:1;108994:9;;;;;;;;;;;;;;;;;:61;108976:3;;108939:116;;72667:139;-1:-1:-1;;;;;72786:10:0;72774:22;72735:4;72759:39;;;:6;:39;;;;;;;72667:139::o;101804:70::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;101804:70:0;;:::o;123137:309::-;71176:8;;123320:20;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;123360:78:::1;123380:11;123393:5;123400:8;123410:4;123416:6;123424:8;123434:3;123360:19;:78::i;:::-;123353:85:::0;123137:309;-1:-1:-1;;;;;;;;123137:309:0:o;105018:346::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;-1:-1:-1;;;;;105135:32:0;::::1;105132:224;;105184:6;:24;::::0;;:33;;;-1:-1:-1;;;105184:24:0::1;105232:25:::0;;:34;;;105132:224:::1;;;105297:59;::::0;-1:-1:-1;;;105297:59:0;;-1:-1:-1;;;;;105297:44:0;::::1;::::0;::::1;::::0;:59:::1;::::0;105342:5;;105349:6;;105297:59:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;105018:346:::0;;;:::o;116758:686::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;116880:10:::1;:8;:10::i;:::-;116894:1;116880:15;:34;;;;116899:10;:8;:10::i;:::-;116913:1;116899:15;116880:34;116872:78;;;;-1:-1:-1::0;;;116872:78:0::1;;;;;;;:::i;:::-;116969:29;116986:11;116969:16;:29::i;:::-;116961:65;;;;-1:-1:-1::0;;;116961:65:0::1;;;;;;;:::i;:::-;117045:16;117062:6;117045:24;;;;;;:::i;:::-;;;;;;;;;;;;;;117073:1;117045:29;117037:65;;;;-1:-1:-1::0;;;117037:65:0::1;;;;;;;:::i;:::-;117131:10;:8;:10::i;:::-;117116:11;:25;117113:150;;;117225:5;-1:-1:-1::0;;;;;117208:30:0::1;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;117208:32:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;117192:50;;;;;;117180:6;117164:24;;;;;;:78;117156:107;;;;-1:-1:-1::0;;;117156:107:0::1;;;;;;;:::i;:::-;117329:5;-1:-1:-1::0;;;;;117324:11:0::1;117317:3;117302:11;:18;;117301:34;117274:16;117291:6;117274:24;;;;;;:::i;:::-;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;:61;;;;117346:16:::1;:29:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;117346:29:0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;117430:5;-1:-1:-1::0;;;;;117391:45:0::1;117417:11;117409:6;117391:45;;;;;;:::i;:::-;;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;116758:686:::0;;;:::o;115974:104::-;116047:16;:23;115974:104;:::o;107536:441::-;107686:20;105417:10;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;107728:76:::1;::::0;-1:-1:-1;;;107728:76:0;;-1:-1:-1;;;;;107728:50:0;::::1;::::0;::::1;::::0;:76:::1;::::0;107779:12;;107793:10;;107728:76:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;107728:76:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;107719:85;;107819:6;107815:154;107831:12;:19;107829:1;:21;107815:154;;;107927:12;107940:1;107927:15;;;;;;;;;;;;;;-1:-1:-1::0;;;;;107875:94:0::1;107907:18;-1:-1:-1::0;;;;;107875:94:0::1;107893:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;107875:94:0::1;;107944:10;107955:1;107944:13;;;;;;;;;;;;;;107959:6;107966:1;107959:9;;;;;;;;;;;;;;107875:94;;;;;;;:::i;:::-;;;;;;;;107852:3;;107815:154;;;;107536:441:::0;;;;;:::o;110780:104::-;110854:15;:22;110780:104;:::o;100994:170::-;101040:124;100994:170;:::o;114198:237::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;114359:68:::1;114376:11;114389:5;114396:8;114406:20;114359:16;:68::i;:::-;114198:237:::0;;;;:::o;72529:132::-;72634:17;72595:4;72619:34;;;:6;:34;;;;;;;72529:132::o;112160:234::-;112229:4;;112246:117;112262:19;:17;:19::i;:::-;112260:1;:21;112246:117;;;112326:7;112304:15;112320:1;112304:18;;;;;;;;;;;;;;;;:29;112301:62;;;112359:4;112352:11;;;;;112301:62;112283:3;;112246:117;;;-1:-1:-1;112381:5:0;;112160:234;-1:-1:-1;;112160:234:0:o;72427:96::-;72480:4;72504:11;;;:6;:11;;;;;;;72427:96::o;116353:397::-;116406:23;116431:22;116455:23;116501:16;116491:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;116491:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;116537:16:0;:23;116491:26;;-1:-1:-1;116537:23:0;;-1:-1:-1;;;;;;;116582:13:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116582:13:0;;116571:24;;116629:1;-1:-1:-1;;;;;116615:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116615:16:0;;116606:25;;116646:6;116642:100;116658:1;116656;:3;116642:100;;;116706:36;116722:16;116739:1;116722:19;;;;;;;;;;;;;;;;;;116706:36;;;;;;;-1:-1:-1;;116706:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116722:19;116706:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:36::i;:::-;116680:8;116689:1;116680:11;;;;;;;;;;;;;116693:6;116700:1;116693:9;;;;;;;;-1:-1:-1;;;;;116679:63:0;;;116693:9;;;;;;;;;;;116679:63;;;;;116661:3;;116642:100;;;;116353:397;;;;:::o;109075:292::-;109174:10;105417;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;109205:22:0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;:37:::1;::::0;109232:9;109205:26:::1;:37::i;:::-;-1:-1:-1::0;;;;;109253:22:0;::::1;;::::0;;;:11:::1;:22;::::0;;;;:30;;;109197:45;;-1:-1:-1;109317:12:0::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;109299:60:0::1;;109342:9;109353:5;109299:60;;;;;;;:::i;:::-;;;;;;;;109075:292:::0;;;;:::o;114447:1413::-;-1:-1:-1;;;114658:21:0;;:6;:21;;;;114647:33;;:10;:33::i;:::-;-1:-1:-1;;;114699:22:0;;:6;:22;;-1:-1:-1;;;;;;;;;;;114699:22:0;:27;;:73;;;114739:33;114752:12;:10;:12::i;:::-;114766:5;114739:12;:33::i;:::-;-1:-1:-1;;;;;114730:42:0;:5;-1:-1:-1;;;;;114730:42:0;;114699:73;114691:99;;;;-1:-1:-1;;;114691:99:0;;;;;;;:::i;:::-;114810:17;;114851:26;-1:-1:-1;;;114851:9:0;:26::i;:::-;114846:1;:31;;114838:62;;;;-1:-1:-1;;;114838:62:0;;;;;;;:::i;:::-;114915:6;114911:863;114927:1;114925;:3;114911:863;;;114954:6;114950:124;114966:1;114964;:3;114950:124;;;115026:10;115037:1;115026:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;114999:50:0;:10;115010:1;114999:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;114999:50:0;;;114991:83;;;;-1:-1:-1;;;114991:83:0;;;;;;;:::i;:::-;114969:3;;114950:124;;;;115089:18;101040:124;115150:11;115163:5;115197:8;115180:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;115170:37;;;;;;115236:20;115219:38;;;;;;;;:::i;:::-;;;;;;;;;;;;;115209:49;;;;;;115260:10;115271:1;115260:13;;;;;;;;;;;;;;:23;;;115120:164;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;115110:175;;;;;;115089:196;;115300:14;115356:16;;115374:10;115327:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;115317:69;;;;;;115300:86;;115401:17;115421:68;115431:6;115439:10;115450:1;115439:13;;;;;;;;;;;;;;:15;;;115456:10;115467:1;115456:13;;;;;;;;;;;;;;:15;;;115473:10;115484:1;115473:13;;;;;;;;;;;;;;:15;;;115421:68;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;115421:68:0;;-1:-1:-1;;115421:68:0;;;-1:-1:-1;;;;;;;115512:23:0;;115504:53;;;;-1:-1:-1;;;115504:53:0;;;;;;;:::i;:::-;115593:10;115604:1;115593:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;115580:36:0;:9;-1:-1:-1;;;;;115580:36:0;;115572:61;;;;-1:-1:-1;;;115572:61:0;;;;;;;:::i;:::-;115648:46;115667:10;115678:1;115667:13;;;;;;;;;;;;;;:23;;;115692:1;115648:18;:46::i;:::-;;115752:9;-1:-1:-1;;;;;115714:48:0;115745:5;-1:-1:-1;;;;;115714:48:0;115732:11;115714:48;;;;;;;;;;-1:-1:-1;;;114930:3:0;;114911:863;;;;115784:68;115801:11;115814:5;115821:8;115831:20;115784:16;:68::i;111176:972::-;111272:22;111296:37;111349:13;111366:38;111384:19;111366:17;:38::i;:::-;111346:58;-1:-1:-1;;;;;;;111418:19:0;;111415:64;;-1:-1:-1;111460:19:0;111415:64;111490:6;111515;111511:140;111527:19;:17;:19::i;:::-;111525:1;:21;111511:140;;;-1:-1:-1;;;;;111569:26:0;;111627:1;111569:26;;;:19;:26;;;;;111596:15;:18;;111627:1;;111596:15;111612:1;;111596:18;;;;;;;;;;;;;;;;;;111569:46;;;;;;;;;;;;;-1:-1:-1;;;;;111569:46:0;:60;111566:85;;111648:3;;;;;111566:85;111548:3;;111511:140;;;;111684:1;-1:-1:-1;;;;;111673:13:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;111673:13:0;;111662:24;;111734:1;-1:-1:-1;;;;;111720:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;111720:16:0;;111697:39;;111747:6;111772;111768:373;111784:19;:17;:19::i;:::-;111782:1;:21;111768:373;;;111825:12;111840:15;111856:1;111840:18;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;111902:26:0;;;;;:19;:26;;;;;;:35;;;;;;;;;;;111840:18;;-1:-1:-1;111902:35:0;111955:32;;111952:178;;112022:7;112008:8;112017:1;112008:11;;;;;;;;;;;;;:21;;;;;112074:18;112048:20;112069:1;112048:23;;;;;;;;-1:-1:-1;;;;;112048:44:0;;;:23;;;;;;;;;;;:44;112111:3;;;;;111952:178;-1:-1:-1;;111805:3:0;;111768:373;;;;111176:972;;;;;;:::o;104761:174::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;-1:-1:-1;;;;;104853:20:0;::::1;;::::0;;;:10:::1;:20;::::0;;;;;:29;;-1:-1:-1;;104853:29:0::1;::::0;::::1;;::::0;;::::1;::::0;;;104898;;104853;;:20;104898:29:::1;::::0;::::1;104761:174:::0;;:::o;71501:151::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;71591:8:::1;::::0;71567:45:::1;::::0;71609:1:::1;::::0;-1:-1:-1;;;;;71591:8:0::1;::::0;71567:45:::1;::::0;71609:1;;71567:45:::1;71623:8;:21:::0;;-1:-1:-1;;;;;;71623:21:0::1;::::0;;71501:151::o;110896:268::-;-1:-1:-1;;;;;111040:32:0;110973:16;111040:32;;;:18;:32;;;;;;111113:3;111097:19;;;;110896:268::o;110086:281::-;110185:10;105417;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;110216:22:0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;110252:17;;::::1;110249:52;;;110296:5;110284:17;;110249:52;110319:40;110338:9;110349;110319:18;:40::i;104153:359::-:0;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;104305:22:::1;:37;::::0;;:58;;-1:-1:-1;;;;;104305:58:0;;::::1;-1:-1:-1::0;;;;;;104305:58:0;;::::1;;::::0;;;104374:39;:60;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;;;104305:37:0::1;104445:38:::0;;:59;;;;;::::1;::::0;::::1;;::::0;;104153:359::o;106539:265::-;106691:20;105417:10;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;106731:65:::1;106751:18;106771:12;106785:10;106731:19;:65::i;:::-;106724:72:::0;106539:265;-1:-1:-1;;;;106539:265:0:o;104524:174::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;104620:26:::1;:11;104634:12:::0;;104620:26:::1;:::i;:::-;;104662:28;104677:12;;104662:28;;;;;;;:::i;:::-;;;;;;;;104524:174:::0;;:::o;120460:1122::-;120644:8;;120591:21;;-1:-1:-1;;;;;120644:8:0;120628:12;:10;:12::i;:::-;-1:-1:-1;;;;;120628:24:0;;120625:73;;-1:-1:-1;;;120678:19:0;;:6;:19;;-1:-1:-1;;;;;;;;;;;120678:19:0;120667:31;;:10;:31::i;:::-;120757:1;120717:14;120757:1;120732:12;:10;:12::i;:::-;-1:-1:-1;;;;;120717:28:0;;;;;;;;;;;;;;-1:-1:-1;120717:28:0;;;:42;120709:84;;;;-1:-1:-1;;;120709:84:0;;;;;;;:::i;:::-;120806:12;120848:10;:8;:10::i;:::-;120860:12;:10;:12::i;:::-;120831:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;120821:53;;;;;;120806:68;;120887:21;120911:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;120887:68;;121054:4;121043:8;121037:15;121032:2;121022:8;121018:17;121015:1;121007:52;120990:69;;121114:13;-1:-1:-1;;;;;121080:82:0;;121171:4;-1:-1:-1;;;121296:4:0;121303:12;:10;:12::i;:::-;121317:4;121323:6;121331:8;121341:11;121195:158;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;121195:158:0;;;;;;;;;;;;;;-1:-1:-1;;;;;121195:158:0;-1:-1:-1;;;121195:158:0;;;121080:274;;;;;-1:-1:-1;;;;;;121080:274:0;;;;;;;121195:158;121080:274;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121406:13;121375:14;:28;121390:12;:10;:12::i;:::-;-1:-1:-1;;;;;121375:28:0;;;;;;;;;;;;;;-1:-1:-1;121375:28:0;:44;;-1:-1:-1;;;;;;121375:44:0;;;;;;;;;;;121430:43;121446:13;121461:11;121430:15;:43::i;:::-;121560:13;-1:-1:-1;;;;;121489:85:0;121509:12;:10;:12::i;:::-;-1:-1:-1;;;;;121489:85:0;;121523:4;121529:6;121537:8;121547:11;121489:85;;;;;;;;;:::i;:::-;;;;;;;;120460:1122;;;;;;;;:::o;106816:335::-;106945:10;105417;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;106976:71:::1;::::0;-1:-1:-1;;;106976:71:0;;-1:-1:-1;;;;;106976:49:0;::::1;::::0;::::1;::::0;:71:::1;::::0;107026:9;;107037;;106976:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106968:79;;107115:9;-1:-1:-1::0;;;;;107063:80:0::1;107095:18;-1:-1:-1::0;;;;;107063:80:0::1;107081:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;107063:80:0::1;;107126:9;107137:5;107063:80;;;;;;;:::i;:::-;;;;;;;;106816:335:::0;;;;;:::o;101939:43::-;;;;;;;;;;;;;;;:::o;73406:141::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;73494:45:::1;73513:17:::0;;::::1;73533:5:::0;73494:10:::1;:45::i;71841:122::-:0;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;71921:34:::1;71943:11;71921:21;:34::i;:::-;71841:122:::0;:::o;101610:48::-;;;;;;;;;;;;-1:-1:-1;;;;;101610:48:0;;:::o;118783:482::-;118868:7;118987:4;119038:11;119051:15;119021:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;119011:57;;;;;;119085:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;119075:55;;;;;;118918:336;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;118918:336:0;;;;;;;;;118908:347;;118918:336;118908:347;;;;;118783:482;-1:-1:-1;;;118783:482:0:o;102569:342::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;17725:19;17748:12;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;102753:38:::1;102781:9;102753:27;:38::i;:::-;102802:101;102839:16;102857:18;102877:17;102896:6;102802:36;:101::i;:::-;17872:14:::0;17868:57;;;17912:5;17897:20;;-1:-1:-1;;17897:20:0;;;17868:57;102569:342;;;;;;:::o;102532:28::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;102532:28:0;;-1:-1:-1;102532:28:0;:::o;109490:172::-;109571:20;109611:43;109630:11;109611:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;109611:43:0;;;;;;;;;;;;;;;;;;;;;109643:10;109611:18;:43::i;119273:1067::-;119404:8;;119353:19;;-1:-1:-1;;;;;119404:8:0;119388:12;:10;:12::i;:::-;-1:-1:-1;;;;;119388:24:0;;119385:201;;-1:-1:-1;;;119440:19:0;;:6;:19;;-1:-1:-1;;;;;;;;;;;119440:19:0;119429:31;;:10;:31::i;:::-;-1:-1:-1;;;119483:22:0;;:6;:22;;-1:-1:-1;;;;;;;;;;;119483:22:0;:27;;:73;;;119523:33;119536:12;:10;:12::i;:::-;119550:5;119523:12;:33::i;:::-;-1:-1:-1;;;;;119514:42:0;:5;-1:-1:-1;;;;;119514:42:0;;119483:73;119475:99;;;;-1:-1:-1;;;119475:99:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;119604:19:0;;;119635:1;119604:19;;;:12;:19;;;;;;;:33;119596:73;;;;-1:-1:-1;;;119596:73:0;;;;;;;:::i;:::-;119682:12;119724:10;:8;:10::i;:::-;119736:5;119707:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;119697:46;;;;;;119682:61;;119756:21;119780:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;119756:68;;119921:4;119910:8;119904:15;119899:2;119889:8;119885:17;119882:1;119874:52;119859:67;;119981:11;-1:-1:-1;;;;;119947:80:0;;120036:4;-1:-1:-1;;;120129:4:0;120136:5;120058:84;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;120058:84:0;;;;;;;;;;;;;;-1:-1:-1;;;;;120058:84:0;-1:-1:-1;;;120058:84:0;;;119947:196;;;;;-1:-1:-1;;;;;;119947:196:0;;;;;;;120058:84;119947:196;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;120164:19:0;;;;;;;:12;:19;;;;;;;;;:33;;-1:-1:-1;;;;;;120164:33:0;;;;;;;;;;;120237:27;;-1:-1:-1;;;120237:27:0;;;;120208:57;;120164:33;;:19;120237:25;;:27;;;;;120164:19;120237:27;;;;;120164:19;120237:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;120208:15;:57::i;:::-;120320:11;-1:-1:-1;;;;;120281:51:0;120313:5;-1:-1:-1;;;;;120281:51:0;120299:12;:10;:12::i;:::-;-1:-1:-1;;;;;120281:51:0;;;;;;;;;;;119273:1067;;;;;;:::o;123458:1480::-;-1:-1:-1;;;123654:20:0;123698:19;;;:6;:19;;-1:-1:-1;;;;;;;;;;;123698:19:0;123687:31;;:10;:31::i;:::-;-1:-1:-1;;;;;123737:19:0;;;;:50;;-1:-1:-1;;;;123760:22:0;;:6;:22;;-1:-1:-1;;;;;;;;;;;123760:22:0;:27;123737:50;:96;;;;123800:33;123813:12;:10;:12::i;:::-;123827:5;123800:12;:33::i;:::-;-1:-1:-1;;;;;123791:42:0;:5;-1:-1:-1;;;;;123791:42:0;;123737:96;123729:122;;;;-1:-1:-1;;;123729:122:0;;;;;;;:::i;:::-;-1:-1:-1;;;123891:23:0;;:6;:23;;;;123870:17;;:44;;123862:75;;;;-1:-1:-1;;;123862:75:0;;;;;;;:::i;:::-;123952:6;123948:883;123964:10;:17;123962:1;:19;123948:883;;;124007:6;124003:124;124019:1;124017;:3;124003:124;;;124079:10;124090:1;124079:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;124052:50:0;:10;124063:1;124052:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;124052:50:0;;;124044:83;;;;-1:-1:-1;;;124044:83:0;;;;;;;:::i;:::-;124022:3;;124003:124;;;;124142:12;101217:148;124195:12;:10;:12::i;:::-;124209:11;124222:5;124245:4;124229:22;;;;;;124269:6;124253:24;;;;;;124279:8;124289:3;124294:10;124305:1;124294:13;;;;;;;;;;;;;;:23;;;124167:151;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;124157:162;;;;;;124142:177;;124380:16;;124398:4;124351:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;124341:63;;;;;;124334:70;;124419:17;124439:66;124449:4;124455:10;124466:1;124455:13;;;;;;;;;;;;;;:15;;;124472:10;124483:1;124472:13;;;;;;;;;;;;;;:15;;;124489:10;124500:1;124489:13;;;;;;;;;;;;;;:15;;;124439:66;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;124439:66:0;;-1:-1:-1;;124439:66:0;;;-1:-1:-1;;;;;;;124528:23:0;;124520:53;;;;-1:-1:-1;;;124520:53:0;;;;;;;:::i;:::-;124609:10;124620:1;124609:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;124596:36:0;:9;-1:-1:-1;;;;;124596:36:0;;124588:61;;;;-1:-1:-1;;;124588:61:0;;;;;;;:::i;:::-;124664:46;124683:10;124694:1;124683:13;;;;;;;124664:46;;124809:9;-1:-1:-1;;;;;124730:89:0;124766:12;:10;:12::i;:::-;-1:-1:-1;;;;;124730:89:0;124759:5;-1:-1:-1;;;;;124730:89:0;;124746:11;124780:4;124786:6;124794:8;124804:3;124730:89;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;123983:3:0;;123948:883;;;;124848:82;124868:11;124881:5;124888:12;:10;:12::i;:::-;124902:4;124908:6;124916:8;124926:3;124848:19;:82::i;:::-;124841:89;123458:1480;-1:-1:-1;;;;;;;;;123458:1480:0:o;112406:288::-;71176:8;;-1:-1:-1;;;;;71176:8:0;71162:10;:22;71154:31;;;;;;112501:10:::1;:8;:10::i;:::-;112515:1;112501:15;:34;;;;112520:10;:8;:10::i;:::-;112534:1;112520:15;112501:34;112493:78;;;;-1:-1:-1::0;;;112493:78:0::1;;;;;;;:::i;:::-;112591:26;112608:8;112591:16;:26::i;:::-;112590:27;112582:63;;;;-1:-1:-1::0;;;112582:63:0::1;;;;;;;:::i;:::-;112656:15;:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;112656:30:0;;;;;::::1;::::0;112406:288::o;70930:183::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;17725:19;17748:12;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;71024:8:::1;:20:::0;;-1:-1:-1;;;;;;71024:20:0::1;-1:-1:-1::0;;;;;71024:20:0;;::::1;::::0;;;::::1;::::0;;;;71060:45:::1;::::0;71096:8;::::1;::::0;-1:-1:-1;;71060:45:0::1;::::0;-1:-1:-1;;71060:45:0::1;17872:14:::0;17868:57;;;17912:5;17897:20;;-1:-1:-1;;17897:20:0;;;70930:183;;:::o;116090:251::-;116158:16;116176:13;116202:20;116225:16;116242:6;116225:24;;;;;;:::i;:::-;;;;;;;;;;;;;;;116290:3;116274:19;;;;116225:24;;-1:-1:-1;116090:251:0;-1:-1:-1;;;116090:251:0:o;107989:335::-;108118:10;105417;:24;105428:12;:10;:12::i;:::-;-1:-1:-1;;;;;105417:24:0;;;;;;;;;;;;-1:-1:-1;105417:24:0;;;;105409:50;;;;-1:-1:-1;;;105409:50:0;;;;;;;:::i;:::-;108149:71:::1;::::0;-1:-1:-1;;;108149:71:0;;-1:-1:-1;;;;;108149:49:0;::::1;::::0;::::1;::::0;:71:::1;::::0;108199:9;;108210;;108149:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108141:79;;108288:9;-1:-1:-1::0;;;;;108236:80:0::1;108268:18;-1:-1:-1::0;;;;;108236:80:0::1;108254:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;108236:80:0::1;;108299:9;108310:5;108236:80;;;;;;;:::i;101704:50::-:0;;;;;;;;;;;;-1:-1:-1;;;;;101704:50:0;;:::o;72814:130::-;72882:11;;;;:6;:11;;;;;;:20;;72879:57;;72917:11;;;;:6;:11;;;;;;:19;72814:130::o;19543:106::-;19631:10;19543:106;:::o;105862:431::-;106044:76;;-1:-1:-1;;;106044:76:0;;106002:20;;-1:-1:-1;;;;;106044:50:0;;;;;:76;;106095:12;;106109:10;;106044:76;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106044:76:0;;;;;;;;;;;;:::i;:::-;106035:85;;106135:6;106131:154;106147:12;:19;106145:1;:21;106131:154;;;106243:12;106256:1;106243:15;;;;;;;;;;;;;;-1:-1:-1;;;;;106191:94:0;106223:18;-1:-1:-1;;;;;106191:94:0;106209:12;:10;:12::i;:::-;-1:-1:-1;;;;;106191:94:0;;106260:10;106271:1;106260:13;;;;;;;;;;;;;;106275:6;106282:1;106275:9;;;;;;;;;;;;;;106191:94;;;;;;;:::i;:::-;;;;;;;;106168:3;;106131:154;;82071:98;82151:9;;82143:19::o;64182:378::-;64340:4;64334:11;;-1:-1:-1;;;64378:55:0;;64373:2;64366:10;;64359:75;64468:2;64461:10;;64448:24;;;64242:12;;64529:23;64334:11;64529;:23::i;:::-;64522:30;64182:378;-1:-1:-1;;;64182:378:0:o;64707:121::-;64761:12;64793:27;64805:14;64814:4;64805:8;:14::i;:::-;64793:11;:27::i;63552:192::-;63616:12;63641:17;63661:13;63669:4;63661:7;:13::i;:::-;63641:33;;63692:44;63699:30;63712:4;:11;63725:3;63699:12;:30::i;:::-;63731:4;63692:6;:44::i;121745:1198::-;121911:20;;-1:-1:-1;;;;;121971:19:0;;;121970:40;;122005:5;121970:40;;;121994:8;121970:40;122084:1;122029:26;;;:13;:26;;;;;;;;-1:-1:-1;;;;;122029:43:0;;;;;;;;;;;121944:66;;-1:-1:-1;122029:43:0;:57;122021:98;;;;-1:-1:-1;;;122021:98:0;;;;;;;:::i;:::-;122132:12;122174:11;122187:15;122157:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;122147:57;;;;;;122132:72;;122217:21;122241:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;122217:68;;122383:4;122372:8;122366:15;122361:2;122351:8;122347:17;122344:1;122336:52;122320:68;;122443:12;-1:-1:-1;;;;;122409:81:0;;122499:4;-1:-1:-1;;;122638:4:0;122645:11;122658:5;122665:8;122675:4;122681:6;122689:8;122699:3;122522:181;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;122522:181:0;;;;;;;;;;;;;;-1:-1:-1;;;;;122522:181:0;-1:-1:-1;;;122522:181:0;;;122409:295;;;;;-1:-1:-1;;;;;;122409:295:0;;;;;;;122522:181;122409:295;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;122725:26:0;;;;:13;:26;;;;;;;;-1:-1:-1;;;;;122725:43:0;;;;;;;;;;:58;;-1:-1:-1;;;;;;122725:58:0;;;;;;;;;;-1:-1:-1;122794:34:0;122725:58;122824:3;122794:15;:34::i;:::-;122922:12;-1:-1:-1;;;;;122844:91:0;122883:8;-1:-1:-1;;;;;122844:91:0;122876:5;-1:-1:-1;;;;;122844:91:0;;122863:11;122893:4;122899:6;122907:8;122917:3;122844:91;;;;;;;;;;:::i;:::-;;;;;;;;121745:1198;;;;;;;;;;;;:::o;112706:1377::-;112864:10;:8;:10::i;:::-;112878:1;112864:15;:34;;;;112883:10;:8;:10::i;:::-;112897:1;112883:15;112864:34;112856:78;;;;-1:-1:-1;;;112856:78:0;;;;;;;:::i;:::-;112972:20;:27;112953:8;:15;:46;112945:84;;;;-1:-1:-1;;;112945:84:0;;;;;;;:::i;:::-;113048:29;113065:11;113048:16;:29::i;:::-;113040:65;;;;-1:-1:-1;;;113040:65:0;;;;;;;:::i;:::-;113120:6;113116:960;113132:8;:15;113130:1;:17;113116:960;;;113177:29;113194:8;113203:1;113194:11;;;;;;;;;;;;;;113177:16;:29::i;:::-;113169:61;;;;-1:-1:-1;;;113169:61:0;;;;;;;:::i;:::-;113262:20;113283:1;113262:23;;;;;;;;;;;;;;-1:-1:-1;;;;;113253:32:0;:5;-1:-1:-1;;;;;113253:32:0;;:94;;;;113316:31;113328:11;113341:5;113316:11;:31::i;:::-;-1:-1:-1;;;;;113289:58:0;:20;113310:1;113289:23;;;;;;;;;;;;;;-1:-1:-1;;;;;113289:58:0;;113253:94;:122;;;-1:-1:-1;113367:8:0;;-1:-1:-1;;;;;113367:8:0;113351:12;:10;:12::i;:::-;-1:-1:-1;;;;;113351:24:0;;113253:122;113245:169;;;;-1:-1:-1;;;113245:169:0;;;;;;;:::i;:::-;113885:5;-1:-1:-1;;;;;113880:11:0;113873:3;113858:11;:18;;113857:34;113811:18;:43;113830:20;113851:1;113830:23;;;;;;;;;;;;;;-1:-1:-1;;;;;113811:43:0;-1:-1:-1;;;;;113811:43:0;;;;;;;;;;;;:80;;;;113948:20;113969:1;113948:23;;;;;;;;;;;;;;113906:19;:26;113926:5;-1:-1:-1;;;;;113906:26:0;-1:-1:-1;;;;;113906:26:0;;;;;;;;;;;;:39;113933:8;113942:1;113933:11;;;;;;;;;;;;;;113906:39;;;;;;;;;;;;:65;;;;;-1:-1:-1;;;;;113906:65:0;;;;;-1:-1:-1;;;;;113906:65:0;;;;;;113991:73;114007:11;114020:5;114027:8;114036:1;114027:11;;;;;;;;;;;;;;114040:20;114061:1;114040:23;;;;;;;;;;;;;;113991:73;;;;;;;;;:::i;:::-;;;;;;;;113149:3;;113116:960;;;;112706:1377;;;;:::o;23912:181::-;23970:7;24002:5;;;24026:6;;;;24018:46;;;;-1:-1:-1;;;24018:46:0;;;;;;;:::i;125126:367::-;125205:22;125214:3;125219:7;125205:8;:22::i;:::-;125192:9;:35;;125184:62;;;;-1:-1:-1;;;125184:62:0;;;;;;;:::i;:::-;-1:-1:-1;;;125257:21:0;125289:15;:6;:15;;;;-1:-1:-1;;;;;125319:19:0;;125316:76;;-1:-1:-1;125385:4:0;125316:76;125403:25;;-1:-1:-1;;;;;125403:14:0;;;125418:9;125403:25;;;;;;;;;125418:9;125403:14;:25;;;;;;;;;;;;;;;;;;;;;125468:5;-1:-1:-1;;;;;125444:41:0;125454:12;:10;:12::i;:::-;-1:-1:-1;;;;;125444:41:0;;125475:9;125444:41;;;;;;:::i;:::-;;;;;;;;125126:367;;:::o;110379:282::-;-1:-1:-1;;;;;110499:22:0;;110468:10;110499:22;;;:11;:22;;;;;;:37;;110526:9;110499:26;:37::i;:::-;-1:-1:-1;;;;;110547:22:0;;;;;;:11;:22;;;;;:30;;;110491:45;;-1:-1:-1;110611:12:0;:10;:12::i;:::-;-1:-1:-1;;;;;110593:60:0;;110636:9;110647:5;110593:60;;;;;;;:::i;105491:359::-;-1:-1:-1;;;105574:10:0;105595:24;;;:6;:24;;;;105587:43;;105625:4;;105587:33;;:3;;:7;:33::i;:::-;:37;;:43::i;:::-;105675:11;:18;105574:56;;-1:-1:-1;105641:20:0;;-1:-1:-1;;;;;105664:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105664:30:0;;105641:53;;105709:6;105705:66;105721:6;:13;105719:1;:15;105705:66;;;105766:5;105754:6;105761:1;105754:9;;;;;;;;;;;;;;;;;:17;105736:3;;105705:66;;;;105782:60;105802:18;105822:11;105782:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105782:60:0;;;;;;;;;;;;;;;;;;;;;105835:6;105782:19;:60::i;72122:209::-;-1:-1:-1;;;;;72202:25:0;;72194:34;;;;;;72268:8;;72244:46;;-1:-1:-1;;;;;72244:46:0;;;;72268:8;;72244:46;;72268:8;;72244:46;72301:8;:22;;-1:-1:-1;;;;;;72301:22:0;-1:-1:-1;;;;;72301:22:0;;;;;;;;;;72122:209::o;18019:508::-;18436:4;18482:17;18514:7;18019:508;:::o;63020:326::-;63083:12;63108:20;63143:4;:11;63158:1;63143:16;:41;;;;;63181:3;63169:4;63174:1;63169:7;;;;;;;;;;;;;;63163:21;;63143:41;63139:175;;;-1:-1:-1;63211:4:0;63139:175;;;63258:44;63265:30;63278:4;:11;63291:3;63265:12;:30::i;:::-;63297:4;63258:6;:44::i;66726:472::-;66817:13;;;66827:2;66817:13;;;;;;;;;66775:12;;;;66817:13;;;;;;;;;;;-1:-1:-1;66817:13:0;66800:30;;66885:2;66880;66877:1;66873:10;66866:22;66910:6;66927:106;66943:2;66939:1;:6;66927:106;;;66971:1;66973;66971:4;;;;;;;;;;;;-1:-1:-1;;;;;;66971:4:0;:9;66967:55;;67001:5;;66967:55;66947:3;;66927:106;;;67043:16;67077:1;67072:2;:6;-1:-1:-1;;;;;67062:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67062:17:0;;67043:36;;67095:6;67090:80;67111:3;:10;67107:1;:14;67090:80;;;67152:6;;67154:3;;;;67152:1;;:6;;;;;;;;;;;;;;67143:3;67147:1;67143:6;;;;;;;;;;;:15;-1:-1:-1;;;;;67143:15:0;;;;;;;;-1:-1:-1;67123:3:0;;67090:80;;;-1:-1:-1;67187:3:0;66726:472;-1:-1:-1;;;;66726:472:0:o;68362:761::-;68423:12;68452:5;:12;68468:1;68452:17;68448:69;;;-1:-1:-1;68493:12:0;;;68503:1;68493:12;;;;;;;;68486:19;;68448:69;68529:8;;68565:84;68581:5;:12;68577:1;:16;68565:84;;;68622:5;68628:1;68622:8;;;;;;;;;;;;;;:15;68615:22;;;;68595:3;;;;;;;68565:84;;;68661:22;68696:3;-1:-1:-1;;;;;68686:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68686:14:0;-1:-1:-1;68711:17:0;;-1:-1:-1;68661:39:0;-1:-1:-1;68781:4:0;68766:20;;68800:287;68815:5;:12;68811:1;:16;68800:287;;;68849:17;68869:5;68875:1;68869:8;;;;;;;;;;;;;;68849:28;;68906:12;68965:4;68959;68955:15;68944:26;;68987:42;68994:12;69008:7;69017:4;:11;68987:6;:42::i;:::-;69060:5;69066:1;69060:8;;;;;;;;;;;;;;:15;69044:31;;;;68800:287;;68829:3;;;;;;;68800:287;;65777:689;65844:12;65869:20;65910:2;65904:3;:8;65900:534;;;65939:12;;;65949:1;65939:12;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65929:22:0;-1:-1:-1;65987:12:0;;;66001:2;65979:25;;;65966:7;65974:1;65966:10;;;;;;;;;;;:38;-1:-1:-1;;;;;65966:38:0;;;;;;;;;65900:534;;;66037:11;66072:1;66088:91;66101:1;66095:3;:7;;;;;;:12;66088:91;;66128:8;;;;;66160:3;66155:8;66088:91;;;66215:6;66224:1;66215:10;-1:-1:-1;;;;;66205:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66205:21:0;-1:-1:-1;66195:31:0;-1:-1:-1;66280:2:0;66262:15;;;:20;66284:2;66254:33;;;66241:7;66249:1;66241:10;;;;;;;;;;;:46;-1:-1:-1;;;;;66241:46:0;;;;;;;;;66310:1;66306:5;;66302:121;66318:6;66313:1;:11;66302:121;;66399:3;66392:1;66385:6;:8;66379:3;:15;66372:3;:23;;;;;;66371:31;;;;;;66404:2;66363:44;;;66350:7;66358:1;66350:10;;;;;;;;;;;:57;-1:-1:-1;;;;;66350:57:0;;;;;;;;-1:-1:-1;66326:3:0;;66302:121;;;65900:534;;66451:7;-1:-1:-1;65777:689:0;;;;:::o;69423:1211::-;69510:12;69535:22;69613:4;69607:11;69594:24;;69654:9;69648:16;69696:6;69685:9;69678:25;69744:4;69733:9;69729:20;69782:6;69778:2;69774:15;69853:4;69842:9;69838:20;69805:227;69881:3;69877:2;69874:11;69805:227;;;70007:9;;69996:21;;69919:4;69911:13;;;;69948;69805:227;;;-1:-1:-1;70058:17:0;;70119:16;;70107:29;;70089:48;;70058:17;-1:-1:-1;70159:3:0;-1:-1:-1;70183:15:0;;;70263:4;70247:21;;70214:228;70291:3;70287:2;70284:11;70214:228;;;70417:9;;70406:21;;70329:4;70321:13;;;;70358;70214:228;;;-1:-1:-1;70523:16:0;;70511:29;;;;70504:37;70495:47;;;;70568:2;70491:56;-1:-1:-1;;70471:115:0;70465:4;70458:129;-1:-1:-1;70617:9:0;-1:-1:-1;69423:1211:0;;;;:::o;22655:106::-;22713:7;22744:1;22740;:5;:13;;22752:1;22740:13;;;-1:-1:-1;22748:1:0;;22655:106;-1:-1:-1;22655:106:0:o;24368:136::-;24426:7;24453:43;24457:1;24460;24453:43;;;;;;;;;;;;;;;;;:3;:43::i;25361:471::-;25419:7;25664:6;25660:47;;-1:-1:-1;25694:1:0;25687:8;;25660:47;25731:5;;;25735:1;25731;:5;:1;25755:5;;;;;:10;25747:56;;;;-1:-1:-1;;;25747:56:0;;;;;;;:::i;26300:132::-;26358:7;26385:39;26389:1;26392;26385:39;;;;;;;;;;;;;;;;;:3;:39::i;67509:566::-;67595:5;67622:4;67648;67665:170;67678:2;67671:3;:9;67665:170;;67749:10;;67736:24;;67797:2;67789:10;;;;67814:9;;;;-1:-1:-1;;67682:9:0;67665:170;;;67934:10;;67990:11;;67867:2;:8;;;;67859:3;:17;-1:-1:-1;;67859:21:0;67946:9;;67930:26;;;67986:22;;68035:21;68022:35;;-1:-1:-1;;;67900:168:0:o;24799:192::-;24885:7;24921:12;24913:6;;;;24905:29;;;;-1:-1:-1;;;24905:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;24957:5:0;;;24799:192::o;26920:345::-;27006:7;27108:12;27101:5;27093:28;;;;-1:-1:-1;;;27093:28:0;;;;;;;;:::i;:::-;;27132:9;27148:1;27144;:5;;;;;;;26920:345;-1:-1:-1;;;;;26920:345:0:o;-1:-1:-1:-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;70763:54;;72163:35;;72153:2;;72212:1;;72202:12;538:707;;655:3;648:4;640:6;636:17;632:27;622:2;;-1:-1;;663:12;622:2;710:6;697:20;732:80;747:64;804:6;747:64;:::i;:::-;732:80;:::i;:::-;840:21;;;723:89;-1:-1;884:4;897:14;;;;872:17;;;986;;;977:27;;;;974:36;-1:-1;971:2;;;1023:1;;1013:12;971:2;1048:1;1033:206;1058:6;1055:1;1052:13;1033:206;;;1138:37;1171:3;1159:10;1138:37;:::i;:::-;1126:50;;1190:14;;;;1218;;;;1080:1;1073:9;1033:206;;;1037:14;;;;;615:630;;;;:::o;1280:788::-;;1424:3;1417:4;1409:6;1405:17;1401:27;1391:2;;-1:-1;;1432:12;1391:2;1479:6;1466:20;1501:107;1516:91;1600:6;1516:91;:::i;1501:107::-;1636:21;;;1492:116;-1:-1;1680:4;1693:14;;;;1668:17;;;1794:4;1782:17;;;1773:27;;;;1770:36;-1:-1;1767:2;;;1819:1;;1809:12;1767:2;1844:1;;1829:233;1854:6;1851:1;1848:13;1829:233;;;1794:4;4856:9;4851:3;4847:19;4843:30;4840:2;;;1844:1;;4876:12;4840:2;4904:20;1794:4;4904:20;:::i;:::-;5011:49;5056:3;5032:22;5011:49;:::i;:::-;4993:16;4986:75;5152:47;5195:3;1680:4;5175:9;5171:22;5152:47;:::i;:::-;5134:16;;;5127:73;5258:2;5312:22;;;3755:20;5273:16;;;5266:75;5399:2;5453:22;;;3755:20;5414:16;;;5407:75;1922:77;;2013:14;;;;2041;;;;1876:1;1869:9;1829:233;;;1833:14;;;;;;;1384:684;;;;:::o;2094:707::-;;2211:3;2204:4;2196:6;2192:17;2188:27;2178:2;;-1:-1;;2219:12;2178:2;2266:6;2253:20;2288:80;2303:64;2360:6;2303:64;:::i;2288:80::-;2396:21;;;2279:89;-1:-1;2440:4;2453:14;;;;2428:17;;;2542;;;2533:27;;;;2530:36;-1:-1;2527:2;;;2579:1;;2569:12;2527:2;2604:1;2589:206;2614:6;2611:1;2608:13;2589:206;;;5577:20;;2682:50;;2746:14;;;;2774;;;;2636:1;2629:9;2589:206;;3826:442;;3928:3;3921:4;3913:6;3909:17;3905:27;3895:2;;-1:-1;;3936:12;3895:2;3983:6;3970:20;4005:65;4020:49;4062:6;4020:49;:::i;4005:65::-;3996:74;;4090:6;4083:5;4076:21;4194:3;4126:4;4185:6;4118;4176:16;;4173:25;4170:2;;;4211:1;;4201:12;4170:2;71078:6;4126:4;4118:6;4114:17;4126:4;4152:5;4148:16;71055:30;71134:1;71116:16;;;4126:4;71116:16;71109:27;4152:5;3888:380;-1:-1;;3888:380::o;5788:126::-;5853:20;;70979:4;70968:16;;72651:33;;72641:2;;72698:1;;72688:12;5921:241;;6025:2;6013:9;6004:7;6000:23;5996:32;5993:2;;;-1:-1;;6031:12;5993:2;6093:53;6138:7;6114:22;6093:53;:::i;6169:491::-;;;;6307:2;6295:9;6286:7;6282:23;6278:32;6275:2;;;-1:-1;;6313:12;6275:2;6375:53;6420:7;6396:22;6375:53;:::i;:::-;6365:63;;6483:53;6528:7;6465:2;6508:9;6504:22;6483:53;:::i;:::-;6473:63;;6591:53;6636:7;6573:2;6616:9;6612:22;6591:53;:::i;:::-;6581:63;;6269:391;;;;;:::o;6667:617::-;;;;;6822:3;6810:9;6801:7;6797:23;6793:33;6790:2;;;-1:-1;;6829:12;6790:2;6891:53;6936:7;6912:22;6891:53;:::i;:::-;6881:63;;6999:53;7044:7;6981:2;7024:9;7020:22;6999:53;:::i;:::-;6989:63;;7107:53;7152:7;7089:2;7132:9;7128:22;7107:53;:::i;:::-;7097:63;;7215:53;7260:7;7197:2;7240:9;7236:22;7215:53;:::i;:::-;7205:63;;6784:500;;;;;;;:::o;7291:743::-;;;;;;7463:3;7451:9;7442:7;7438:23;7434:33;7431:2;;;-1:-1;;7470:12;7431:2;7532:53;7577:7;7553:22;7532:53;:::i;:::-;7522:63;;7640:53;7685:7;7622:2;7665:9;7661:22;7640:53;:::i;:::-;7630:63;;7748:53;7793:7;7730:2;7773:9;7769:22;7748:53;:::i;:::-;7738:63;;7856:53;7901:7;7838:2;7881:9;7877:22;7856:53;:::i;:::-;7846:63;;7965:53;8010:7;7946:3;7990:9;7986:22;7965:53;:::i;:::-;7955:63;;7425:609;;;;;;;;:::o;8041:491::-;;;;8179:2;8167:9;8158:7;8154:23;8150:32;8147:2;;;-1:-1;;8185:12;8147:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8237:63;-1:-1;8337:2;8376:22;;72:20;97:33;72:20;97:33;:::i;:::-;8141:391;;8345:63;;-1:-1;;;8445:2;8484:22;;;;5577:20;;8141:391::o;8539:763::-;;;;8727:2;8715:9;8706:7;8702:23;8698:32;8695:2;;;-1:-1;;8733:12;8695:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8785:63;-1:-1;8913:2;8898:18;;8885:32;-1:-1;;;;;8926:30;;;8923:2;;;-1:-1;;8959:12;8923:2;8989:78;9059:7;9050:6;9039:9;9035:22;8989:78;:::i;:::-;8979:88;;9132:2;9121:9;9117:18;9104:32;9090:46;;8937:18;9148:6;9145:30;9142:2;;;-1:-1;;9178:12;9142:2;;9208:78;9278:7;9269:6;9258:9;9254:22;9208:78;:::i;:::-;9198:88;;;8689:613;;;;;:::o;9309:502::-;;;9455:2;9443:9;9434:7;9430:23;9426:32;9423:2;;;-1:-1;;9461:12;9423:2;9523:53;9568:7;9544:22;9523:53;:::i;:::-;9513:63;;9641:2;9630:9;9626:18;9613:32;-1:-1;;;;;9657:6;9654:30;9651:2;;;-1:-1;;9687:12;9651:2;9717:78;9787:7;9778:6;9767:9;9763:22;9717:78;:::i;:::-;9707:88;;;9417:394;;;;;:::o;9818:360::-;;;9936:2;9924:9;9915:7;9911:23;9907:32;9904:2;;;-1:-1;;9942:12;9904:2;10004:53;10049:7;10025:22;10004:53;:::i;:::-;9994:63;;10094:2;10134:9;10130:22;3621:20;72309:5;70596:13;70589:21;72287:5;72284:32;72274:2;;-1:-1;;72320:12;72274:2;10102:60;;;;9898:280;;;;;:::o;10185:366::-;;;10306:2;10294:9;10285:7;10281:23;10277:32;10274:2;;;-1:-1;;10312:12;10274:2;10374:53;10419:7;10395:22;10374:53;:::i;:::-;10364:63;10464:2;10503:22;;;;5577:20;;-1:-1;;;10268:283::o;10558:491::-;;;;10696:2;10684:9;10675:7;10671:23;10667:32;10664:2;;;-1:-1;;10702:12;10664:2;10764:53;10809:7;10785:22;10764:53;:::i;:::-;10754:63;10854:2;10893:22;;5577:20;;-1:-1;10962:2;11001:22;;;5577:20;;10658:391;-1:-1;;;10658:391::o;11056:397::-;;;11195:2;11183:9;11174:7;11170:23;11166:32;11163:2;;;-1:-1;;11201:12;11163:2;11259:17;11246:31;-1:-1;;;;;11297:18;11289:6;11286:30;11283:2;;;-1:-1;;11319:12;11283:2;11420:6;11409:9;11405:22;;;290:3;283:4;275:6;271:17;267:27;257:2;;-1:-1;;298:12;257:2;341:6;328:20;11297:18;360:6;357:30;354:2;;;-1:-1;;390:12;354:2;485:3;11195:2;;469:6;465:17;426:6;451:32;;448:41;445:2;;;-1:-1;;492:12;445:2;11195;422:17;;;;;11339:98;;-1:-1;11157:296;;-1:-1;;;;11157:296::o;11460:638::-;;;11631:2;11619:9;11610:7;11606:23;11602:32;11599:2;;;-1:-1;;11637:12;11599:2;11695:17;11682:31;-1:-1;;;;;11733:18;11725:6;11722:30;11719:2;;;-1:-1;;11755:12;11719:2;11785:78;11855:7;11846:6;11835:9;11831:22;11785:78;:::i;:::-;11775:88;;11928:2;11917:9;11913:18;11900:32;11886:46;;11733:18;11944:6;11941:30;11938:2;;;-1:-1;;11974:12;11938:2;;12004:78;12074:7;12065:6;12054:9;12050:22;12004:78;:::i;12105:377::-;;12234:2;12222:9;12213:7;12209:23;12205:32;12202:2;;;-1:-1;;12240:12;12202:2;12298:17;12285:31;-1:-1;;;;;12328:6;12325:30;12322:2;;;-1:-1;;12358:12;12322:2;12388:78;12458:7;12449:6;12438:9;12434:22;12388:78;:::i;12489:392::-;;12629:2;;12617:9;12608:7;12604:23;12600:32;12597:2;;;-1:-1;;12635:12;12597:2;12686:17;12680:24;-1:-1;;;;;12716:6;12713:30;12710:2;;;-1:-1;;12746:12;12710:2;12833:22;;2948:4;2936:17;;2932:27;-1:-1;2922:2;;-1:-1;;2963:12;2922:2;3003:6;2997:13;3025:80;3040:64;3097:6;3040:64;:::i;3025:80::-;3133:21;;;3190:14;;;;3165:17;;;3279;;;3270:27;;;;3267:36;-1:-1;3264:2;;;-1:-1;;3306:12;3264:2;-1:-1;3332:10;;3326:217;3351:6;3348:1;3345:13;3326:217;;;5725:13;;3419:61;;3373:1;3366:9;;;;;3494:14;;;;3522;;3326:217;;;-1:-1;12766:99;12591:290;-1:-1;;;;;;;12591:290::o;12888:241::-;;12992:2;12980:9;12971:7;12967:23;12963:32;12960:2;;;-1:-1;;12998:12;12960:2;-1:-1;3755:20;;12954:175;-1:-1;12954:175::o;13136:366::-;;;13257:2;13245:9;13236:7;13232:23;13228:32;13225:2;;;-1:-1;;13263:12;13225:2;3768:6;3755:20;13315:63;;13415:2;13458:9;13454:22;72:20;97:33;124:5;97:33;:::i;13509:491::-;;;;13647:2;13635:9;13626:7;13622:23;13618:32;13615:2;;;-1:-1;;13653:12;13615:2;3768:6;3755:20;13705:63;;13823:53;13868:7;13805:2;13848:9;13844:22;13823:53;:::i;:::-;13813:63;;13913:2;13956:9;13952:22;5577:20;13921:63;;13609:391;;;;;:::o;14007:366::-;;;14128:2;14116:9;14107:7;14103:23;14099:32;14096:2;;;-1:-1;;14134:12;14096:2;-1:-1;;3755:20;;;14286:2;14325:22;;;5577:20;;-1:-1;14090:283::o;14380:491::-;;;;14518:2;14506:9;14497:7;14493:23;14489:32;14486:2;;;-1:-1;;14524:12;14486:2;-1:-1;;3755:20;;;14676:2;14715:22;;5577:20;;-1:-1;14784:2;14823:22;;;5577:20;;14480:391;-1:-1;14480:391::o;14878:347::-;;14992:2;14980:9;14971:7;14967:23;14963:32;14960:2;;;-1:-1;;14998:12;14960:2;15056:17;15043:31;-1:-1;;;;;15086:6;15083:30;15080:2;;;-1:-1;;15116:12;15080:2;15146:63;15201:7;15192:6;15181:9;15177:22;15146:63;:::i;15232:362::-;;15357:2;15345:9;15336:7;15332:23;15328:32;15325:2;;;-1:-1;;15363:12;15325:2;15414:17;15408:24;-1:-1;;;;;15444:6;15441:30;15438:2;;;-1:-1;;15474:12;15438:2;15546:22;;4383:4;4371:17;;4367:27;-1:-1;4357:2;;-1:-1;;4398:12;4357:2;4438:6;4432:13;4460:65;4475:49;4517:6;4475:49;:::i;4460:65::-;4545:6;4538:5;4531:21;4649:3;15357:2;4640:6;4573;4631:16;;4628:25;4625:2;;;-1:-1;;4656:12;4625:2;4676:39;4708:6;15357:2;4607:5;4603:16;15357:2;4573:6;4569:17;4676:39;:::i;:::-;15494:84;15319:275;-1:-1;;;;;15319:275::o;15601:825::-;;;;;15774:3;15762:9;15753:7;15749:23;15745:33;15742:2;;;-1:-1;;15781:12;15742:2;15839:17;15826:31;-1:-1;;;;;15877:18;15869:6;15866:30;15863:2;;;-1:-1;;15899:12;15863:2;15929:63;15984:7;15975:6;15964:9;15960:22;15929:63;:::i;:::-;15919:73;;16057:2;16046:9;16042:18;16029:32;16015:46;;15877:18;16073:6;16070:30;16067:2;;;-1:-1;;16103:12;16067:2;;16133:63;16188:7;16179:6;16168:9;16164:22;16133:63;:::i;:::-;16123:73;;;16251:51;16294:7;16233:2;16274:9;16270:22;16251:51;:::i;:::-;15736:690;;;;-1:-1;16241:61;;16339:2;16378:22;5577:20;;-1:-1;;15736:690::o;16433:597::-;;;;16581:2;16569:9;16560:7;16556:23;16552:32;16549:2;;;-1:-1;;16587:12;16549:2;16645:17;16632:31;-1:-1;;;;;16675:6;16672:30;16669:2;;;-1:-1;;16705:12;16669:2;16735:63;16790:7;16781:6;16770:9;16766:22;16735:63;:::i;:::-;16725:73;;;16835:2;16878:9;16874:22;5577:20;16843:63;;16943:2;16986:9;16982:22;72:20;97:33;124:5;97:33;:::i;:::-;16951:63;;;;16543:487;;;;;:::o;17285:263::-;;17400:2;17388:9;17379:7;17375:23;17371:32;17368:2;;;-1:-1;;17406:12;17368:2;-1:-1;5725:13;;17362:186;-1:-1;17362:186::o;17555:366::-;;;17676:2;17664:9;17655:7;17651:23;17647:32;17644:2;;;-1:-1;;17682:12;17644:2;5590:6;5577:20;17734:63;;17852:53;17897:7;17834:2;17877:9;17873:22;17852:53;:::i;:::-;17842:63;;17638:283;;;;;:::o;17928:1203::-;;;;;;;;18152:3;18140:9;18131:7;18127:23;18123:33;18120:2;;;-1:-1;;18159:12;18120:2;5590:6;5577:20;18211:63;;18329:53;18374:7;18311:2;18354:9;18350:22;18329:53;:::i;:::-;18319:63;;18437:53;18482:7;18419:2;18462:9;18458:22;18437:53;:::i;:::-;18427:63;;18555:2;18544:9;18540:18;18527:32;-1:-1;;;;;18579:18;18571:6;18568:30;18565:2;;;-1:-1;;18601:12;18565:2;18631:63;18686:7;18677:6;18666:9;18662:22;18631:63;:::i;:::-;18621:73;;18759:3;18748:9;18744:19;18731:33;18717:47;;18579:18;18776:6;18773:30;18770:2;;;-1:-1;;18806:12;18770:2;;18836:63;18891:7;18882:6;18871:9;18867:22;18836:63;:::i;:::-;18826:73;;;18955:51;18998:7;18936:3;18978:9;18974:22;18955:51;:::i;:::-;18945:61;;19043:3;19087:9;19083:22;5577:20;19052:63;;18114:1017;;;;;;;;;;:::o;19138:889::-;;;;;19343:3;19331:9;19322:7;19318:23;19314:33;19311:2;;;-1:-1;;19350:12;19311:2;5590:6;5577:20;19402:63;;19502:2;19545:9;19541:22;72:20;97:33;124:5;97:33;:::i;:::-;19510:63;-1:-1;19638:2;19623:18;;19610:32;-1:-1;;;;;19651:30;;;19648:2;;;-1:-1;;19684:12;19648:2;19714:78;19784:7;19775:6;19764:9;19760:22;19714:78;:::i;:::-;19704:88;;19857:2;19846:9;19842:18;19829:32;19815:46;;19662:18;19873:6;19870:30;19867:2;;;-1:-1;;19903:12;19867:2;;19933:78;20003:7;19994:6;19983:9;19979:22;19933:78;:::i;:::-;19923:88;;;19305:722;;;;;;;:::o;20034:1331::-;;;;;;;20325:3;20313:9;20304:7;20300:23;20296:33;20293:2;;;-1:-1;;20332:12;20293:2;5590:6;5577:20;20384:63;;20502:53;20547:7;20484:2;20527:9;20523:22;20502:53;:::i;:::-;20492:63;;20592:2;20635:9;20631:22;5577:20;20600:63;;20728:2;20717:9;20713:18;20700:32;-1:-1;;;;;20752:18;20744:6;20741:30;20738:2;;;-1:-1;;20774:12;20738:2;20804:78;20874:7;20865:6;20854:9;20850:22;20804:78;:::i;:::-;20794:88;;20947:3;20936:9;20932:19;20919:33;20905:47;;20752:18;20964:6;20961:30;20958:2;;;-1:-1;;20994:12;20958:2;21024:78;21094:7;21085:6;21074:9;21070:22;21024:78;:::i;:::-;21014:88;;21167:3;21156:9;21152:19;21139:33;21125:47;;20752:18;21184:6;21181:30;21178:2;;;-1:-1;;21214:12;21178:2;;21244:105;21341:7;21332:6;21321:9;21317:22;21244:105;:::i;:::-;21234:115;;;20287:1078;;;;;;;;:::o;21372:1519::-;;;;;;;;;21665:3;21653:9;21644:7;21640:23;21636:33;21633:2;;;-1:-1;;21672:12;21633:2;21755:22;5577:20;21724:63;;21842:53;21887:7;21824:2;21867:9;21863:22;21842:53;:::i;:::-;21832:63;;21932:2;21975:9;21971:22;5577:20;21940:63;;22068:2;22057:9;22053:18;22040:32;-1:-1;;;;;22092:18;22084:6;22081:30;22078:2;;;-1:-1;;22114:12;22078:2;22144:63;22199:7;22190:6;22179:9;22175:22;22144:63;:::i;:::-;22134:73;;22272:3;22261:9;22257:19;22244:33;22230:47;;22092:18;22289:6;22286:30;22283:2;;;-1:-1;;22319:12;22283:2;22349:63;22404:7;22395:6;22384:9;22380:22;22349:63;:::i;:::-;22339:73;;22468:51;22511:7;22449:3;22491:9;22487:22;22468:51;:::i;:::-;22458:61;;22556:3;22600:9;22596:22;5577:20;22565:63;;22693:3;22682:9;22678:19;22665:33;22651:47;;22092:18;22710:6;22707:30;22704:2;;;-1:-1;;22740:12;22704:2;;22770:105;22867:7;22858:6;22847:9;22843:22;22770:105;:::i;:::-;22760:115;;;21627:1264;;;;;;;;;;;:::o;25437:690::-;;25630:5;67562:12;68761:6;68756:3;68749:19;68798:4;;68793:3;68789:14;25642:93;;68798:4;25806:5;67090:14;-1:-1;25845:260;25870:6;25867:1;25864:13;25845:260;;;25931:13;;-1:-1;;;;;70763:54;23947:45;;23052:14;;;;68249;;;;70774:42;25885:9;25845:260;;;-1:-1;26111:10;;25561:566;-1:-1;;;;;25561:566::o;27904:690::-;;28097:5;67562:12;68761:6;68756:3;68749:19;68798:4;;68793:3;68789:14;28109:93;;68798:4;28273:5;67090:14;-1:-1;28312:260;28337:6;28334:1;28331:13;28312:260;;;28398:13;;29557:37;;23634:14;;;;68249;;;;28359:1;28352:9;28312:260;;29765:343;;29907:5;67562:12;68761:6;68756:3;68749:19;30000:52;30045:6;68798:4;68793:3;68789:14;68798:4;30026:5;30022:16;30000:52;:::i;:::-;71981:7;71965:14;-1:-1;;71961:28;30064:39;;;;68798:4;30064:39;;29855:253;-1:-1;;29855:253::o;39696:335::-;67562:12;;39696:335;;39881:125;;67099:4;67090:14;;;39696:335;26610:268;26635:6;26632:1;26629:13;26610:268;;;26696:13;;-1:-1;;;;;70763:54;23947:45;;23052:14;;;;68249;;;;70774:42;26650:9;26610:268;;;-1:-1;40016:10;;39862:169;-1:-1;;;;;;39862:169::o;40038:335::-;67562:12;;40038:335;;40223:125;;67099:4;67090:14;;;40038:335;29077:268;29102:6;29099:1;29096:13;29077:268;;;29163:13;;29557:37;;23634:14;;;;68249;;;;29124:1;29117:9;29077:268;;40380:275;;30966:5;67562:12;31078:52;31123:6;31118:3;31111:4;31104:5;31100:16;31078:52;:::i;:::-;31142:16;;;;;40516:139;-1:-1;;40516:139::o;40662:659::-;-1:-1;;;33099:87;;33084:1;33205:11;;29557:37;;;;41173:12;;;29557:37;41284:12;;;40907:414::o;41328:798::-;-1:-1;;;;;;35156:87;;72076:2;72072:14;;;;-1:-1;;72072:14;35141:1;35262:11;;24109:74;41867:12;;;29557:37;;;;41978:12;;;29557:37;42089:12;;;41601:525::o;42133:392::-;29557:37;;;72076:2;72072:14;-1:-1;;72072:14;42386:2;42377:12;;24109:74;42488:12;;;42277:248::o;42963:222::-;-1:-1;;;;;70763:54;;;;23947:45;;43090:2;43075:18;;43061:124::o;43192:333::-;-1:-1;;;;;70763:54;;;23947:45;;70763:54;;43511:2;43496:18;;23947:45;43347:2;43332:18;;43318:207::o;43532:980::-;-1:-1;;;;;70763:54;;;23947:45;;70763:54;;44032:2;44017:18;;23947:45;43851:3;44069:2;44054:18;;44047:48;;;43532:980;;44109:78;;43836:19;;44173:6;44109:78;:::i;:::-;44235:9;44229:4;44225:20;44220:2;44209:9;44205:18;44198:48;44260:78;44333:4;44324:6;44260:78;:::i;:::-;70979:4;70968:16;;;;44413:3;44398:19;;39649:35;-1:-1;;44497:3;44482:19;29557:37;44252:86;43822:690;-1:-1;;;;43822:690::o;44519:528::-;;70774:42;;;;;23985:5;70763:54;23954:3;23947:45;29587:5;44884:2;44873:9;44869:18;29557:37;44720:2;44921;44910:9;44906:18;44899:48;44961:76;44720:2;44709:9;44705:18;45023:6;44961:76;:::i;45054:333::-;-1:-1;;;;;70763:54;;;;23947:45;;45373:2;45358:18;;29557:37;45209:2;45194:18;;45180:207::o;45394:1172::-;-1:-1;;;;;70763:54;;;23947:45;;45918:2;45903:18;;29557:37;;;70763:54;;;46001:2;45986:18;;23947:45;70763:54;;46084:2;46069:18;;23947:45;45753:3;46121;46106:19;;46099:49;;;45394:1172;;46162:78;45738:19;;;46226:6;46162:78;:::i;:::-;46154:86;;46289:9;46283:4;46279:20;46273:3;46262:9;46258:19;46251:49;46314:78;46387:4;46378:6;46314:78;:::i;:::-;70979:4;70968:16;;;;46467:3;46452:19;;39649:35;-1:-1;;46551:3;46536:19;29557:37;46306:86;45724:842;-1:-1;;;;;;45724:842::o;46573:390::-;46760:2;46774:47;;;46745:18;;;68749:19;;;46573:390;;25058:21;68789:14;;;46573:390;25085:291;25110:6;25107:1;25104:13;25085:291;;;70299:12;;;-1:-1;;;;;70273:39;70299:12;25206:6;70273:39;:::i;:::-;70763:54;23947:45;;25297:72;-1:-1;23052:14;;;;25132:1;25125:9;25085:291;;;-1:-1;46827:126;46731:232;-1:-1;;;;;;46731:232::o;46970:629::-;;47225:2;47246:17;47239:47;47300:108;47225:2;47214:9;47210:18;47394:6;47300:108;:::i;:::-;47456:9;47450:4;47446:20;47441:2;47430:9;47426:18;47419:48;47481:108;47584:4;47575:6;47481:108;:::i;47606:928::-;;47959:2;47948:9;47944:18;47959:2;47980:17;47973:47;48034:128;27160:5;67562:12;68761:6;68756:3;68749:19;68789:14;47948:9;68789:14;27172:103;;68798:4;;;68789:14;68798:4;27332:6;27328:17;47948:9;27319:27;;68798:4;27427:5;67090:14;-1:-1;27466:360;27491:6;27488:1;27485:13;27466:360;;;27543:20;;47948:9;27547:4;27543:20;;27538:3;27531:33;23400:66;23462:3;27598:6;27592:13;23400:66;:::i;:::-;27805:14;;;;27612:92;-1:-1;68249:14;;;;27513:1;27506:9;27466:360;;;27470:14;;48210:9;48204:4;48200:20;68798:4;48184:9;48180:18;48173:48;48235:108;48338:4;48329:6;48235:108;:::i;:::-;48227:116;;;;;48391:9;48385:4;48381:20;48376:2;48365:9;48361:18;48354:48;48416:108;48519:4;48510:6;48416:108;:::i;:::-;48408:116;47930:604;-1:-1;;;;;;47930:604::o;48541:370::-;;48718:2;48739:17;48732:47;48793:108;48718:2;48707:9;48703:18;48887:6;48793:108;:::i;48918:629::-;;49173:2;49194:17;49187:47;49248:108;49173:2;49162:9;49158:18;49342:6;49248:108;:::i;:::-;49404:9;49398:4;49394:20;49389:2;49378:9;49374:18;49367:48;49429:108;49532:4;49523:6;49429:108;:::i;49554:210::-;70596:13;;70589:21;29440:34;;49675:2;49660:18;;49646:118::o;49771:222::-;29557:37;;;49898:2;49883:18;;49869:124::o;50000:1140::-;29557:37;;;-1:-1;;;;;70763:54;;;50544:2;50529:18;;23947:45;50627:2;50612:18;;29557:37;;;;70763:54;;;50710:2;50695:18;;23947:45;50793:3;50778:19;;29557:37;;;;70774:42;50862:19;;29557:37;70979:4;70968:16;50957:3;50942:19;;39649:35;51041:3;51026:19;;29557:37;70763:54;51125:3;51110:19;;23947:45;50363:3;50348:19;;50334:806::o;51147:556::-;29557:37;;;51523:2;51508:18;;29557:37;;;;51606:2;51591:18;;29557:37;-1:-1;;;;;70763:54;51689:2;51674:18;;23947:45;51358:3;51343:19;;51329:374::o;51710:780::-;29557:37;;;52142:2;52127:18;;29557:37;;;;-1:-1;;;;;70763:54;;;52225:2;52210:18;;23947:45;52308:2;52293:18;;29557:37;;;;52391:3;52376:19;;29557:37;70763:54;70774:42;52460:19;;23947:45;51977:3;51962:19;;51948:542::o;52497:548::-;29557:37;;;70979:4;70968:16;;;;52865:2;52850:18;;39649:35;52948:2;52933:18;;29557:37;53031:2;53016:18;;29557:37;52704:3;52689:19;;52675:370::o;53052:310::-;;53199:2;53220:17;53213:47;53274:78;53199:2;53188:9;53184:18;53338:6;53274:78;:::i;53369:724::-;;53616:3;53638:17;53631:47;53692:78;53616:3;53605:9;53601:19;53756:6;53692:78;:::i;:::-;53818:9;53812:4;53808:20;53803:2;53792:9;53788:18;53781:48;53843:78;53916:4;53907:6;53843:78;:::i;:::-;70979:4;70968:16;;;;53996:2;53981:18;;39649:35;-1:-1;;54079:2;54064:18;29557:37;53835:86;53587:506;-1:-1;;53587:506::o;54100:416::-;54300:2;54314:47;;;31395:2;54285:18;;;68749:19;31431:31;68789:14;;;31411:52;31482:12;;;54271:245::o;54523:416::-;54723:2;54737:47;;;31733:2;54708:18;;;68749:19;-1:-1;;;68789:14;;;31749:40;31808:12;;;54694:245::o;54946:416::-;55146:2;55160:47;;;32059:2;55131:18;;;68749:19;-1:-1;;;68789:14;;;32075:41;32135:12;;;55117:245::o;55369:416::-;55569:2;55583:47;;;32386:2;55554:18;;;68749:19;32422:33;68789:14;;;32402:54;32475:12;;;55540:245::o;55792:416::-;55992:2;56006:47;;;32726:2;55977:18;;;68749:19;-1:-1;;;68789:14;;;32742:36;32797:12;;;55963:245::o;56215:416::-;56415:2;56429:47;;;33455:2;56400:18;;;68749:19;33491:29;68789:14;;;33471:50;33540:12;;;56386:245::o;56638:416::-;56838:2;56852:47;;;33791:2;56823:18;;;68749:19;-1:-1;;;68789:14;;;33807:37;33863:12;;;56809:245::o;57061:416::-;57261:2;57275:47;;;34114:2;57246:18;;;68749:19;-1:-1;;;68789:14;;;34130:43;34192:12;;;57232:245::o;57484:416::-;57684:2;57698:47;;;34443:2;57669:18;;;68749:19;34479:30;68789:14;;;34459:51;34529:12;;;57655:245::o;57907:416::-;58107:2;58121:47;;;34780:2;58092:18;;;68749:19;-1:-1;;;68789:14;;;34796:39;34854:12;;;58078:245::o;58330:416::-;58530:2;58544:47;;;35512:2;58515:18;;;68749:19;-1:-1;;;68789:14;;;35528:42;35589:12;;;58501:245::o;58753:416::-;58953:2;58967:47;;;35840:2;58938:18;;;68749:19;35876:34;68789:14;;;35856:55;-1:-1;;;35931:12;;;35924:25;35968:12;;;58924:245::o;59176:416::-;59376:2;59390:47;;;36219:2;59361:18;;;68749:19;-1:-1;;;68789:14;;;36235:35;36289:12;;;59347:245::o;59599:416::-;59799:2;59813:47;;;36540:2;59784:18;;;68749:19;36576:34;68789:14;;;36556:55;-1:-1;;;36631:12;;;36624:38;36681:12;;;59770:245::o;60022:416::-;60222:2;60236:47;;;36932:2;60207:18;;;68749:19;36968:27;68789:14;;;36948:48;37015:12;;;60193:245::o;60445:416::-;60645:2;60659:47;;;37266:2;60630:18;;;68749:19;-1:-1;;;68789:14;;;37282:36;37337:12;;;60616:245::o;60868:416::-;61068:2;61082:47;;;37588:2;61053:18;;;68749:19;37624:25;68789:14;;;37604:46;37669:12;;;61039:245::o;61291:416::-;61491:2;61505:47;;;37920:2;61476:18;;;68749:19;37956:29;68789:14;;;37936:50;38005:12;;;61462:245::o;61714:416::-;61914:2;61928:47;;;38256:2;61899:18;;;68749:19;38292:25;68789:14;;;38272:46;38337:12;;;61885:245::o;62137:416::-;62337:2;62351:47;;;38588:2;62322:18;;;68749:19;38624:25;68789:14;;;38604:46;38669:12;;;62308:245::o;62560:416::-;62760:2;62774:47;;;38920:2;62745:18;;;68749:19;38956:34;68789:14;;;38936:55;-1:-1;;;39011:12;;;39004:26;39049:12;;;62731:245::o;63212:333::-;29557:37;;;-1:-1;;;;;70763:54;63531:2;63516:18;;23947:45;63367:2;63352:18;;63338:207::o;63552:556::-;29557:37;;;-1:-1;;;;;70763:54;;;63928:2;63913:18;;23947:45;64011:2;63996:18;;29557:37;;;;70763:54;64094:2;64079:18;;23947:45;63763:3;63748:19;;63734:374::o;64115:836::-;;29587:5;29564:3;29557:37;64390:3;64509:2;64498:9;64494:18;64487:48;64549:78;64390:3;64379:9;64375:19;64613:6;64549:78;:::i;:::-;64675:9;64669:4;64665:20;64660:2;64649:9;64645:18;64638:48;64700:78;64773:4;64764:6;64700:78;:::i;:::-;70979:4;70968:16;;;;64853:2;64838:18;;39649:35;-1:-1;;64936:3;64921:19;29557:37;64692:86;64361:590;-1:-1;;;64361:590::o;64958:333::-;29557:37;;;65277:2;65262:18;;29557:37;65113:2;65098:18;;65084:207::o;65298:256::-;65360:2;65354:9;65386:17;;;-1:-1;;;;;65446:34;;65482:22;;;65443:62;65440:2;;;65518:1;;65508:12;65440:2;65360;65527:22;65338:216;;-1:-1;65338:216::o;65561:304::-;;-1:-1;;;;;65712:6;65709:30;65706:2;;;-1:-1;;65742:12;65706:2;-1:-1;65787:4;65775:17;;;65840:15;;65643:222::o;66521:322::-;;-1:-1;;;;;66657:6;66654:30;66651:2;;;-1:-1;;66687:12;66651:2;-1:-1;71981:7;66741:17;-1:-1;;66737:33;66828:4;66818:15;;66588:255::o;71151:268::-;71216:1;71223:101;71237:6;71234:1;71231:13;71223:101;;;71304:11;;;71298:18;71285:11;;;71278:39;71259:2;71252:10;71223:101;;;71339:6;71336:1;71333:13;71330:2;;;-1:-1;;71216:1;71386:16;;71379:27;71200:219::o;72104:117::-;-1:-1;;;;;70763:54;;72163:35;;72153:2;;72212:1;;72202:12
Swarm Source
ipfs://4bed37698494fa0eba930b7340d3d6f42c3a2216fe8e86a4468ffeb85e285db1
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.