Source Code
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
YandaMultitokenProtocolV2
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity)
/** *Submitted for verification at moonbeam.moonscan.io on 2023-03-08 */ // Sources flattened with hardhat v2.12.0 https://hardhat.org // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File @openzeppelin/contracts/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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) { return a + b; } /** * @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 a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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 a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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 IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ 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' 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) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File contracts/YandaMultitokenProtocolV2.sol // SPDX-License-Identifier: GNU GPLv3 pragma solidity ^0.8.3; contract YandaMultitokenProtocolV2 is AccessControl{ using SafeMath for uint256; using SafeERC20 for IERC20; uint internal TIME_FRAME_SIZE; uint internal VALIDATORS_PERC; uint internal BROKER_PERC; uint internal FEE_NOMINATOR; uint internal FEE_DENOMINATOR; uint internal _penaltyPerc; uint internal _lockingPeriod; uint256 internal _totalStaked; IERC20 internal _tokenContract; address payable internal _beneficiary; enum State { AWAITING_COST, AWAITING_TRANSFER, AWAITING_TERMINATION, AWAITING_VALIDATION, COMPLETED } struct Process { State state; uint256 cost; uint256 costConf; address token; address payable deposit; address payable depositConf; uint256 fee; address service; bytes32 productId; uint256 startBlock; address[] validatorsList; address firstValidator; bool firstResult; address secondValidator; bool secondResult; } struct Service { address[] validators; uint validationPerc; uint commissionPerc; uint validatorVersion; uint feeNominator; uint feeDenominator; } struct Stake { uint256 amount; uint256 unlockingBlock; } mapping(address => mapping(bytes32 => Process)) internal _processes; mapping(address => bytes32) internal _depositingProducts; mapping(address => Service) internal _services; mapping(address => uint256) internal _stakesByValidators; mapping(address => address[]) internal _validatorStakers; mapping(address => mapping(address => Stake)) internal _stakes; event Deposit( address indexed customer, address indexed service, bytes32 indexed productId, uint256 weiAmount ); event Action( address indexed customer, address indexed service, bytes32 indexed productId, string data ); event Terminate( address indexed customer, address indexed service, bytes32 indexed productId, address[] validatorsList ); event Complete( address indexed customer, address indexed service, bytes32 indexed productId, bool success ); event CostRequest( address indexed customer, address indexed service, bytes32 indexed productId, address[] validatorsList, string data ); event CostResponse( address indexed customer, address indexed service, bytes32 indexed productId, uint cost ); event Staked( address indexed staker, address indexed validator, uint256 amount, uint256 unlockingBlock ); event UnStaked( address indexed staker, address indexed validator, uint256 amount ); modifier onlyService() { require(_services[msg.sender].validators.length > 0, "Only service can call this method"); _; } constructor(uint penaltyPerc, uint lockingPeriod, address token) { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _beneficiary = payable(msg.sender); _penaltyPerc = penaltyPerc; _lockingPeriod = lockingPeriod; _tokenContract = IERC20(token); VALIDATORS_PERC = 15; BROKER_PERC = 80; FEE_NOMINATOR = 2; FEE_DENOMINATOR = 1000; TIME_FRAME_SIZE = 10; } function _containsAddress(address[] memory array, address search) internal pure returns(bool) { for(uint x=0; x < array.length; x++) { if (array[x] == search) { return true; } } return false; } function setBeneficiary(address payable newAddr) external onlyRole(DEFAULT_ADMIN_ROLE) { _beneficiary = newAddr; } function setDefaultPerc(uint vPerc, uint bPerc) external onlyRole(DEFAULT_ADMIN_ROLE) { VALIDATORS_PERC = vPerc; BROKER_PERC = bPerc; } function setProtocolFee(uint nominator, uint denominator) external onlyRole(DEFAULT_ADMIN_ROLE) { FEE_NOMINATOR = nominator; FEE_DENOMINATOR = denominator; } function setValidationTimeFrame(uint blocks) external onlyRole(DEFAULT_ADMIN_ROLE) { TIME_FRAME_SIZE = blocks; } function getValidationTimeFrame() external view returns(uint) { return TIME_FRAME_SIZE; } function getStakingTokenAddr() external view returns(address) { return address(_tokenContract); } receive() external payable { address sender = _msgSender(); Process storage process = _processes[sender][_depositingProducts[sender]]; require(process.token == address(0), "The current process wait for an ERC20 token deposit"); require(process.state == State.AWAITING_TRANSFER, "You don't have a deposit awaiting process, please create it first"); require(process.cost == msg.value, "Deposit amount doesn't match with the requested deposit"); if(process.fee < process.cost) { // Transfer main payment from customer to the broker(subtracting the fee) process.deposit.transfer(msg.value.sub(process.fee)); } // Update process state and emit an event process.state = State.AWAITING_TERMINATION; emit Deposit(sender, process.service, process.productId, msg.value); } function addService(address service, address[] memory vList, uint fNominator, uint fDenominator) external onlyRole(DEFAULT_ADMIN_ROLE) { require(vList.length > 2, "Validators minimum quantity is 3"); _services[service] = Service({ validators: vList, validationPerc: VALIDATORS_PERC, commissionPerc: BROKER_PERC, validatorVersion: 1, feeNominator: fNominator, feeDenominator: fDenominator }); } function setServicePerc(address service, uint vPerc, uint bPerc) external onlyRole(DEFAULT_ADMIN_ROLE) { Service storage instance = _services[service]; instance.validationPerc = vPerc; instance.commissionPerc = bPerc; } function setValidators(address[] memory vList) external onlyService { _services[msg.sender].validators = vList; } function getValidatorVer(address service) external view returns(uint) { return _services[service].validatorVersion; } function setValidatorVer(uint vVer) external onlyService { _services[msg.sender].validatorVersion = vVer; } function getPenaltyPerc() external view returns(uint) { return _penaltyPerc; } function setPenaltyPerc(uint newPenaltyPerc) external onlyRole(DEFAULT_ADMIN_ROLE) { _penaltyPerc = newPenaltyPerc; } function getLockingPeriod() external view returns(uint256) { return _lockingPeriod; } function setLockingPeriod(uint256 newLockingPeriod) external onlyRole(DEFAULT_ADMIN_ROLE) { _lockingPeriod = newLockingPeriod; } function inTimeFrame(address[] memory list, address search, uint256 startBlock, uint intSize) internal view returns(bool) { for(uint x=0; x < list.length; x++) { if(list[x] == search) { return ( (x * intSize) <= (block.number - startBlock) && (block.number - startBlock) < (x * intSize + intSize) ); } } return false; } function random() internal view returns(uint256) { // Temp solution with fake random // TODO resolve with real randomness return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp))); } function _randValidatorsList(address service, address exclude1, address exclude2) internal view returns(address[] memory) { uint256 localTotalStaked = _totalStaked - _stakesByValidators[exclude1] - _stakesByValidators[exclude2]; uint256 index = 0; uint resultLength = _services[service].validators.length; if (exclude1 != address(0)) { resultLength -= 1; } if (exclude2 != address(0)) { resultLength -= 1; } address[] memory result = new address[](resultLength); for(uint x=0; x < result.length; x++) { index = random() % localTotalStaked; for(uint y=0; y < _services[service].validators.length; y++) { if (_services[service].validators[y] != exclude1 && _services[service].validators[y] != exclude2) { if (_containsAddress(result, _services[service].validators[y]) == false) { if (index <= _stakesByValidators[_services[service].validators[y]]) { result[x] = _services[service].validators[y]; localTotalStaked -= _stakesByValidators[_services[service].validators[y]]; break; } index -= _stakesByValidators[_services[service].validators[y]]; } } } } return result; } function _createProcess(address token, address service, bytes32 productId, string calldata data) internal { require(_services[service].validationPerc > 0, 'Requested service address not found'); require(_processes[msg.sender][productId].service == address(0), 'Process with specified productId already exist'); _processes[msg.sender][productId] = Process({ state: State.AWAITING_COST, cost: 0, costConf: 0, token: token, deposit: payable(address(0)), depositConf: payable(address(0)), fee: 0, service: service, productId: productId, startBlock: block.number, validatorsList: _randValidatorsList(service, address(0), address(0)), firstValidator: address(0), firstResult: false, secondValidator: address(0), secondResult: false }); emit CostRequest(msg.sender, service, productId, _processes[msg.sender][productId].validatorsList, data); if(_depositingProducts[msg.sender].length > 0) { if(_processes[msg.sender][_depositingProducts[msg.sender]].state == State.AWAITING_TRANSFER) { delete _processes[msg.sender][_depositingProducts[msg.sender]]; } } _depositingProducts[msg.sender] = productId; } function createProcess(address service, bytes32 productId, string calldata data) external { _createProcess(address(0), service, productId, data); } function createProcess(address token, address service, bytes32 productId, string calldata data) external { _createProcess(token, service, productId, data); } function _rewardLoop(address validator, uint256 reward, address token) internal returns(uint256) { uint256 transfersSum = 0; IERC20 tokenContract; if(token != address(0)) { tokenContract = IERC20(token); } for (uint256 i = 0; i < _validatorStakers[validator].length; i++) { address staker = _validatorStakers[validator][i]; Stake storage stakeRecord = _stakes[staker][validator]; // Calc reward share according to the staked amount uint256 transferAmount = reward.mul(stakeRecord.amount.mul(100).div(_stakesByValidators[validator])).div(100); // Transfer reward to the staker if(token == address(0)) { payable(staker).transfer(transferAmount); } else { tokenContract.transfer(staker, transferAmount); } transfersSum += transferAmount; } return transfersSum; } function _bonusLoop(address validator, uint256 bonus) internal returns(uint256) { uint256 transfersSum = 0; for (uint256 i = 0; i < _validatorStakers[validator].length; i++) { address staker = _validatorStakers[validator][i]; // Calc bonus share according to the staked amount uint256 transferAmount = bonus.mul(_stakes[staker][validator].amount.mul(100).div(_stakesByValidators[validator])).div(100); // Increase stake with bonus _stakes[staker][validator].amount = _stakes[staker][validator].amount.add(transferAmount); transfersSum += transferAmount; } return transfersSum; } function _rewardStakers(address firstValidator, address secondValidator, uint256 rewardAmount, address token) internal returns(uint256) { uint256 firstReward = rewardAmount.mul(_stakesByValidators[firstValidator].mul(100).div(_stakesByValidators[firstValidator].add(_stakesByValidators[secondValidator]))).div(100); uint256 secondReward = rewardAmount - firstReward; uint256 firstRewardTsSum = _rewardLoop(firstValidator, firstReward, token); uint256 secondRewardTsSum = _rewardLoop(secondValidator, secondReward, token); return firstRewardTsSum + secondRewardTsSum; } function _rewardBonus(address firstValidator, address secondValidator, uint256 bonus) internal { uint256 firstBonus = bonus.mul(_stakesByValidators[firstValidator].mul(100).div(_stakesByValidators[firstValidator].add(_stakesByValidators[secondValidator]))).div(100); uint256 secondBonus = bonus - firstBonus; uint256 firstBonusTsSum = _bonusLoop(firstValidator, firstBonus); uint256 secondBonusTsSum = _bonusLoop(secondValidator, secondBonus); _stakesByValidators[firstValidator] += firstBonusTsSum; _stakesByValidators[secondValidator] += secondBonusTsSum; } function _makePayouts(address customer, bytes32 productId, bool needRefund, uint256 bonus) internal { Process storage process = _processes[customer][productId]; uint256 reward_amount = process.fee.mul(_services[process.service].validationPerc).div(100); uint256 transfers_sum = _rewardStakers(process.firstValidator, process.secondValidator, reward_amount, process.token); if(bonus > 0) { _rewardBonus(process.firstValidator, process.secondValidator, bonus); } if(needRefund == false) { uint256 commission_amount = process.fee.mul(_services[process.service].commissionPerc).div(100); if(process.token == address(0)) { payable(process.service).transfer(commission_amount); _beneficiary.transfer(process.fee - transfers_sum - commission_amount); } else { IERC20 tokenContract = IERC20(process.token); tokenContract.transfer(process.service, commission_amount); tokenContract.transfer(address(_beneficiary), process.fee - transfers_sum - commission_amount); } } else { if(process.token == address(0)) { payable(customer).transfer(process.fee - transfers_sum); } else { IERC20 tokenContract = IERC20(process.token); tokenContract.transfer(customer, process.fee - transfers_sum); } } } function _penalizeLoop(address validator, uint256 penalty) internal returns(uint256) { uint256 transfersSum = 0; for (uint256 i = 0; i < _validatorStakers[validator].length; i++) { address staker = _validatorStakers[validator][i]; uint256 transferAmount = penalty.mul(_stakes[staker][validator].amount.mul(100).div(_stakesByValidators[validator])).div(100); _stakes[staker][validator].amount = _stakes[staker][validator].amount - transferAmount; transfersSum += transferAmount; } // Subtract penalty from the validator total stakes amount _stakesByValidators[validator] -= transfersSum; return transfersSum; } function setProcessCost(address customer, bytes32 productId, uint256 cost, address payable depositAddr) external { require(_stakesByValidators[msg.sender] > 0, "Only validator with stakes can call this method"); Process storage process = _processes[customer][productId]; require(_containsAddress(_services[process.service].validators, msg.sender), "Your address is not whitelisted in the product service settings"); require(process.state == State.AWAITING_COST, "Cost is already set, check the state"); require( inTimeFrame( process.validatorsList, msg.sender, process.startBlock, TIME_FRAME_SIZE ), "Cannot accept validation, you are out of time" ); if(process.firstValidator == address(0)) { process.firstValidator = msg.sender; process.cost = cost; process.deposit = depositAddr; process.startBlock = block.number; process.validatorsList = _randValidatorsList(process.service, process.firstValidator, address(0)); emit CostRequest(customer, process.service, productId, process.validatorsList, ''); } else if(process.secondValidator == address(0)) { process.secondValidator = msg.sender; process.costConf = cost; process.depositConf = depositAddr; if(process.cost == process.costConf && process.deposit == process.depositConf) { Service storage service = _services[process.service]; if(service.feeNominator > 0 && service.feeDenominator > 0) { process.fee = cost.mul(service.feeNominator).div(service.feeDenominator); } else { process.fee = cost.mul(FEE_NOMINATOR).div(FEE_DENOMINATOR); } process.state = State.AWAITING_TRANSFER; emit CostResponse(customer, process.service, productId, cost); } else { process.startBlock = block.number; process.validatorsList = _randValidatorsList(process.service, process.firstValidator, process.secondValidator); emit CostRequest(customer, process.service, productId, process.validatorsList, ''); } } else { if(process.cost == cost && process.deposit == depositAddr) { process.secondValidator = msg.sender; process.costConf = cost; process.depositConf = depositAddr; } else { process.firstValidator = msg.sender; process.cost = cost; process.deposit = depositAddr; } process.cost = cost; Service storage service = _services[process.service]; if(service.feeNominator > 0 && service.feeDenominator > 0) { process.fee = cost.mul(service.feeNominator).div(service.feeDenominator); } else { process.fee = cost.mul(FEE_NOMINATOR).div(FEE_DENOMINATOR); } process.state = State.AWAITING_TRANSFER; emit CostResponse(customer, process.service, productId, cost); } } function declareAction(address customer, bytes32 productId, string calldata data) external onlyService { emit Action(customer, msg.sender, productId, data); } function startTermination(address customer, bytes32 productId) external { require((_services[msg.sender].validationPerc > 0) || (msg.sender == customer), "Only service or product customer can call this method"); Process storage process = _processes[customer][productId]; require(process.state == State.AWAITING_TERMINATION, "Cannot start termination, check the state"); process.state = State.AWAITING_VALIDATION; process.startBlock = block.number; process.validatorsList = _randValidatorsList(process.service, address(0), address(0)); process.firstValidator = address(0); process.firstResult = false; process.secondValidator = address(0); process.secondResult = false; emit Terminate(customer, msg.sender, productId, process.validatorsList); } function validateTermination(address customer, bytes32 productId, bool result) external { require(_stakesByValidators[msg.sender] > 0, "Only validator with stakes can call this method"); Process storage process = _processes[customer][productId]; require(_containsAddress(_services[process.service].validators, msg.sender), "Your address is not whitelisted in the product service settings"); require(process.state == State.AWAITING_VALIDATION, "Cannot accept validation, check the state"); require( inTimeFrame( process.validatorsList, msg.sender, process.startBlock, TIME_FRAME_SIZE ), "Cannot accept validation, you are out of time" ); // If we don't have first validator response yet if(process.firstValidator == address(0)) { process.firstValidator = msg.sender; process.firstResult = result; process.startBlock = block.number; process.validatorsList = _randValidatorsList(process.service, process.firstValidator, address(0)); emit Terminate(customer, process.service, productId, process.validatorsList); // If we have first validator response but not the second one } else if(process.secondValidator == address(0)) { process.secondValidator = msg.sender; process.secondResult = result; // If the first and second validator results match if(process.firstResult == process.secondResult) { _makePayouts(customer, productId, !process.firstResult, 0); process.state = State.COMPLETED; emit Complete(customer, process.service, productId, process.firstResult); // If the first and second validator results do not match } else { process.startBlock = block.number; process.validatorsList = _randValidatorsList(process.service, process.firstValidator, process.secondValidator); emit Terminate(customer, process.service, productId, process.validatorsList); } // If we have received the third validator response } else { if(process.firstResult == result) { uint256 penalty = _stakesByValidators[process.secondValidator].mul(_penaltyPerc).div(100); uint256 appliedPenalty = _penalizeLoop(process.secondValidator, penalty); process.secondValidator = msg.sender; process.secondResult = result; _makePayouts(customer, productId, !process.firstResult, appliedPenalty); } else { uint256 penalty = _stakesByValidators[process.firstValidator].mul(_penaltyPerc).div(100); uint256 appliedPenalty = _penalizeLoop(process.firstValidator, penalty); process.firstValidator = msg.sender; process.firstResult = result; _makePayouts(customer, productId, !process.firstResult, appliedPenalty); } process.state = State.COMPLETED; emit Complete(customer, process.service, productId, process.firstResult); } } function getProcess(address customer, bytes32 productId) external view returns(Process memory) { return _processes[customer][productId]; } function stake(address validator, uint256 amount) external { require(validator != address(0), "Validator address cannot be 0"); require(amount > 0, "Cannot stake 0"); bool success = _tokenContract.transferFrom(msg.sender, address(this), amount); if(success) { _totalStaked = _totalStaked.add(amount); bool alreadyStaked = false; if (_stakes[msg.sender][validator].amount > 0) { alreadyStaked = true; } _stakes[msg.sender][validator].amount = _stakes[msg.sender][validator].amount.add(amount); _stakes[msg.sender][validator].unlockingBlock = block.number + _lockingPeriod; _stakesByValidators[validator] = _stakesByValidators[validator].add(amount); if (alreadyStaked == false && _containsAddress(_validatorStakers[validator], msg.sender) == false) { _validatorStakers[validator].push(msg.sender); } emit Staked(msg.sender, validator, amount, _stakes[msg.sender][validator].unlockingBlock); } else { revert("Wasn't able to transfer your token"); } } function unStake(address validator, uint256 amount) external { require(amount > 0, "Cannot unstake 0"); require(_stakes[msg.sender][validator].amount >= amount, "Your balance is lower than the amount of tokens you want to unstake"); // Check locking period require(_stakes[msg.sender][validator].unlockingBlock <= block.number, "The locking period didn't pass, you cannot unstake"); // This will transfer the amount of token from contract to the sender balance bool success = _tokenContract.transfer(msg.sender, amount); if(success) { _totalStaked -= amount; _stakes[msg.sender][validator].amount = _stakes[msg.sender][validator].amount - amount; _stakesByValidators[validator] = _stakesByValidators[validator] - amount; emit UnStaked(msg.sender, validator, amount); } else { revert("Wasn't able to execute transfer of your tokens"); } } function stakeOf(address staker, address validator) external view returns (Stake memory) { return _stakes[staker][validator]; } function totalStakeOf(address validator) external view returns (uint256) { return _stakesByValidators[validator]; } function totalStaked() external view returns (uint256) { return _totalStaked; } function deposit(uint256 amount) external { address sender = _msgSender(); Process storage process = _processes[sender][_depositingProducts[sender]]; require(process.token != address(0), "The current process doesn't wait for an ERC20 token deposit"); require(process.state == State.AWAITING_TRANSFER, "You don't have a deposit awaiting process, please create it first"); require(process.cost == amount, "Deposit amount doesn't match with the requested cost"); // Create ERC20 token interface IERC20 tokenContract = IERC20(process.token); // Transfer deposit payment from customer to the contract tokenContract.safeTransferFrom(sender, address(this), amount); if(process.fee < process.cost) { // Transfer main payment from contract to the broker(subtracting the fee) tokenContract.safeTransfer(address(process.deposit), amount.sub(process.fee)); } // Update process state and emit an event process.state = State.AWAITING_TERMINATION; emit Deposit(sender, process.service, process.productId, amount); // TODO find out is it possible to revert function call after one of the safe transfers failed? } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"penaltyPerc","type":"uint256"},{"internalType":"uint256","name":"lockingPeriod","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"Action","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"Complete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"address[]","name":"validatorsList","type":"address[]"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"CostRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"cost","type":"uint256"}],"name":"CostResponse","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockingBlock","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"customer","type":"address"},{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"bytes32","name":"productId","type":"bytes32"},{"indexed":false,"internalType":"address[]","name":"validatorsList","type":"address[]"}],"name":"Terminate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnStaked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"service","type":"address"},{"internalType":"address[]","name":"vList","type":"address[]"},{"internalType":"uint256","name":"fNominator","type":"uint256"},{"internalType":"uint256","name":"fDenominator","type":"uint256"}],"name":"addService","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"service","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"string","name":"data","type":"string"}],"name":"createProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"service","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"string","name":"data","type":"string"}],"name":"createProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"customer","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"string","name":"data","type":"string"}],"name":"declareAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLockingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPenaltyPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"customer","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"}],"name":"getProcess","outputs":[{"components":[{"internalType":"enum YandaMultitokenProtocolV2.State","name":"state","type":"uint8"},{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256","name":"costConf","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address payable","name":"deposit","type":"address"},{"internalType":"address payable","name":"depositConf","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"service","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"address[]","name":"validatorsList","type":"address[]"},{"internalType":"address","name":"firstValidator","type":"address"},{"internalType":"bool","name":"firstResult","type":"bool"},{"internalType":"address","name":"secondValidator","type":"address"},{"internalType":"bool","name":"secondResult","type":"bool"}],"internalType":"struct YandaMultitokenProtocolV2.Process","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingTokenAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidationTimeFrame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"service","type":"address"}],"name":"getValidatorVer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newAddr","type":"address"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vPerc","type":"uint256"},{"internalType":"uint256","name":"bPerc","type":"uint256"}],"name":"setDefaultPerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLockingPeriod","type":"uint256"}],"name":"setLockingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPenaltyPerc","type":"uint256"}],"name":"setPenaltyPerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"customer","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"address payable","name":"depositAddr","type":"address"}],"name":"setProcessCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nominator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"setProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"service","type":"address"},{"internalType":"uint256","name":"vPerc","type":"uint256"},{"internalType":"uint256","name":"bPerc","type":"uint256"}],"name":"setServicePerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blocks","type":"uint256"}],"name":"setValidationTimeFrame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vVer","type":"uint256"}],"name":"setValidatorVer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"vList","type":"address[]"}],"name":"setValidators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"address","name":"validator","type":"address"}],"name":"stakeOf","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockingBlock","type":"uint256"}],"internalType":"struct YandaMultitokenProtocolV2.Stake","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"customer","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"}],"name":"startTermination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"totalStakeOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"customer","type":"address"},{"internalType":"bytes32","name":"productId","type":"bytes32"},{"internalType":"bool","name":"result","type":"bool"}],"name":"validateTermination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162004be538038062004be5833981016040819052620000349162000137565b6200004160003362000096565b600a8054336001600160a01b0319918216178255600694909455600792909255600980549093166001600160a01b039190911617909155600f600290815560506003556004556103e86005556001556200017d565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000133576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620000f23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000806000606084860312156200014c578283fd5b83516020850151604086015191945092506001600160a01b038116811462000172578182fd5b809150509250925092565b614a58806200018d6000396000f3fe6080604052600436106102085760003560e01c8063817b1cd211610118578063adc9772e116100a0578063d93938141161006f578063d939381414610868578063e3f56eaa14610888578063e9b87387146108be578063ef4604a9146108eb578063fd6d2dcf1461090b57610420565b8063adc9772e14610784578063b6b55f25146107a4578063ce4cb876146107c4578063d547741f1461084857610420565b806389f18983116100e757806389f18983146106ef57806391d148541461070f5780639300c9261461072f5780639e7455eb1461074f578063a217fddf1461076f57610420565b8063817b1cd21461067d57806384f3ca41146106925780638670fdd9146106ba57806389bf146a146106cf57610420565b80632f2ff15d1161019b578063402fbbd81161016a578063402fbbd8146105f357806344715aaa146106085780635f96529f1461062857806363de06f814610648578063787ef2421461066857610420565b80632f2ff15d146105735780633293025c1461059357806336568abe146105b357806338f8f528146105d357610420565b80631c31f710116101d75780631c31f710146104e3578063240de27714610503578063248a9ca31461052357806326b321d11461055357610420565b806301ffc9a71461042557806304f32b5d1461045a5780630cb395db1461047c5780630e53e633146104c357610420565b3661042057336000818152600b60209081526040808320600c8352818420548452909152902060038101546001600160a01b0316156102aa5760405162461bcd60e51b815260206004820152603360248201527f5468652063757272656e742070726f63657373207761697420666f7220616e20604482015272115490cc8c081d1bdad95b8819195c1bdcda5d606a1b60648201526084015b60405180910390fd5b6001815460ff1660048111156102d057634e487b7160e01b600052602160045260246000fd5b146102ed5760405162461bcd60e51b81526004016102a190614712565b348160010154146103665760405162461bcd60e51b815260206004820152603760248201527f4465706f73697420616d6f756e7420646f65736e2774206d617463682077697460448201527f682074686520726571756573746564206465706f73697400000000000000000060648201526084016102a1565b8060010154816006015410156103c557600481015460068201546001600160a01b03909116906108fc9061039b90349061092b565b6040518115909202916000818181858888f193505050501580156103c3573d6000803e3d6000fd5b505b805460ff19166002178155600881015460078201546040513481526001600160a01b03918216918516907f1f0f1dee49a1720a0d98e3a0575a04dd9f143ff5e29555c3085471c1c70eed5b9060200160405180910390a45050005b600080fd5b34801561043157600080fd5b506104456104403660046143c6565b610940565b60405190151581526020015b60405180910390f35b34801561046657600080fd5b5061047a610475366004614264565b610979565b005b34801561048857600080fd5b506104b56104973660046140d5565b6001600160a01b03166000908152600d602052604090206003015490565b604051908152602001610451565b3480156104cf57600080fd5b5061047a6104de3660046141f8565b6109f9565b3480156104ef57600080fd5b5061047a6104fe3660046140d5565b610be4565b34801561050f57600080fd5b5061047a61051e3660046143ee565b610c12565b34801561052f57600080fd5b506104b561053e36600461438a565b60009081526020819052604090206001015490565b34801561055f57600080fd5b5061047a61056e36600461438a565b610c29565b34801561057f57600080fd5b5061047a61058e3660046143a2565b610c3a565b34801561059f57600080fd5b5061047a6105ae36600461438a565b610c64565b3480156105bf57600080fd5b5061047a6105ce3660046143a2565b610c75565b3480156105df57600080fd5b5061047a6105ee366004614264565b610cf3565b3480156105ff57600080fd5b506007546104b5565b34801561061457600080fd5b5061047a61062336600461419a565b610d07565b34801561063457600080fd5b5061047a610643366004614129565b610e00565b34801561065457600080fd5b5061047a61066336600461438a565b610e14565b34801561067457600080fd5b506001546104b5565b34801561068957600080fd5b506008546104b5565b34801561069e57600080fd5b506009546040516001600160a01b039091168152602001610451565b3480156106c657600080fd5b506006546104b5565b3480156106db57600080fd5b5061047a6106ea366004614223565b610e55565b3480156106fb57600080fd5b5061047a61070a36600461438a565b6113dc565b34801561071b57600080fd5b5061044561072a3660046143a2565b6113ed565b34801561073b57600080fd5b5061047a61074a36600461433b565b611416565b34801561075b57600080fd5b5061047a61076a3660046142be565b611462565b34801561077b57600080fd5b506104b5600081565b34801561079057600080fd5b5061047a61079f3660046141f8565b611a0d565b3480156107b057600080fd5b5061047a6107bf36600461438a565b611d9d565b3480156107d057600080fd5b5061082d6107df3660046140f1565b604080518082018252600080825260209182018190526001600160a01b0394851681526010825282812093909416845291825291829020825180840190935280548352600101549082015290565b60408051825181526020928301519281019290925201610451565b34801561085457600080fd5b5061047a6108633660046143a2565b611fa3565b34801561087457600080fd5b5061047a6108833660046141f8565b611fc8565b34801561089457600080fd5b506104b56108a33660046140d5565b6001600160a01b03166000908152600e602052604090205490565b3480156108ca57600080fd5b506108de6108d93660046141f8565b612309565b60405161045191906147ba565b3480156108f757600080fd5b5061047a610906366004614307565b612511565b34801561091757600080fd5b5061047a6109263660046143ee565b612544565b60006109378284614934565b90505b92915050565b60006001600160e01b03198216637965db0b60e01b148061097157506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b336000908152600d60205260409020546109a55760405162461bcd60e51b81526004016102a190614779565b82336001600160a01b0316856001600160a01b03167fb67fab32200b6a6d186136689c0b4c4072ae0bd5dd17b98fb8105d1b9747939985856040516109eb9291906145d2565b60405180910390a450505050565b336000908152600d6020526040902060010154151580610a215750336001600160a01b038316145b610a8b5760405162461bcd60e51b815260206004820152603560248201527f4f6e6c792073657276696365206f722070726f6475637420637573746f6d65726044820152740818d85b8818d85b1b081d1a1a5cc81b595d1a1bd9605a1b60648201526084016102a1565b6001600160a01b0382166000908152600b6020908152604080832084845290915290206002815460ff166004811115610ad457634e487b7160e01b600052602160045260246000fd5b14610b335760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f74207374617274207465726d696e6174696f6e2c20636865636b2060448201526874686520737461746560b81b60648201526084016102a1565b805460ff191660031781554360098201556007810154610b5e906001600160a01b031660008061255b565b8051610b7491600a840191602090910190613f4a565b50600b810180546001600160a81b0319908116909155600c820180549091169055604051829033906001600160a01b038616907f2ec6ff0a3927bfb55544f85fb0e2367f025ffb0b469ec8276385f8e569e0376e90610bd790600a87019061456a565b60405180910390a4505050565b6000610bef81612999565b50600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c1d81612999565b50600491909155600555565b6000610c3481612999565b50600755565b600082815260208190526040902060010154610c5581612999565b610c5f83836129a6565b505050565b6000610c6f81612999565b50600655565b6001600160a01b0381163314610ce55760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016102a1565b610cef8282612a2a565b5050565b610d01600085858585612a8f565b50505050565b6000610d1281612999565b6002845111610d635760405162461bcd60e51b815260206004820181905260248201527f56616c696461746f7273206d696e696d756d207175616e74697479206973203360448201526064016102a1565b6040805160c08101825285815260025460208083019190915260035482840152600160608301526080820186905260a082018590526001600160a01b0388166000908152600d8252929092208151805192939192610dc49284920190613f4a565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0909101516005909101555050505050565b610e0d8585858585612a8f565b5050505050565b336000908152600d6020526040902054610e405760405162461bcd60e51b81526004016102a190614779565b336000908152600d6020526040902060030155565b336000908152600e6020526040902054610e815760405162461bcd60e51b81526004016102a190614619565b6001600160a01b038084166000908152600b60209081526040808320868452825280832060078101549094168352600d8252918290208054835181840281018401909452808452610f119392830182828015610f0657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ee8575b505050505033612ef9565b610f2d5760405162461bcd60e51b81526004016102a1906146b5565b6003815460ff166004811115610f5357634e487b7160e01b600052602160045260246000fd5b14610fb25760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f74206163636570742076616c69646174696f6e2c20636865636b2060448201526874686520737461746560b81b60648201526084016102a1565b61102081600a0180548060200260200160405190810160405280929190818152602001828054801561100d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610fef575b5050505050338360090154600154612f6d565b61103c5760405162461bcd60e51b81526004016102a190614668565b600b8101546001600160a01b031661110657600b810180546001600160a81b0319163360ff60a01b191617600160a01b8415150217908190554360098301556007820154611098916001600160a01b039182169116600061255b565b80516110ae91600a840191602090910190613f4a565b50600781015460405184916001600160a01b0390811691908716907f2ec6ff0a3927bfb55544f85fb0e2367f025ffb0b469ec8276385f8e569e0376e906110f990600a87019061456a565b60405180910390a4610d01565b600c8101546001600160a01b031661122157600c810180546001600160a81b0319163360ff60a01b191617600160a01b84151581029190911791829055600b8301549181900460ff90811615159190920491909116151514156111ee57611182848483600b0160149054906101000a900460ff16156000613021565b8054600460ff199091161781556007810154600b82015460408051600160a01b90920460ff16151582525185926001600160a01b0390811692908816917f5c2cc6518d5891ba2f9c21f49d712982ba12450a2a8adeb21e4a41f85a995b709181900360200190a461121c565b4360098201556007810154600b820154600c830154611098926001600160a01b03908116928116911661255b565b610d01565b600b81015460ff600160a01b90910416151582151514156112e157600654600c8201546001600160a01b03166000908152600e602052604081205490916112759160649161126f9190613407565b90613413565b600c830154909150600090611293906001600160a01b03168361341f565b600c840180546001600160a81b0319163360ff60a01b191617600160a01b871515810291909117909155600b8501549192506112da918891889160ff919004161584613021565b5050611377565b600654600b8201546001600160a01b03166000908152600e602052604081205490916113149160649161126f9190613407565b600b830154909150600090611332906001600160a01b03168361341f565b600b840180546001600160a81b0319163360ff60a01b191617600160a01b87151581029190911791829055919250611374918891889160ff9104161584613021565b50505b8054600460ff199091161781556007810154600b820154604051600160a01b90910460ff161515815284916001600160a01b0390811691908716907f5c2cc6518d5891ba2f9c21f49d712982ba12450a2a8adeb21e4a41f85a995b70906020016109eb565b60006113e781612999565b50600155565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b336000908152600d60205260409020546114425760405162461bcd60e51b81526004016102a190614779565b336000908152600d602090815260409091208251610cef92840190613f4a565b336000908152600e602052604090205461148e5760405162461bcd60e51b81526004016102a190614619565b6001600160a01b038085166000908152600b60209081526040808320878452825280832060078101549094168352600d825291829020805483518184028101840190945280845261151c9392830182828015610f06576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610ee857505050505033612ef9565b6115385760405162461bcd60e51b81526004016102a1906146b5565b6000815460ff16600481111561155e57634e487b7160e01b600052602160045260246000fd5b146115b75760405162461bcd60e51b8152602060048201526024808201527f436f737420697320616c7265616479207365742c20636865636b2074686520736044820152637461746560e01b60648201526084016102a1565b61162381600a0180548060200260200160405190810160405280929190818152602001828054801561100d576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610fef575050505050338360090154600154612f6d565b61163f5760405162461bcd60e51b81526004016102a190614668565b600b8101546001600160a01b031661171057600b810180546001600160a01b031990811633908117909255600183018590556004830180546001600160a01b038681169190931617905543600984015560078301546116a292911690600061255b565b80516116b891600a840191602090910190613f4a565b50600781015460405185916001600160a01b0390811691908816907fde23c39256eb8276bf5f5a3b3654613cb6dc5d9a36e408f3ad61e531217b0d899061170390600a8701906145ad565b60405180910390a4610e0d565b600c8101546001600160a01b031661189257600c81018054336001600160a01b031991821617909155600282018490556005820180549091166001600160a01b03841617905560018101548314801561177d5750600581015460048201546001600160a01b039081169116145b1561185f5760078101546001600160a01b03166000908152600d602052604090206004810154158015906117b5575060008160050154115b156117e3576117d9816005015461126f83600401548761340790919063ffffffff16565b6006830155611804565b6117fe60055461126f6004548761340790919063ffffffff16565b60068301555b815460ff19166001178255600782015460405185815286916001600160a01b0390811691908916907f9829c39553001f6f75967caf0b4a8a903f5332af8a010a6b7e8532b7ed023f519060200160405180910390a45061188d565b4360098201556007810154600b820154600c8301546116a2926001600160a01b03908116928116911661255b565b610e0d565b8281600101541480156118b4575060048101546001600160a01b038381169116145b156118f257600c81018054336001600160a01b031991821617909155600282018490556005820180549091166001600160a01b038416179055611927565b600b81018054336001600160a01b031991821617909155600182018490556004820180549091166001600160a01b0384161790555b6001810183905560078101546001600160a01b03166000908152600d60205260409020600481015415801590611961575060008160050154115b1561198f57611985816005015461126f83600401548761340790919063ffffffff16565b60068301556119b0565b6119aa60055461126f6004548761340790919063ffffffff16565b60068301555b815460ff19166001178255600782015460405185815286916001600160a01b0390811691908916907f9829c39553001f6f75967caf0b4a8a903f5332af8a010a6b7e8532b7ed023f519060200160405180910390a4505050505050565b6001600160a01b038216611a635760405162461bcd60e51b815260206004820152601d60248201527f56616c696461746f7220616464726573732063616e6e6f74206265203000000060448201526064016102a1565b60008111611aa45760405162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b60448201526064016102a1565b6009546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd90606401602060405180830381600087803b158015611af757600080fd5b505af1158015611b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2f919061436e565b90508015611d4a57600854611b44908361358c565b6008553360009081526010602090815260408083206001600160a01b038716845290915281205415611b74575060015b3360009081526010602090815260408083206001600160a01b0388168452909152902054611ba2908461358c565b3360009081526010602090815260408083206001600160a01b0389168452909152902055600754611bd390436148e9565b3360009081526010602090815260408083206001600160a01b0389168452825280832060010193909355600e90522054611c0d908461358c565b6001600160a01b0385166000908152600e602052604090205580158015611ca557506001600160a01b0384166000908152600f60209081526040918290208054835181840281018401909452808452611ca39392830182828015610f06576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610ee857505050505033612ef9565b155b15611ce3576001600160a01b0384166000908152600f602090815260408220805460018101825590835291200180546001600160a01b031916331790555b3360008181526010602090815260408083206001600160a01b03891680855290835292819020600101548151888152928301529192917f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc910160405180910390a350610c5f565b60405162461bcd60e51b815260206004820152602260248201527f5761736e27742061626c6520746f207472616e7366657220796f757220746f6b60448201526132b760f11b60648201526084016102a1565b336000818152600b60209081526040808320600c8352818420548452909152902060038101546001600160a01b0316611e3e5760405162461bcd60e51b815260206004820152603b60248201527f5468652063757272656e742070726f6365737320646f65736e2774207761697460448201527f20666f7220616e20455243323020746f6b656e206465706f736974000000000060648201526084016102a1565b6001815460ff166004811115611e6457634e487b7160e01b600052602160045260246000fd5b14611e815760405162461bcd60e51b81526004016102a190614712565b82816001015414611ef15760405162461bcd60e51b815260206004820152603460248201527f4465706f73697420616d6f756e7420646f65736e2774206d61746368207769746044820152731a081d1a19481c995c5d595cdd19590818dbdcdd60621b60648201526084016102a1565b60038101546001600160a01b0316611f0b81843087613598565b816001015482600601541015611f4f5760048201546006830154611f4f916001600160a01b031690611f3e90879061092b565b6001600160a01b0384169190613603565b815460ff19166002178255600882015460078301546040518681526001600160a01b03918216918616907f1f0f1dee49a1720a0d98e3a0575a04dd9f143ff5e29555c3085471c1c70eed5b906020016109eb565b600082815260208190526040902060010154611fbe81612999565b610c5f8383612a2a565b6000811161200b5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f7420756e7374616b6520360841b60448201526064016102a1565b3360009081526010602090815260408083206001600160a01b03861684529091529020548111156120b05760405162461bcd60e51b815260206004820152604360248201527f596f75722062616c616e6365206973206c6f776572207468616e20746865206160448201527f6d6f756e74206f6620746f6b656e7320796f752077616e7420746f20756e7374606482015262616b6560e81b608482015260a4016102a1565b3360009081526010602090815260408083206001600160a01b03861684529091529020600101544310156121415760405162461bcd60e51b815260206004820152603260248201527f546865206c6f636b696e6720706572696f64206469646e277420706173732c20604482015271796f752063616e6e6f7420756e7374616b6560701b60648201526084016102a1565b60095460405163a9059cbb60e01b8152336004820152602481018390526000916001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561218e57600080fd5b505af11580156121a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c6919061436e565b905080156122aa5781600860008282546121e09190614934565b90915550503360009081526010602090815260408083206001600160a01b0387168452909152902054612214908390614934565b3360009081526010602090815260408083206001600160a01b0388168452825280832093909355600e9052205461224c908390614934565b6001600160a01b0384166000818152600e60205260409081902092909255905133907f8a3c16627a0e7a870a5d5cd0121ca5d80e2efd0ec7198a11644f1a516ac370939061229d9086815260200190565b60405180910390a3610c5f565b60405162461bcd60e51b815260206004820152602e60248201527f5761736e27742061626c6520746f2065786563757465207472616e736665722060448201526d6f6620796f757220746f6b656e7360901b60648201526084016102a1565b604080516101e080820183526000808352602080840182905283850182905260608085018390526080850183905260a0850183905260c0850183905260e0850183905261010085018390526101208501839052610140850152610160840182905261018084018290526101a084018290526101c084018290526001600160a01b0387168252600b815284822086835290528390208351918201909352825491929091829060ff1660048111156123cf57634e487b7160e01b600052602160045260246000fd5b60048111156123ee57634e487b7160e01b600052602160045260246000fd5b81526001820154602080830191909152600283015460408084019190915260038401546001600160a01b0390811660608501526004850154811660808501526005850154811660a0850152600685015460c085015260078501541660e084015260088401546101008401526009840154610120840152600a840180548251818502810185019093528083526101409094019391929091908301828280156124be57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116124a0575b5050509183525050600b8201546001600160a01b03808216602084015260ff600160a01b92839004811615156040850152600c909401549081166060840152049091161515608090910152905092915050565b600061251c81612999565b506001600160a01b039092166000908152600d60205260409020600181019190915560020155565b600061254f81612999565b50600291909155600355565b6001600160a01b038082166000908152600e60205260408082205492851682528120546008546060939161258e91614934565b6125989190614934565b6001600160a01b038087166000908152600d602052604081205492935091908616156125cc576125c9600182614934565b90505b6001600160a01b038516156125e9576125e6600182614934565b90505b60008167ffffffffffffffff81111561261257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561263b578160200160208202803683370190505b50905060005b815181101561298b5784612653613633565b61265d91906149a9565b935060005b6001600160a01b038a166000908152600d6020526040902054811015612978576001600160a01b038a81166000908152600d602052604090208054918b1691839081106126bf57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161480159061273257506001600160a01b038a81166000908152600d602052604090208054918a16918390811061271a57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614155b15612966576001600160a01b038a166000908152600d60205260409020805461278f9185918490811061277557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316612ef9565b612966576001600160a01b038a166000908152600d602052604081208054600e929190849081106127d057634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0316835282019290925260400190205485116128f7576001600160a01b038a166000908152600d6020526040902080548290811061283357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b031683838151811061287157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201810191909152908b166000908152600d909152604081208054600e929190849081106128c157634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b031683528201929092526040019020546128f09087614934565b9550612978565b6001600160a01b038a166000908152600d602052604081208054600e9291908490811061293457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b031683528201929092526040019020546129639086614934565b94505b806129708161498e565b915050612662565b50806129838161498e565b915050612641565b5093505050505b9392505050565b6129a3813361366f565b50565b6129b082826113ed565b610cef576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556129e63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612a3482826113ed565b15610cef576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b0384166000908152600d6020526040902060010154612b035760405162461bcd60e51b815260206004820152602360248201527f52657175657374656420736572766963652061646472657373206e6f7420666f6044820152621d5b9960ea1b60648201526084016102a1565b336000908152600b602090815260408083208684529091529020600701546001600160a01b031615612b8e5760405162461bcd60e51b815260206004820152602e60248201527f50726f636573732077697468207370656369666965642070726f64756374496460448201526d08185b1c9958591e48195e1a5cdd60921b60648201526084016102a1565b604080516101e0810190915280600081526020016000815260200160008152602001866001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001856001600160a01b03168152602001848152602001438152602001612c0d8660008061255b565b8152600060208083018290526040808401839052606084018390526080909301829052338252600b815282822087835290522081518154829060ff19166001836004811115612c6c57634e487b7160e01b600052602160045260246000fd5b021790555060208281015160018301556040830151600283015560608301516003830180546001600160a01b039283166001600160a01b031991821617909155608085015160048501805491841691831691909117905560a085015160058501805491841691831691909117905560c0850151600685015560e0850151600785018054919093169116179055610100830151600883015561012083015160098301556101408301518051612d2692600a8501920190613f4a565b50610160820151600b80830180546101808601511515600160a01b9081026001600160a81b03199283166001600160a01b0396871617179092556101a0860151600c90950180546101c0909701511515909202951693831693909317939093179091553360008181526020938452604080822088835290945283902092518693928816927fde23c39256eb8276bf5f5a3b3654613cb6dc5d9a36e408f3ad61e531217b0d8991612ddd91600a01908890889061457d565b60405180910390a4336000908152600b60209081526040808320600c835281842054845290915290205460019060ff166004811115612e2c57634e487b7160e01b600052602160045260246000fd5b1415612ee357336000908152600b60209081526040808320600c83528184205484529091528120805460ff1916815560018101829055600281018290556003810180546001600160a01b03199081169091556004820180548216905560058201805482169055600682018390556007820180549091169055600881018290556009810182905590612ec0600a830182613faf565b50600b810180546001600160a81b0319908116909155600c909101805490911690555b5050336000908152600c60205260409020555050565b6000805b8351811015612f6357826001600160a01b0316848281518110612f3057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415612f5157600191505061093a565b80612f5b8161498e565b915050612efd565b5060009392505050565b6000805b855181101561301357846001600160a01b0316868281518110612fa457634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561300157612fc58443614934565b612fcf8483614915565b11158015612ff9575082612fe38183614915565b612fed91906148e9565b612ff78543614934565b105b915050613019565b8061300b8161498e565b915050612f71565b50600090505b949350505050565b6001600160a01b038085166000908152600b60209081526040808320878452825280832060078101549094168352600d909152812060010154600683015461306f9160649161126f91613407565b600b830154600c840154600385015492935060009261309f926001600160a01b03908116928116918691166136d3565b905083156130c857600b830154600c8401546130c8916001600160a01b03908116911686613782565b846132fb5760078301546001600160a01b03166000908152600d602052604081206002015460068501546131029160649161126f91613407565b60038501549091506001600160a01b03166131b15760078401546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015613153573d6000803e3d6000fd5b50600a5460068501546001600160a01b03909116906108fc908390613179908690614934565b6131839190614934565b6040518115909202916000818181858888f193505050501580156131ab573d6000803e3d6000fd5b506132f5565b6003840154600785015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052911690819063a9059cbb90604401602060405180830381600087803b15801561320757600080fd5b505af115801561321b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323f919061436e565b50600a5460068601546001600160a01b038084169263a9059cbb92911690859061326a908890614934565b6132749190614934565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156132ba57600080fd5b505af11580156132ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f2919061436e565b50505b506133fe565b60038301546001600160a01b031661335257866001600160a01b03166108fc82856006015461332a9190614934565b6040518115909202916000818181858888f193505050501580156132f5573d6000803e3d6000fd5b600383015460068401546001600160a01b0390911690819063a9059cbb908a9061337d908690614934565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156133c357600080fd5b505af11580156133d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fb919061436e565b50505b50505050505050565b60006109378284614915565b60006109378284614901565b600080805b6001600160a01b0385166000908152600f6020526040902054811015613556576001600160a01b0385166000908152600f6020526040812080548390811061347c57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03898116808552600e845260408086205492909316808652601085528386209186529352908320549193506134db9160649161126f916134d49190839085613407565b8990613407565b6001600160a01b038084166000908152601060209081526040808320938c168352929052205490915061350f908290614934565b6001600160a01b038084166000908152601060209081526040808320938c168352929052205561353f81856148e9565b93505050808061354e9061498e565b915050613424565b506001600160a01b0384166000908152600e60205260408120805483929061357f908490614934565b9091555090949350505050565b600061093782846148e9565b6040516001600160a01b0380851660248301528316604482015260648101829052610d019085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261387d565b6040516001600160a01b038316602482015260448101829052610c5f90849063a9059cbb60e01b906064016135cc565b60004442604051602001613651929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905090565b61367982826113ed565b610cef57613691816001600160a01b0316601461394f565b61369c83602061394f565b6040516020016136ad9291906144f5565b60408051601f198184030181529082905262461bcd60e51b82526102a1916004016145e6565b6001600160a01b038084166000908152600e60205260408082205492871682528120549091829161373d9160649161126f91613736916137129161358c565b6001600160a01b038b166000908152600e602052604090205461126f906064613407565b8790613407565b9050600061374b8286614934565b9050600061375a888487613b31565b90506000613769888488613b31565b905061377581836148e9565b9998505050505050505050565b6001600160a01b038083166000908152600e602052604080822054928616825281205490916137eb9160649161126f916137e4916137c0919061358c565b6001600160a01b0389166000908152600e602052604090205461126f906064613407565b8590613407565b905060006137f98284614934565b905060006138078684613cff565b905060006138158684613cff565b6001600160a01b0388166000908152600e60205260408120805492935084929091906138429084906148e9565b90915550506001600160a01b0386166000908152600e60205260408120805483929061386f9084906148e9565b909155505050505050505050565b60006138d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613e369092919063ffffffff16565b805190915015610c5f57808060200190518101906138f0919061436e565b610c5f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a1565b6060600061395e836002614915565b6139699060026148e9565b67ffffffffffffffff81111561398f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156139b9576020820181803683370190505b509050600360fc1b816000815181106139e257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613a1f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613a43846002614915565b613a4e9060016148e9565b90505b6001811115613ae2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a9057634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613ab457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613adb81614977565b9050613a51565b5083156109375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016102a1565b600080806001600160a01b03841615613b475750825b60005b6001600160a01b0387166000908152600f6020526040902054811015613cf4576001600160a01b0387166000908152600f60205260408120805483908110613ba257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03908116808452601083526040808520928d168552918352818420600e909352908320548254919450919291613c029160649161126f91613bfb9190839085613407565b8c90613407565b90506001600160a01b038816613c4e576040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015613c48573d6000803e3d6000fd5b50613cd2565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905286169063a9059cbb90604401602060405180830381600087803b158015613c9857600080fd5b505af1158015613cac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd0919061436e565b505b613cdc81876148e9565b95505050508080613cec9061498e565b915050613b4a565b509095945050505050565b600080805b6001600160a01b0385166000908152600f6020526040902054811015613e2e576001600160a01b0385166000908152600f60205260408120805483908110613d5c57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03898116808552600e84526040808620549290931680865260108552838620918652935290832054919350613db49160649161126f916134d49190839085613407565b6001600160a01b038084166000908152601060209081526040808320938c1683529290522054909150613de7908261358c565b6001600160a01b038084166000908152601060209081526040808320938c1683529290522055613e1781856148e9565b935050508080613e269061498e565b915050613d04565b509392505050565b60606130198484600085856001600160a01b0385163b613e985760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a1565b600080866001600160a01b03168587604051613eb491906144d9565b60006040518083038185875af1925050503d8060008114613ef1576040519150601f19603f3d011682016040523d82523d6000602084013e613ef6565b606091505b5091509150613f06828286613f11565b979650505050505050565b60608315613f20575081612992565b825115613f305782518084602001fd5b8160405162461bcd60e51b81526004016102a191906145e6565b828054828255906000526020600020908101928215613f9f579160200282015b82811115613f9f57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613f6a565b50613fab929150613fc9565b5090565b50805460008255906000526020600020908101906129a391905b5b80821115613fab5760008155600101613fca565b8035610974816149ff565b600082601f830112613ff9578081fd5b8135602067ffffffffffffffff80831115614016576140166149e9565b8260051b604051601f19603f8301168101818110848211171561403b5761403b6149e9565b60405284815283810192508684018288018501891015614059578687fd5b8692505b858310156140825761406e81613fde565b84529284019260019290920191840161405d565b50979650505050505050565b60008083601f84011261409f578182fd5b50813567ffffffffffffffff8111156140b6578182fd5b6020830191508360208285010111156140ce57600080fd5b9250929050565b6000602082840312156140e6578081fd5b8135610937816149ff565b60008060408385031215614103578081fd5b823561410e816149ff565b9150602083013561411e816149ff565b809150509250929050565b600080600080600060808688031215614140578081fd5b853561414b816149ff565b9450602086013561415b816149ff565b935060408601359250606086013567ffffffffffffffff81111561417d578182fd5b6141898882890161408e565b969995985093965092949392505050565b600080600080608085870312156141af578384fd5b84356141ba816149ff565b9350602085013567ffffffffffffffff8111156141d5578384fd5b6141e187828801613fe9565b949794965050505060408301359260600135919050565b6000806040838503121561420a578182fd5b8235614215816149ff565b946020939093013593505050565b600080600060608486031215614237578283fd5b8335614242816149ff565b925060208401359150604084013561425981614a14565b809150509250925092565b60008060008060608587031215614279578384fd5b8435614284816149ff565b935060208501359250604085013567ffffffffffffffff8111156142a6578283fd5b6142b28782880161408e565b95989497509550505050565b600080600080608085870312156142d3578384fd5b84356142de816149ff565b9350602085013592506040850135915060608501356142fc816149ff565b939692955090935050565b60008060006060848603121561431b578283fd5b8335614326816149ff565b95602085013595506040909401359392505050565b60006020828403121561434c578081fd5b813567ffffffffffffffff811115614362578182fd5b61301984828501613fe9565b60006020828403121561437f578081fd5b815161093781614a14565b60006020828403121561439b578081fd5b5035919050565b600080604083850312156143b4578182fd5b82359150602083013561411e816149ff565b6000602082840312156143d7578081fd5b81356001600160e01b031981168114610937578182fd5b60008060408385031215614400578182fd5b50508035926020909101359150565b6000815180845260208085019450808401835b838110156144475781516001600160a01b031687529582019590820190600101614422565b509495945050505050565b6000815480845260208085019450838352808320835b838110156144475781546001600160a01b031687529582019560019182019101614468565b600581106144ab57634e487b7160e01b600052602160045260246000fd5b9052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600082516144eb81846020870161494b565b9190910192915050565b60007f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008252835161452d81601785016020880161494b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161455e81602884016020880161494b565b01602801949350505050565b6000602082526109376020830184614452565b6000604082526145906040830186614452565b82810360208401526145a38185876144af565b9695505050505050565b6000604082526145c06040830184614452565b82810360209384015290815201919050565b6000602082526130196020830184866144af565b600060208252825180602084015261460581604085016020870161494b565b601f01601f19169190910160400192915050565b6020808252602f908201527f4f6e6c792076616c696461746f722077697468207374616b65732063616e206360408201526e185b1b081d1a1a5cc81b595d1a1bd9608a1b606082015260800190565b6020808252602d908201527f43616e6e6f74206163636570742076616c69646174696f6e2c20796f7520617260408201526c65206f7574206f662074696d6560981b606082015260800190565b6020808252603f908201527f596f75722061646472657373206973206e6f742077686974656c69737465642060408201527f696e207468652070726f6475637420736572766963652073657474696e677300606082015260800190565b60208082526041908201527f596f7520646f6e277420686176652061206465706f736974206177616974696e60408201527f672070726f636573732c20706c656173652063726561746520697420666972736060820152601d60fa1b608082015260a00190565b60208082526021908201527f4f6e6c7920736572766963652063616e2063616c6c2074686973206d6574686f6040820152601960fa1b606082015260800190565b6000602082526147ce60208301845161448d565b602083015160408301526040830151606083015260608301516147fc60808401826001600160a01b03169052565b5060808301516001600160a01b03811660a08401525060a08301516001600160a01b03811660c08401525060c083015160e083015260e083015161010061484d818501836001600160a01b03169052565b84015161012084810191909152840151610140808501919091528401516101e06101608086018290529192509061488861020086018461440f565b908601519092506101806148a6868201836001600160a01b03169052565b86015190506101a06148bb8682018315159052565b86015190506101c06148d7868201836001600160a01b03169052565b90950151151593019290925250919050565b600082198211156148fc576148fc6149bd565b500190565b600082614910576149106149d3565b500490565b600081600019048311821515161561492f5761492f6149bd565b500290565b600082821015614946576149466149bd565b500390565b60005b8381101561496657818101518382015260200161494e565b83811115610d015750506000910152565b600081614986576149866149bd565b506000190190565b60006000198214156149a2576149a26149bd565b5060010190565b6000826149b8576149b86149d3565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146129a357600080fd5b80151581146129a357600080fdfea26469706673582212203ec26f75fe81ee04fa38f77f93a68abe326b6185e8d4f2251d84b9db6a534eef64736f6c63430008030033000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000005100000000000000000000000000d5582d46f20f08cd6133acecde1456df635ccdcc
Deployed Bytecode
0x6080604052600436106102085760003560e01c8063817b1cd211610118578063adc9772e116100a0578063d93938141161006f578063d939381414610868578063e3f56eaa14610888578063e9b87387146108be578063ef4604a9146108eb578063fd6d2dcf1461090b57610420565b8063adc9772e14610784578063b6b55f25146107a4578063ce4cb876146107c4578063d547741f1461084857610420565b806389f18983116100e757806389f18983146106ef57806391d148541461070f5780639300c9261461072f5780639e7455eb1461074f578063a217fddf1461076f57610420565b8063817b1cd21461067d57806384f3ca41146106925780638670fdd9146106ba57806389bf146a146106cf57610420565b80632f2ff15d1161019b578063402fbbd81161016a578063402fbbd8146105f357806344715aaa146106085780635f96529f1461062857806363de06f814610648578063787ef2421461066857610420565b80632f2ff15d146105735780633293025c1461059357806336568abe146105b357806338f8f528146105d357610420565b80631c31f710116101d75780631c31f710146104e3578063240de27714610503578063248a9ca31461052357806326b321d11461055357610420565b806301ffc9a71461042557806304f32b5d1461045a5780630cb395db1461047c5780630e53e633146104c357610420565b3661042057336000818152600b60209081526040808320600c8352818420548452909152902060038101546001600160a01b0316156102aa5760405162461bcd60e51b815260206004820152603360248201527f5468652063757272656e742070726f63657373207761697420666f7220616e20604482015272115490cc8c081d1bdad95b8819195c1bdcda5d606a1b60648201526084015b60405180910390fd5b6001815460ff1660048111156102d057634e487b7160e01b600052602160045260246000fd5b146102ed5760405162461bcd60e51b81526004016102a190614712565b348160010154146103665760405162461bcd60e51b815260206004820152603760248201527f4465706f73697420616d6f756e7420646f65736e2774206d617463682077697460448201527f682074686520726571756573746564206465706f73697400000000000000000060648201526084016102a1565b8060010154816006015410156103c557600481015460068201546001600160a01b03909116906108fc9061039b90349061092b565b6040518115909202916000818181858888f193505050501580156103c3573d6000803e3d6000fd5b505b805460ff19166002178155600881015460078201546040513481526001600160a01b03918216918516907f1f0f1dee49a1720a0d98e3a0575a04dd9f143ff5e29555c3085471c1c70eed5b9060200160405180910390a45050005b600080fd5b34801561043157600080fd5b506104456104403660046143c6565b610940565b60405190151581526020015b60405180910390f35b34801561046657600080fd5b5061047a610475366004614264565b610979565b005b34801561048857600080fd5b506104b56104973660046140d5565b6001600160a01b03166000908152600d602052604090206003015490565b604051908152602001610451565b3480156104cf57600080fd5b5061047a6104de3660046141f8565b6109f9565b3480156104ef57600080fd5b5061047a6104fe3660046140d5565b610be4565b34801561050f57600080fd5b5061047a61051e3660046143ee565b610c12565b34801561052f57600080fd5b506104b561053e36600461438a565b60009081526020819052604090206001015490565b34801561055f57600080fd5b5061047a61056e36600461438a565b610c29565b34801561057f57600080fd5b5061047a61058e3660046143a2565b610c3a565b34801561059f57600080fd5b5061047a6105ae36600461438a565b610c64565b3480156105bf57600080fd5b5061047a6105ce3660046143a2565b610c75565b3480156105df57600080fd5b5061047a6105ee366004614264565b610cf3565b3480156105ff57600080fd5b506007546104b5565b34801561061457600080fd5b5061047a61062336600461419a565b610d07565b34801561063457600080fd5b5061047a610643366004614129565b610e00565b34801561065457600080fd5b5061047a61066336600461438a565b610e14565b34801561067457600080fd5b506001546104b5565b34801561068957600080fd5b506008546104b5565b34801561069e57600080fd5b506009546040516001600160a01b039091168152602001610451565b3480156106c657600080fd5b506006546104b5565b3480156106db57600080fd5b5061047a6106ea366004614223565b610e55565b3480156106fb57600080fd5b5061047a61070a36600461438a565b6113dc565b34801561071b57600080fd5b5061044561072a3660046143a2565b6113ed565b34801561073b57600080fd5b5061047a61074a36600461433b565b611416565b34801561075b57600080fd5b5061047a61076a3660046142be565b611462565b34801561077b57600080fd5b506104b5600081565b34801561079057600080fd5b5061047a61079f3660046141f8565b611a0d565b3480156107b057600080fd5b5061047a6107bf36600461438a565b611d9d565b3480156107d057600080fd5b5061082d6107df3660046140f1565b604080518082018252600080825260209182018190526001600160a01b0394851681526010825282812093909416845291825291829020825180840190935280548352600101549082015290565b60408051825181526020928301519281019290925201610451565b34801561085457600080fd5b5061047a6108633660046143a2565b611fa3565b34801561087457600080fd5b5061047a6108833660046141f8565b611fc8565b34801561089457600080fd5b506104b56108a33660046140d5565b6001600160a01b03166000908152600e602052604090205490565b3480156108ca57600080fd5b506108de6108d93660046141f8565b612309565b60405161045191906147ba565b3480156108f757600080fd5b5061047a610906366004614307565b612511565b34801561091757600080fd5b5061047a6109263660046143ee565b612544565b60006109378284614934565b90505b92915050565b60006001600160e01b03198216637965db0b60e01b148061097157506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b336000908152600d60205260409020546109a55760405162461bcd60e51b81526004016102a190614779565b82336001600160a01b0316856001600160a01b03167fb67fab32200b6a6d186136689c0b4c4072ae0bd5dd17b98fb8105d1b9747939985856040516109eb9291906145d2565b60405180910390a450505050565b336000908152600d6020526040902060010154151580610a215750336001600160a01b038316145b610a8b5760405162461bcd60e51b815260206004820152603560248201527f4f6e6c792073657276696365206f722070726f6475637420637573746f6d65726044820152740818d85b8818d85b1b081d1a1a5cc81b595d1a1bd9605a1b60648201526084016102a1565b6001600160a01b0382166000908152600b6020908152604080832084845290915290206002815460ff166004811115610ad457634e487b7160e01b600052602160045260246000fd5b14610b335760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f74207374617274207465726d696e6174696f6e2c20636865636b2060448201526874686520737461746560b81b60648201526084016102a1565b805460ff191660031781554360098201556007810154610b5e906001600160a01b031660008061255b565b8051610b7491600a840191602090910190613f4a565b50600b810180546001600160a81b0319908116909155600c820180549091169055604051829033906001600160a01b038616907f2ec6ff0a3927bfb55544f85fb0e2367f025ffb0b469ec8276385f8e569e0376e90610bd790600a87019061456a565b60405180910390a4505050565b6000610bef81612999565b50600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c1d81612999565b50600491909155600555565b6000610c3481612999565b50600755565b600082815260208190526040902060010154610c5581612999565b610c5f83836129a6565b505050565b6000610c6f81612999565b50600655565b6001600160a01b0381163314610ce55760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016102a1565b610cef8282612a2a565b5050565b610d01600085858585612a8f565b50505050565b6000610d1281612999565b6002845111610d635760405162461bcd60e51b815260206004820181905260248201527f56616c696461746f7273206d696e696d756d207175616e74697479206973203360448201526064016102a1565b6040805160c08101825285815260025460208083019190915260035482840152600160608301526080820186905260a082018590526001600160a01b0388166000908152600d8252929092208151805192939192610dc49284920190613f4a565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0909101516005909101555050505050565b610e0d8585858585612a8f565b5050505050565b336000908152600d6020526040902054610e405760405162461bcd60e51b81526004016102a190614779565b336000908152600d6020526040902060030155565b336000908152600e6020526040902054610e815760405162461bcd60e51b81526004016102a190614619565b6001600160a01b038084166000908152600b60209081526040808320868452825280832060078101549094168352600d8252918290208054835181840281018401909452808452610f119392830182828015610f0657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ee8575b505050505033612ef9565b610f2d5760405162461bcd60e51b81526004016102a1906146b5565b6003815460ff166004811115610f5357634e487b7160e01b600052602160045260246000fd5b14610fb25760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f74206163636570742076616c69646174696f6e2c20636865636b2060448201526874686520737461746560b81b60648201526084016102a1565b61102081600a0180548060200260200160405190810160405280929190818152602001828054801561100d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610fef575b5050505050338360090154600154612f6d565b61103c5760405162461bcd60e51b81526004016102a190614668565b600b8101546001600160a01b031661110657600b810180546001600160a81b0319163360ff60a01b191617600160a01b8415150217908190554360098301556007820154611098916001600160a01b039182169116600061255b565b80516110ae91600a840191602090910190613f4a565b50600781015460405184916001600160a01b0390811691908716907f2ec6ff0a3927bfb55544f85fb0e2367f025ffb0b469ec8276385f8e569e0376e906110f990600a87019061456a565b60405180910390a4610d01565b600c8101546001600160a01b031661122157600c810180546001600160a81b0319163360ff60a01b191617600160a01b84151581029190911791829055600b8301549181900460ff90811615159190920491909116151514156111ee57611182848483600b0160149054906101000a900460ff16156000613021565b8054600460ff199091161781556007810154600b82015460408051600160a01b90920460ff16151582525185926001600160a01b0390811692908816917f5c2cc6518d5891ba2f9c21f49d712982ba12450a2a8adeb21e4a41f85a995b709181900360200190a461121c565b4360098201556007810154600b820154600c830154611098926001600160a01b03908116928116911661255b565b610d01565b600b81015460ff600160a01b90910416151582151514156112e157600654600c8201546001600160a01b03166000908152600e602052604081205490916112759160649161126f9190613407565b90613413565b600c830154909150600090611293906001600160a01b03168361341f565b600c840180546001600160a81b0319163360ff60a01b191617600160a01b871515810291909117909155600b8501549192506112da918891889160ff919004161584613021565b5050611377565b600654600b8201546001600160a01b03166000908152600e602052604081205490916113149160649161126f9190613407565b600b830154909150600090611332906001600160a01b03168361341f565b600b840180546001600160a81b0319163360ff60a01b191617600160a01b87151581029190911791829055919250611374918891889160ff9104161584613021565b50505b8054600460ff199091161781556007810154600b820154604051600160a01b90910460ff161515815284916001600160a01b0390811691908716907f5c2cc6518d5891ba2f9c21f49d712982ba12450a2a8adeb21e4a41f85a995b70906020016109eb565b60006113e781612999565b50600155565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b336000908152600d60205260409020546114425760405162461bcd60e51b81526004016102a190614779565b336000908152600d602090815260409091208251610cef92840190613f4a565b336000908152600e602052604090205461148e5760405162461bcd60e51b81526004016102a190614619565b6001600160a01b038085166000908152600b60209081526040808320878452825280832060078101549094168352600d825291829020805483518184028101840190945280845261151c9392830182828015610f06576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610ee857505050505033612ef9565b6115385760405162461bcd60e51b81526004016102a1906146b5565b6000815460ff16600481111561155e57634e487b7160e01b600052602160045260246000fd5b146115b75760405162461bcd60e51b8152602060048201526024808201527f436f737420697320616c7265616479207365742c20636865636b2074686520736044820152637461746560e01b60648201526084016102a1565b61162381600a0180548060200260200160405190810160405280929190818152602001828054801561100d576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610fef575050505050338360090154600154612f6d565b61163f5760405162461bcd60e51b81526004016102a190614668565b600b8101546001600160a01b031661171057600b810180546001600160a01b031990811633908117909255600183018590556004830180546001600160a01b038681169190931617905543600984015560078301546116a292911690600061255b565b80516116b891600a840191602090910190613f4a565b50600781015460405185916001600160a01b0390811691908816907fde23c39256eb8276bf5f5a3b3654613cb6dc5d9a36e408f3ad61e531217b0d899061170390600a8701906145ad565b60405180910390a4610e0d565b600c8101546001600160a01b031661189257600c81018054336001600160a01b031991821617909155600282018490556005820180549091166001600160a01b03841617905560018101548314801561177d5750600581015460048201546001600160a01b039081169116145b1561185f5760078101546001600160a01b03166000908152600d602052604090206004810154158015906117b5575060008160050154115b156117e3576117d9816005015461126f83600401548761340790919063ffffffff16565b6006830155611804565b6117fe60055461126f6004548761340790919063ffffffff16565b60068301555b815460ff19166001178255600782015460405185815286916001600160a01b0390811691908916907f9829c39553001f6f75967caf0b4a8a903f5332af8a010a6b7e8532b7ed023f519060200160405180910390a45061188d565b4360098201556007810154600b820154600c8301546116a2926001600160a01b03908116928116911661255b565b610e0d565b8281600101541480156118b4575060048101546001600160a01b038381169116145b156118f257600c81018054336001600160a01b031991821617909155600282018490556005820180549091166001600160a01b038416179055611927565b600b81018054336001600160a01b031991821617909155600182018490556004820180549091166001600160a01b0384161790555b6001810183905560078101546001600160a01b03166000908152600d60205260409020600481015415801590611961575060008160050154115b1561198f57611985816005015461126f83600401548761340790919063ffffffff16565b60068301556119b0565b6119aa60055461126f6004548761340790919063ffffffff16565b60068301555b815460ff19166001178255600782015460405185815286916001600160a01b0390811691908916907f9829c39553001f6f75967caf0b4a8a903f5332af8a010a6b7e8532b7ed023f519060200160405180910390a4505050505050565b6001600160a01b038216611a635760405162461bcd60e51b815260206004820152601d60248201527f56616c696461746f7220616464726573732063616e6e6f74206265203000000060448201526064016102a1565b60008111611aa45760405162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b60448201526064016102a1565b6009546040516323b872dd60e01b8152336004820152306024820152604481018390526000916001600160a01b0316906323b872dd90606401602060405180830381600087803b158015611af757600080fd5b505af1158015611b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2f919061436e565b90508015611d4a57600854611b44908361358c565b6008553360009081526010602090815260408083206001600160a01b038716845290915281205415611b74575060015b3360009081526010602090815260408083206001600160a01b0388168452909152902054611ba2908461358c565b3360009081526010602090815260408083206001600160a01b0389168452909152902055600754611bd390436148e9565b3360009081526010602090815260408083206001600160a01b0389168452825280832060010193909355600e90522054611c0d908461358c565b6001600160a01b0385166000908152600e602052604090205580158015611ca557506001600160a01b0384166000908152600f60209081526040918290208054835181840281018401909452808452611ca39392830182828015610f06576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610ee857505050505033612ef9565b155b15611ce3576001600160a01b0384166000908152600f602090815260408220805460018101825590835291200180546001600160a01b031916331790555b3360008181526010602090815260408083206001600160a01b03891680855290835292819020600101548151888152928301529192917f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc910160405180910390a350610c5f565b60405162461bcd60e51b815260206004820152602260248201527f5761736e27742061626c6520746f207472616e7366657220796f757220746f6b60448201526132b760f11b60648201526084016102a1565b336000818152600b60209081526040808320600c8352818420548452909152902060038101546001600160a01b0316611e3e5760405162461bcd60e51b815260206004820152603b60248201527f5468652063757272656e742070726f6365737320646f65736e2774207761697460448201527f20666f7220616e20455243323020746f6b656e206465706f736974000000000060648201526084016102a1565b6001815460ff166004811115611e6457634e487b7160e01b600052602160045260246000fd5b14611e815760405162461bcd60e51b81526004016102a190614712565b82816001015414611ef15760405162461bcd60e51b815260206004820152603460248201527f4465706f73697420616d6f756e7420646f65736e2774206d61746368207769746044820152731a081d1a19481c995c5d595cdd19590818dbdcdd60621b60648201526084016102a1565b60038101546001600160a01b0316611f0b81843087613598565b816001015482600601541015611f4f5760048201546006830154611f4f916001600160a01b031690611f3e90879061092b565b6001600160a01b0384169190613603565b815460ff19166002178255600882015460078301546040518681526001600160a01b03918216918616907f1f0f1dee49a1720a0d98e3a0575a04dd9f143ff5e29555c3085471c1c70eed5b906020016109eb565b600082815260208190526040902060010154611fbe81612999565b610c5f8383612a2a565b6000811161200b5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f7420756e7374616b6520360841b60448201526064016102a1565b3360009081526010602090815260408083206001600160a01b03861684529091529020548111156120b05760405162461bcd60e51b815260206004820152604360248201527f596f75722062616c616e6365206973206c6f776572207468616e20746865206160448201527f6d6f756e74206f6620746f6b656e7320796f752077616e7420746f20756e7374606482015262616b6560e81b608482015260a4016102a1565b3360009081526010602090815260408083206001600160a01b03861684529091529020600101544310156121415760405162461bcd60e51b815260206004820152603260248201527f546865206c6f636b696e6720706572696f64206469646e277420706173732c20604482015271796f752063616e6e6f7420756e7374616b6560701b60648201526084016102a1565b60095460405163a9059cbb60e01b8152336004820152602481018390526000916001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561218e57600080fd5b505af11580156121a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c6919061436e565b905080156122aa5781600860008282546121e09190614934565b90915550503360009081526010602090815260408083206001600160a01b0387168452909152902054612214908390614934565b3360009081526010602090815260408083206001600160a01b0388168452825280832093909355600e9052205461224c908390614934565b6001600160a01b0384166000818152600e60205260409081902092909255905133907f8a3c16627a0e7a870a5d5cd0121ca5d80e2efd0ec7198a11644f1a516ac370939061229d9086815260200190565b60405180910390a3610c5f565b60405162461bcd60e51b815260206004820152602e60248201527f5761736e27742061626c6520746f2065786563757465207472616e736665722060448201526d6f6620796f757220746f6b656e7360901b60648201526084016102a1565b604080516101e080820183526000808352602080840182905283850182905260608085018390526080850183905260a0850183905260c0850183905260e0850183905261010085018390526101208501839052610140850152610160840182905261018084018290526101a084018290526101c084018290526001600160a01b0387168252600b815284822086835290528390208351918201909352825491929091829060ff1660048111156123cf57634e487b7160e01b600052602160045260246000fd5b60048111156123ee57634e487b7160e01b600052602160045260246000fd5b81526001820154602080830191909152600283015460408084019190915260038401546001600160a01b0390811660608501526004850154811660808501526005850154811660a0850152600685015460c085015260078501541660e084015260088401546101008401526009840154610120840152600a840180548251818502810185019093528083526101409094019391929091908301828280156124be57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116124a0575b5050509183525050600b8201546001600160a01b03808216602084015260ff600160a01b92839004811615156040850152600c909401549081166060840152049091161515608090910152905092915050565b600061251c81612999565b506001600160a01b039092166000908152600d60205260409020600181019190915560020155565b600061254f81612999565b50600291909155600355565b6001600160a01b038082166000908152600e60205260408082205492851682528120546008546060939161258e91614934565b6125989190614934565b6001600160a01b038087166000908152600d602052604081205492935091908616156125cc576125c9600182614934565b90505b6001600160a01b038516156125e9576125e6600182614934565b90505b60008167ffffffffffffffff81111561261257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561263b578160200160208202803683370190505b50905060005b815181101561298b5784612653613633565b61265d91906149a9565b935060005b6001600160a01b038a166000908152600d6020526040902054811015612978576001600160a01b038a81166000908152600d602052604090208054918b1691839081106126bf57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161480159061273257506001600160a01b038a81166000908152600d602052604090208054918a16918390811061271a57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614155b15612966576001600160a01b038a166000908152600d60205260409020805461278f9185918490811061277557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316612ef9565b612966576001600160a01b038a166000908152600d602052604081208054600e929190849081106127d057634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0316835282019290925260400190205485116128f7576001600160a01b038a166000908152600d6020526040902080548290811061283357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b031683838151811061287157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201810191909152908b166000908152600d909152604081208054600e929190849081106128c157634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b031683528201929092526040019020546128f09087614934565b9550612978565b6001600160a01b038a166000908152600d602052604081208054600e9291908490811061293457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b031683528201929092526040019020546129639086614934565b94505b806129708161498e565b915050612662565b50806129838161498e565b915050612641565b5093505050505b9392505050565b6129a3813361366f565b50565b6129b082826113ed565b610cef576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556129e63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612a3482826113ed565b15610cef576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b0384166000908152600d6020526040902060010154612b035760405162461bcd60e51b815260206004820152602360248201527f52657175657374656420736572766963652061646472657373206e6f7420666f6044820152621d5b9960ea1b60648201526084016102a1565b336000908152600b602090815260408083208684529091529020600701546001600160a01b031615612b8e5760405162461bcd60e51b815260206004820152602e60248201527f50726f636573732077697468207370656369666965642070726f64756374496460448201526d08185b1c9958591e48195e1a5cdd60921b60648201526084016102a1565b604080516101e0810190915280600081526020016000815260200160008152602001866001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001856001600160a01b03168152602001848152602001438152602001612c0d8660008061255b565b8152600060208083018290526040808401839052606084018390526080909301829052338252600b815282822087835290522081518154829060ff19166001836004811115612c6c57634e487b7160e01b600052602160045260246000fd5b021790555060208281015160018301556040830151600283015560608301516003830180546001600160a01b039283166001600160a01b031991821617909155608085015160048501805491841691831691909117905560a085015160058501805491841691831691909117905560c0850151600685015560e0850151600785018054919093169116179055610100830151600883015561012083015160098301556101408301518051612d2692600a8501920190613f4a565b50610160820151600b80830180546101808601511515600160a01b9081026001600160a81b03199283166001600160a01b0396871617179092556101a0860151600c90950180546101c0909701511515909202951693831693909317939093179091553360008181526020938452604080822088835290945283902092518693928816927fde23c39256eb8276bf5f5a3b3654613cb6dc5d9a36e408f3ad61e531217b0d8991612ddd91600a01908890889061457d565b60405180910390a4336000908152600b60209081526040808320600c835281842054845290915290205460019060ff166004811115612e2c57634e487b7160e01b600052602160045260246000fd5b1415612ee357336000908152600b60209081526040808320600c83528184205484529091528120805460ff1916815560018101829055600281018290556003810180546001600160a01b03199081169091556004820180548216905560058201805482169055600682018390556007820180549091169055600881018290556009810182905590612ec0600a830182613faf565b50600b810180546001600160a81b0319908116909155600c909101805490911690555b5050336000908152600c60205260409020555050565b6000805b8351811015612f6357826001600160a01b0316848281518110612f3057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415612f5157600191505061093a565b80612f5b8161498e565b915050612efd565b5060009392505050565b6000805b855181101561301357846001600160a01b0316868281518110612fa457634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561300157612fc58443614934565b612fcf8483614915565b11158015612ff9575082612fe38183614915565b612fed91906148e9565b612ff78543614934565b105b915050613019565b8061300b8161498e565b915050612f71565b50600090505b949350505050565b6001600160a01b038085166000908152600b60209081526040808320878452825280832060078101549094168352600d909152812060010154600683015461306f9160649161126f91613407565b600b830154600c840154600385015492935060009261309f926001600160a01b03908116928116918691166136d3565b905083156130c857600b830154600c8401546130c8916001600160a01b03908116911686613782565b846132fb5760078301546001600160a01b03166000908152600d602052604081206002015460068501546131029160649161126f91613407565b60038501549091506001600160a01b03166131b15760078401546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015613153573d6000803e3d6000fd5b50600a5460068501546001600160a01b03909116906108fc908390613179908690614934565b6131839190614934565b6040518115909202916000818181858888f193505050501580156131ab573d6000803e3d6000fd5b506132f5565b6003840154600785015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052911690819063a9059cbb90604401602060405180830381600087803b15801561320757600080fd5b505af115801561321b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323f919061436e565b50600a5460068601546001600160a01b038084169263a9059cbb92911690859061326a908890614934565b6132749190614934565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156132ba57600080fd5b505af11580156132ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f2919061436e565b50505b506133fe565b60038301546001600160a01b031661335257866001600160a01b03166108fc82856006015461332a9190614934565b6040518115909202916000818181858888f193505050501580156132f5573d6000803e3d6000fd5b600383015460068401546001600160a01b0390911690819063a9059cbb908a9061337d908690614934565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156133c357600080fd5b505af11580156133d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fb919061436e565b50505b50505050505050565b60006109378284614915565b60006109378284614901565b600080805b6001600160a01b0385166000908152600f6020526040902054811015613556576001600160a01b0385166000908152600f6020526040812080548390811061347c57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03898116808552600e845260408086205492909316808652601085528386209186529352908320549193506134db9160649161126f916134d49190839085613407565b8990613407565b6001600160a01b038084166000908152601060209081526040808320938c168352929052205490915061350f908290614934565b6001600160a01b038084166000908152601060209081526040808320938c168352929052205561353f81856148e9565b93505050808061354e9061498e565b915050613424565b506001600160a01b0384166000908152600e60205260408120805483929061357f908490614934565b9091555090949350505050565b600061093782846148e9565b6040516001600160a01b0380851660248301528316604482015260648101829052610d019085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261387d565b6040516001600160a01b038316602482015260448101829052610c5f90849063a9059cbb60e01b906064016135cc565b60004442604051602001613651929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905090565b61367982826113ed565b610cef57613691816001600160a01b0316601461394f565b61369c83602061394f565b6040516020016136ad9291906144f5565b60408051601f198184030181529082905262461bcd60e51b82526102a1916004016145e6565b6001600160a01b038084166000908152600e60205260408082205492871682528120549091829161373d9160649161126f91613736916137129161358c565b6001600160a01b038b166000908152600e602052604090205461126f906064613407565b8790613407565b9050600061374b8286614934565b9050600061375a888487613b31565b90506000613769888488613b31565b905061377581836148e9565b9998505050505050505050565b6001600160a01b038083166000908152600e602052604080822054928616825281205490916137eb9160649161126f916137e4916137c0919061358c565b6001600160a01b0389166000908152600e602052604090205461126f906064613407565b8590613407565b905060006137f98284614934565b905060006138078684613cff565b905060006138158684613cff565b6001600160a01b0388166000908152600e60205260408120805492935084929091906138429084906148e9565b90915550506001600160a01b0386166000908152600e60205260408120805483929061386f9084906148e9565b909155505050505050505050565b60006138d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613e369092919063ffffffff16565b805190915015610c5f57808060200190518101906138f0919061436e565b610c5f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a1565b6060600061395e836002614915565b6139699060026148e9565b67ffffffffffffffff81111561398f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156139b9576020820181803683370190505b509050600360fc1b816000815181106139e257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613a1f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613a43846002614915565b613a4e9060016148e9565b90505b6001811115613ae2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a9057634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613ab457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613adb81614977565b9050613a51565b5083156109375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016102a1565b600080806001600160a01b03841615613b475750825b60005b6001600160a01b0387166000908152600f6020526040902054811015613cf4576001600160a01b0387166000908152600f60205260408120805483908110613ba257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03908116808452601083526040808520928d168552918352818420600e909352908320548254919450919291613c029160649161126f91613bfb9190839085613407565b8c90613407565b90506001600160a01b038816613c4e576040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015613c48573d6000803e3d6000fd5b50613cd2565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905286169063a9059cbb90604401602060405180830381600087803b158015613c9857600080fd5b505af1158015613cac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd0919061436e565b505b613cdc81876148e9565b95505050508080613cec9061498e565b915050613b4a565b509095945050505050565b600080805b6001600160a01b0385166000908152600f6020526040902054811015613e2e576001600160a01b0385166000908152600f60205260408120805483908110613d5c57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03898116808552600e84526040808620549290931680865260108552838620918652935290832054919350613db49160649161126f916134d49190839085613407565b6001600160a01b038084166000908152601060209081526040808320938c1683529290522054909150613de7908261358c565b6001600160a01b038084166000908152601060209081526040808320938c1683529290522055613e1781856148e9565b935050508080613e269061498e565b915050613d04565b509392505050565b60606130198484600085856001600160a01b0385163b613e985760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a1565b600080866001600160a01b03168587604051613eb491906144d9565b60006040518083038185875af1925050503d8060008114613ef1576040519150601f19603f3d011682016040523d82523d6000602084013e613ef6565b606091505b5091509150613f06828286613f11565b979650505050505050565b60608315613f20575081612992565b825115613f305782518084602001fd5b8160405162461bcd60e51b81526004016102a191906145e6565b828054828255906000526020600020908101928215613f9f579160200282015b82811115613f9f57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613f6a565b50613fab929150613fc9565b5090565b50805460008255906000526020600020908101906129a391905b5b80821115613fab5760008155600101613fca565b8035610974816149ff565b600082601f830112613ff9578081fd5b8135602067ffffffffffffffff80831115614016576140166149e9565b8260051b604051601f19603f8301168101818110848211171561403b5761403b6149e9565b60405284815283810192508684018288018501891015614059578687fd5b8692505b858310156140825761406e81613fde565b84529284019260019290920191840161405d565b50979650505050505050565b60008083601f84011261409f578182fd5b50813567ffffffffffffffff8111156140b6578182fd5b6020830191508360208285010111156140ce57600080fd5b9250929050565b6000602082840312156140e6578081fd5b8135610937816149ff565b60008060408385031215614103578081fd5b823561410e816149ff565b9150602083013561411e816149ff565b809150509250929050565b600080600080600060808688031215614140578081fd5b853561414b816149ff565b9450602086013561415b816149ff565b935060408601359250606086013567ffffffffffffffff81111561417d578182fd5b6141898882890161408e565b969995985093965092949392505050565b600080600080608085870312156141af578384fd5b84356141ba816149ff565b9350602085013567ffffffffffffffff8111156141d5578384fd5b6141e187828801613fe9565b949794965050505060408301359260600135919050565b6000806040838503121561420a578182fd5b8235614215816149ff565b946020939093013593505050565b600080600060608486031215614237578283fd5b8335614242816149ff565b925060208401359150604084013561425981614a14565b809150509250925092565b60008060008060608587031215614279578384fd5b8435614284816149ff565b935060208501359250604085013567ffffffffffffffff8111156142a6578283fd5b6142b28782880161408e565b95989497509550505050565b600080600080608085870312156142d3578384fd5b84356142de816149ff565b9350602085013592506040850135915060608501356142fc816149ff565b939692955090935050565b60008060006060848603121561431b578283fd5b8335614326816149ff565b95602085013595506040909401359392505050565b60006020828403121561434c578081fd5b813567ffffffffffffffff811115614362578182fd5b61301984828501613fe9565b60006020828403121561437f578081fd5b815161093781614a14565b60006020828403121561439b578081fd5b5035919050565b600080604083850312156143b4578182fd5b82359150602083013561411e816149ff565b6000602082840312156143d7578081fd5b81356001600160e01b031981168114610937578182fd5b60008060408385031215614400578182fd5b50508035926020909101359150565b6000815180845260208085019450808401835b838110156144475781516001600160a01b031687529582019590820190600101614422565b509495945050505050565b6000815480845260208085019450838352808320835b838110156144475781546001600160a01b031687529582019560019182019101614468565b600581106144ab57634e487b7160e01b600052602160045260246000fd5b9052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600082516144eb81846020870161494b565b9190910192915050565b60007f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008252835161452d81601785016020880161494b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161455e81602884016020880161494b565b01602801949350505050565b6000602082526109376020830184614452565b6000604082526145906040830186614452565b82810360208401526145a38185876144af565b9695505050505050565b6000604082526145c06040830184614452565b82810360209384015290815201919050565b6000602082526130196020830184866144af565b600060208252825180602084015261460581604085016020870161494b565b601f01601f19169190910160400192915050565b6020808252602f908201527f4f6e6c792076616c696461746f722077697468207374616b65732063616e206360408201526e185b1b081d1a1a5cc81b595d1a1bd9608a1b606082015260800190565b6020808252602d908201527f43616e6e6f74206163636570742076616c69646174696f6e2c20796f7520617260408201526c65206f7574206f662074696d6560981b606082015260800190565b6020808252603f908201527f596f75722061646472657373206973206e6f742077686974656c69737465642060408201527f696e207468652070726f6475637420736572766963652073657474696e677300606082015260800190565b60208082526041908201527f596f7520646f6e277420686176652061206465706f736974206177616974696e60408201527f672070726f636573732c20706c656173652063726561746520697420666972736060820152601d60fa1b608082015260a00190565b60208082526021908201527f4f6e6c7920736572766963652063616e2063616c6c2074686973206d6574686f6040820152601960fa1b606082015260800190565b6000602082526147ce60208301845161448d565b602083015160408301526040830151606083015260608301516147fc60808401826001600160a01b03169052565b5060808301516001600160a01b03811660a08401525060a08301516001600160a01b03811660c08401525060c083015160e083015260e083015161010061484d818501836001600160a01b03169052565b84015161012084810191909152840151610140808501919091528401516101e06101608086018290529192509061488861020086018461440f565b908601519092506101806148a6868201836001600160a01b03169052565b86015190506101a06148bb8682018315159052565b86015190506101c06148d7868201836001600160a01b03169052565b90950151151593019290925250919050565b600082198211156148fc576148fc6149bd565b500190565b600082614910576149106149d3565b500490565b600081600019048311821515161561492f5761492f6149bd565b500290565b600082821015614946576149466149bd565b500390565b60005b8381101561496657818101518382015260200161494e565b83811115610d015750506000910152565b600081614986576149866149bd565b506000190190565b60006000198214156149a2576149a26149bd565b5060010190565b6000826149b8576149b86149d3565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146129a357600080fd5b80151581146129a357600080fdfea26469706673582212203ec26f75fe81ee04fa38f77f93a68abe326b6185e8d4f2251d84b9db6a534eef64736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000005100000000000000000000000000d5582d46f20f08cd6133acecde1456df635ccdcc
-----Decoded View---------------
Arg [0] : penaltyPerc (uint256): 10
Arg [1] : lockingPeriod (uint256): 20736
Arg [2] : token (address): 0xd5582D46F20f08CD6133aceCdE1456DF635cCdcC
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [1] : 0000000000000000000000000000000000000000000000000000000000005100
Arg [2] : 000000000000000000000000d5582d46f20f08cd6133acecde1456df635ccdcc
Deployed Bytecode Sourcemap
42248:28147:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6384:10;47022:14;47088:18;;;:10;:18;;;;;;;;47107:19;:27;;;;;;47088:47;;;;;;;47154:13;;;;-1:-1:-1;;;;;47154:13:0;:27;47146:91;;;;-1:-1:-1;;;47146:91:0;;20320:2:1;47146:91:0;;;20302:21:1;20359:2;20339:18;;;20332:30;20398:34;20378:18;;;20371:62;-1:-1:-1;;;20449:18:1;;;20442:49;20508:19;;47146:91:0;;;;;;;;;47273:23;47256:13;;;;:40;;;;;;-1:-1:-1;;;47256:40:0;;;;;;;;;;47248:118;;;;-1:-1:-1;;;47248:118:0;;;;;;;:::i;:::-;47401:9;47385:7;:12;;;:25;47377:93;;;;-1:-1:-1;;;47377:93:0;;17945:2:1;47377:93:0;;;17927:21:1;17984:2;17964:18;;;17957:30;18023:34;18003:18;;;17996:62;18094:25;18074:18;;;18067:53;18137:19;;47377:93:0;17917:245:1;47377:93:0;47508:7;:12;;;47494:7;:11;;;:26;47491:197;;;47624:15;;;;47663:11;;;;-1:-1:-1;;;;;47624:15:0;;;;:52;;47649:26;;:9;;:13;:26::i;:::-;47624:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47491:197;47749:42;;-1:-1:-1;;47749:42:0;47765:26;47749:42;;;47840:17;;;;47823:15;;;;47807:62;;47859:9;13932:25:1;;-1:-1:-1;;;;;47823:15:0;;;;47807:62;;;;;13920:2:1;13905:18;47807:62:0;;;;;;;46984:893;;42248:28147;;;;;11061:204;;;;;;;;;;-1:-1:-1;11061:204:0;;;;;:::i;:::-;;:::i;:::-;;;13759:14:1;;13752:22;13734:41;;13722:2;13707:18;11061:204:0;;;;;;;;62040:172;;;;;;;;;;-1:-1:-1;62040:172:0;;;;;:::i;:::-;;:::i;:::-;;48790:131;;;;;;;;;;-1:-1:-1;48790:131:0;;;;;:::i;:::-;-1:-1:-1;;;;;48878:18:0;48854:4;48878:18;;;:9;:18;;;;;:35;;;;48790:131;;;;13932:25:1;;;13920:2;13905:18;48790:131:0;13887:76:1;62220:849:0;;;;;;;;;;-1:-1:-1;62220:849:0;;;;;:::i;:::-;;:::i;46130:128::-;;;;;;;;;;-1:-1:-1;46130:128:0;;;;;:::i;:::-;;:::i;46432:180::-;;;;;;;;;;-1:-1:-1;46432:180:0;;;;;:::i;:::-;;:::i;12897:131::-;;;;;;;;;;-1:-1:-1;12897:131:0;;;;;:::i;:::-;12971:7;12998:12;;;;;;;;;;:22;;;;12897:131;49404:142;;;;;;;;;;-1:-1:-1;49404:142:0;;;;;:::i;:::-;;:::i;13338:147::-;;;;;;;;;;-1:-1:-1;13338:147:0;;;;;:::i;:::-;;:::i;49158:131::-;;;;;;;;;;-1:-1:-1;49158:131:0;;;;;:::i;:::-;;:::i;14482:218::-;;;;;;;;;;-1:-1:-1;14482:218:0;;;;;:::i;:::-;;:::i;53163:161::-;;;;;;;;;;-1:-1:-1;53163:161:0;;;;;:::i;:::-;;:::i;49297:99::-;;;;;;;;;;-1:-1:-1;49374:14:0;;49297:99;;47885:503;;;;;;;;;;-1:-1:-1;47885:503:0;;;;;:::i;:::-;;:::i;53332:171::-;;;;;;;;;;-1:-1:-1;53332:171:0;;;;;:::i;:::-;;:::i;48929:121::-;;;;;;;;;;-1:-1:-1;48929:121:0;;;;;:::i;:::-;;:::i;46754:103::-;;;;;;;;;;-1:-1:-1;46834:15:0;;46754:103;;69025:93;;;;;;;;;;-1:-1:-1;69098:12:0;;69025:93;;46865:111;;;;;;;;;;-1:-1:-1;46953:14:0;;46865:111;;-1:-1:-1;;;;;46953:14:0;;;11643:51:1;;11631:2;11616:18;46865:111:0;11598:102:1;49058:92:0;;;;;;;;;;-1:-1:-1;49130:12:0;;49058:92;;63077:3304;;;;;;;;;;-1:-1:-1;63077:3304:0;;;;;:::i;:::-;;:::i;46620:126::-;;;;;;;;;;-1:-1:-1;46620:126:0;;;;;:::i;:::-;;:::i;11357:147::-;;;;;;;;;;-1:-1:-1;11357:147:0;;;;;:::i;:::-;;:::i;48655:127::-;;;;;;;;;;-1:-1:-1;48655:127:0;;;;;:::i;:::-;;:::i;58718:3314::-;;;;;;;;;;-1:-1:-1;58718:3314:0;;;;;:::i;:::-;;:::i;10462:49::-;;;;;;;;;;-1:-1:-1;10462:49:0;10507:4;10462:49;;66549:1186;;;;;;;;;;-1:-1:-1;66549:1186:0;;;;;:::i;:::-;;:::i;69126:1264::-;;;;;;;;;;-1:-1:-1;69126:1264:0;;;;;:::i;:::-;;:::i;68739:141::-;;;;;;;;;;-1:-1:-1;68739:141:0;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;68846:15:0;;;;;:7;:15;;;;;:26;;;;;;;;;;;;;68839:33;;;;;;;;;;;;;;;;;;;;68739:141;;;;;28142:13:1;;28124:32;;28212:4;28200:17;;;28194:24;28172:20;;;28165:54;;;;28097:18;68739:141:0;28079:146:1;13778:149:0;;;;;;;;;;-1:-1:-1;13778:149:0;;;;;:::i;:::-;;:::i;67743:988::-;;;;;;;;;;-1:-1:-1;67743:988:0;;;;;:::i;:::-;;:::i;68888:129::-;;;;;;;;;;-1:-1:-1;68888:129:0;;;;;:::i;:::-;-1:-1:-1;;;;;68979:30:0;68952:7;68979:30;;;:19;:30;;;;;;;68888:129;66389:152;;;;;;;;;;-1:-1:-1;66389:152:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;48396:251::-;;;;;;;;;;-1:-1:-1;48396:251:0;;;;;:::i;:::-;;:::i;46266:158::-;;;;;;;;;;-1:-1:-1;46266:158:0;;;;;:::i;:::-;;:::i;20008:98::-;20066:7;20093:5;20097:1;20093;:5;:::i;:::-;20086:12;;20008:98;;;;;:::o;11061:204::-;11146:4;-1:-1:-1;;;;;;11170:47:0;;-1:-1:-1;;;11170:47:0;;:87;;-1:-1:-1;;;;;;;;;;8423:40:0;;;11221:36;11163:94;;11061:204;;;;:::o;62040:172::-;45303:10;45335:1;45293:21;;;:9;:21;;;;;:39;45285:89;;;;-1:-1:-1;;;45285:89:0;;;;;;;:::i;:::-;62188:9:::1;62176:10;-1:-1:-1::0;;;;;62159:45:0::1;62166:8;-1:-1:-1::0;;;;;62159:45:0::1;;62199:4;;62159:45;;;;;;;:::i;:::-;;;;;;;;62040:172:::0;;;;:::o;62220:849::-;62322:10;62351:1;62312:21;;;:9;:21;;;;;:36;;;:40;;;62311:70;;-1:-1:-1;62358:10:0;-1:-1:-1;;;;;62358:22:0;;;62311:70;62303:136;;;;-1:-1:-1;;;62303:136:0;;19137:2:1;62303:136:0;;;19119:21:1;19176:2;19156:18;;;19149:30;19215:34;19195:18;;;19188:62;-1:-1:-1;;;19266:18:1;;;19259:51;19327:19;;62303:136:0;19109:243:1;62303:136:0;-1:-1:-1;;;;;62476:20:0;;62450:23;62476:20;;;:10;:20;;;;;;;;:31;;;;;;;;62543:26;62526:13;;;;:43;;;;;;-1:-1:-1;;;62526:43:0;;;;;;;;;;62518:97;;;;-1:-1:-1;;;62518:97:0;;24052:2:1;62518:97:0;;;24034:21:1;24091:2;24071:18;;;24064:30;24130:34;24110:18;;;24103:62;-1:-1:-1;;;24181:18:1;;;24174:39;24230:19;;62518:97:0;24024:231:1;62518:97:0;62628:41;;-1:-1:-1;;62628:41:0;62644:25;62628:41;;;62701:12;62680:18;;;:33;62769:15;;;;62749:60;;-1:-1:-1;;;;;62769:15:0;-1:-1:-1;;62749:19:0;:60::i;:::-;62724:85;;;;:22;;;;:85;;;;;;:::i;:::-;-1:-1:-1;62820:22:0;;;:35;;-1:-1:-1;;;;;;62866:27:0;;;;;;62904:23;;;:36;;62951:28;;;;;62995:66;;63027:9;;63015:10;;-1:-1:-1;;;;;62995:66:0;;;;;;;63038:22;;;;62995:66;:::i;:::-;;;;;;;;62220:849;;;:::o;46130:128::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;46228:12:0::1;:22:::0;;-1:-1:-1;;;;;;46228:22:0::1;-1:-1:-1::0;;;;;46228:22:0;;;::::1;::::0;;;::::1;::::0;;46130:128::o;46432:180::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;46539:13:0::1;:25:::0;;;;46575:15:::1;:29:::0;46432:180::o;49404:142::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;49505:14:0::1;:33:::0;49404:142::o;13338:147::-;12971:7;12998:12;;;;;;;;;;:22;;;10953:16;10964:4;10953:10;:16::i;:::-;13452:25:::1;13463:4;13469:7;13452:10;:25::i;:::-;13338:147:::0;;;:::o;49158:131::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;49252:12:0::1;:29:::0;49158:131::o;14482:218::-;-1:-1:-1;;;;;14578:23:0;;6384:10;14578:23;14570:83;;;;-1:-1:-1;;;14570:83:0;;25349:2:1;14570:83:0;;;25331:21:1;25388:2;25368:18;;;25361:30;25427:34;25407:18;;;25400:62;-1:-1:-1;;;25478:18:1;;;25471:45;25533:19;;14570:83:0;25321:237:1;14570:83:0;14666:26;14678:4;14684:7;14666:11;:26::i;:::-;14482:218;;:::o;53163:161::-;53264:52;53287:1;53291:7;53300:9;53311:4;;53264:14;:52::i;:::-;53163:161;;;;:::o;47885:503::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;48054:1:::1;48039:5;:12;:16;48031:61;;;::::0;-1:-1:-1;;;48031:61:0;;18369:2:1;48031:61:0::1;::::0;::::1;18351:21:1::0;;;18388:18;;;18381:30;18447:34;18427:18;;;18420:62;18499:18;;48031:61:0::1;18341:182:1::0;48031:61:0::1;48124:256;::::0;;::::1;::::0;::::1;::::0;;;;;48195:15:::1;::::0;48124:256:::1;::::0;;::::1;::::0;;;;48241:11:::1;::::0;48124:256;;;;48285:1:::1;48124:256:::0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48103:18:0;::::1;-1:-1:-1::0;48103:18:0;;;:9:::1;:18:::0;;;;;;:277;;;;48124:256;;48103:18;;:277:::1;::::0;:18;;:277:::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;48103:277:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;47885:503:0:o;53332:171::-;53448:47;53463:5;53470:7;53479:9;53490:4;;53448:14;:47::i;:::-;53332:171;;;;;:::o;48929:121::-;45303:10;45335:1;45293:21;;;:9;:21;;;;;:39;45285:89;;;;-1:-1:-1;;;45285:89:0;;;;;;;:::i;:::-;49007:10:::1;48997:21;::::0;;;:9:::1;:21;::::0;;;;:38:::1;;:45:::0;48929:121::o;63077:3304::-;63204:10;63218:1;63184:31;;;:19;:31;;;;;;63176:95;;;;-1:-1:-1;;;63176:95:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;63308:20:0;;;63282:23;63308:20;;;:10;:20;;;;;;;;:31;;;;;;;;63385:15;;;;;;;63375:26;;:9;:26;;;;;;63358:67;;;;;;;;;;;;;;;;;;;;;;63375:26;63358:67;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63358:67:0;;;;;;;;;;;;;;;;;;;;;63414:10;63358:16;:67::i;:::-;63350:143;;;;-1:-1:-1;;;63350:143:0;;;;;;;:::i;:::-;63529:25;63512:13;;;;:42;;;;;;-1:-1:-1;;;63512:42:0;;;;;;;;;;63504:96;;;;-1:-1:-1;;;63504:96:0;;22005:2:1;63504:96:0;;;21987:21:1;22044:2;22024:18;;;22017:30;22083:34;22063:18;;;22056:62;-1:-1:-1;;;22134:18:1;;;22127:39;22183:19;;63504:96:0;21977:231:1;63504:96:0;63633:167;63663:7;:22;;63633:167;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63633:167:0;;;;;;;;;;;;;;;;;;;;;63704:10;63733:7;:18;;;63770:15;;63633:11;:167::i;:::-;63611:262;;;;-1:-1:-1;;;63611:262:0;;;;;;;:::i;:::-;63947:22;;;;-1:-1:-1;;;;;63947:22:0;63944:2430;;64000:22;;;:35;;-1:-1:-1;;;;;;64050:28:0;64025:10;-1:-1:-1;;;;64050:28:0;;-1:-1:-1;;;64050:28:0;;;;;;;;;64114:12;64093:18;;;:33;64186:15;;;;64166:72;;-1:-1:-1;;;;;64186:15:0;;;;64203:22;-1:-1:-1;64166:19:0;:72::i;:::-;64141:97;;;;:22;;;;:97;;;;;;:::i;:::-;-1:-1:-1;64278:15:0;;;;64258:71;;64295:9;;-1:-1:-1;;;;;64278:15:0;;;;64258:71;;;;;;;;64306:22;;;;64258:71;:::i;:::-;;;;;;;;63944:2430;;;64421:23;;;;-1:-1:-1;;;;;64421:23:0;64418:1956;;64475:23;;;:36;;-1:-1:-1;;;;;;64526:29:0;64501:10;-1:-1:-1;;;;64526:29:0;;-1:-1:-1;;;64526:29:0;;;;;;;;;;;;;64637:19;;;;64660:20;;;;64526:29;64660:20;;;64637:43;;:19;;;;;;;;:43;;;64634:651;;;64701:58;64714:8;64724:9;64736:7;:19;;;;;;;;;;;;64735:20;64757:1;64701:12;:58::i;:::-;64778:31;;64794:15;-1:-1:-1;;64778:31:0;;;;;;64852:15;;;;64880:19;;;;64833:67;;;-1:-1:-1;;;64880:19:0;;;;;13759:14:1;13752:22;13734:41;;64833:67:0;64869:9;;-1:-1:-1;;;;;64852:15:0;;;;64833:67;;;;;;;;;13722:2:1;64833:67:0;;;64634:651;;;65033:12;65012:18;;;:33;65109:15;;;;65126:22;;;;65150:23;;;;65089:85;;-1:-1:-1;;;;;65109:15:0;;;;65126:22;;;65150:23;65089:19;:85::i;64634:651::-;64418:1956;;;65381:19;;;;;-1:-1:-1;;;65381:19:0;;;;:29;;;;;;65378:852;;;65498:12;;65469:23;;;;-1:-1:-1;;;;;65469:23:0;65431:15;65449:44;;;:19;:44;;;;;;65431:15;;65449:71;;65516:3;;65449:62;;:44;:48;:62::i;:::-;:66;;:71::i;:::-;65578:23;;;;65431:89;;-1:-1:-1;65539:22:0;;65564:47;;-1:-1:-1;;;;;65578:23:0;65431:89;65564:13;:47::i;:::-;65630:23;;;:36;;-1:-1:-1;;;;;;65685:29:0;65656:10;-1:-1:-1;;;;65685:29:0;;-1:-1:-1;;;65685:29:0;;;;;;;;;;;;65768:19;;;;65539:72;;-1:-1:-1;65733:71:0;;65746:8;;65756:9;;65685:29;65768:19;;;;65767:20;65539:72;65733:12;:71::i;:::-;65378:852;;;;;65911:12;;65883:22;;;;-1:-1:-1;;;;;65883:22:0;65845:15;65863:43;;;:19;:43;;;;;;65845:15;;65863:70;;65929:3;;65863:61;;:43;:47;:61::i;:70::-;65991:22;;;;65845:88;;-1:-1:-1;65952:22:0;;65977:46;;-1:-1:-1;;;;;65991:22:0;65845:88;65977:13;:46::i;:::-;66042:22;;;:35;;-1:-1:-1;;;;;;66096:28:0;66067:10;-1:-1:-1;;;;66096:28:0;;-1:-1:-1;;;66096:28:0;;;;;;;;;;;;;65952:71;;-1:-1:-1;66143:71:0;;66156:8;;66166:9;;66096:28;66178:19;;;66177:20;65952:71;66143:12;:71::i;:::-;65378:852;;;66244:31;;66260:15;-1:-1:-1;;66244:31:0;;;;;;66314:15;;;;66342:19;;;;66295:67;;-1:-1:-1;;;66342:19:0;;;;;13759:14:1;13752:22;13734:41;;66331:9:0;;-1:-1:-1;;;;;66314:15:0;;;;66295:67;;;;;;13722:2:1;13707:18;66295:67:0;13689:92:1;46620:126:0;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;46714:15:0::1;:24:::0;46620:126::o;11357:147::-;11443:4;11467:12;;;;;;;;;;;-1:-1:-1;;;;;11467:29:0;;;;;;;;;;;;;;;11357:147::o;48655:127::-;45303:10;45335:1;45293:21;;;:9;:21;;;;;:39;45285:89;;;;-1:-1:-1;;;45285:89:0;;;;;;;:::i;:::-;48744:10:::1;48734:21;::::0;;;:9:::1;:21;::::0;;;;;;;:40;;::::1;::::0;;::::1;::::0;::::1;:::i;58718:3314::-:0;58870:10;58884:1;58850:31;;;:19;:31;;;;;;58842:95;;;;-1:-1:-1;;;58842:95:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;58974:20:0;;;58948:23;58974:20;;;:10;:20;;;;;;;;:31;;;;;;;;59051:15;;;;;;;59041:26;;:9;:26;;;;;;59024:67;;;;;;;;;;;;;;;;;;;;;;59041:26;59024:67;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59024:67:0;;;;;;;;;;;;;;;;;;;;59080:10;59024:16;:67::i;:::-;59016:143;;;;-1:-1:-1;;;59016:143:0;;;;;;;:::i;:::-;59195:19;59178:13;;;;:36;;;;;;-1:-1:-1;;;59178:36:0;;;;;;;;;;59170:85;;;;-1:-1:-1;;;59170:85:0;;17540:2:1;59170:85:0;;;17522:21:1;17579:2;17559:18;;;17552:30;17618:34;17598:18;;;17591:62;-1:-1:-1;;;17669:18:1;;;17662:34;17713:19;;59170:85:0;17512:226:1;59170:85:0;59288:167;59318:7;:22;;59288:167;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59288:167:0;;;;;;;;;;;;;;;;;;;;59359:10;59388:7;:18;;;59425:15;;59288:11;:167::i;:::-;59266:262;;;;-1:-1:-1;;;59266:262:0;;;;;;;:::i;:::-;59544:22;;;;-1:-1:-1;;;;;59544:22:0;59541:2484;;59597:22;;;:35;;-1:-1:-1;;;;;;59597:35:0;;;59622:10;59597:35;;;;;;;59647:12;;:19;;;59681:15;;;:29;;-1:-1:-1;;;;;59681:29:0;;;;;;;;;;59746:12;59725:18;;;:33;-1:-1:-1;59818:15:0;;;59798:72;;59818:15;;;59597:22;59798:19;:72::i;:::-;59773:97;;;;:22;;;;:97;;;;;;:::i;:::-;-1:-1:-1;59912:15:0;;;;59890:77;;59929:9;;-1:-1:-1;;;;;59912:15:0;;;;59890:77;;;;;;;;59940:22;;;;59890:77;:::i;:::-;;;;;;;;59541:2484;;;59988:23;;;;-1:-1:-1;;;;;59988:23:0;59985:2040;;60042:23;;;:36;;60068:10;-1:-1:-1;;;;;;60042:36:0;;;;;;;60093:16;;;:23;;;60131:19;;;:33;;;;;-1:-1:-1;;;;;60131:33:0;;;;;-1:-1:-1;60182:12:0;;;:32;;:74;;;;-1:-1:-1;60237:19:0;;;;60218:15;;;;-1:-1:-1;;;;;60218:15:0;;;60237:19;;60218:38;60182:74;60179:907;;;60313:15;;;;-1:-1:-1;;;;;60313:15:0;60277:23;60303:26;;;:9;:26;;;;;60351:20;;;;:24;;;;:54;;;60404:1;60379:7;:22;;;:26;60351:54;60348:281;;;60444:58;60479:7;:22;;;60444:30;60453:7;:20;;;60444:4;:8;;:30;;;;:::i;:58::-;60430:11;;;:72;60348:281;;;60565:44;60593:15;;60565:23;60574:13;;60565:4;:8;;:23;;;;:::i;:44::-;60551:11;;;:58;60348:281;60647:39;;-1:-1:-1;;60647:39:0;60663:23;60647:39;;;60733:15;;;;60710:56;;13932:25:1;;;60750:9:0;;-1:-1:-1;;;;;60733:15:0;;;;60710:56;;;;;;13920:2:1;13905:18;60710:56:0;;;;;;;60179:907;;;;60828:12;60807:18;;;:33;60904:15;;;;60921:22;;;;60945:23;;;;60884:85;;-1:-1:-1;;;;;60904:15:0;;;;60921:22;;;60945:23;60884:19;:85::i;60179:907::-;59985:2040;;;61137:4;61121:7;:12;;;:20;:54;;;;-1:-1:-1;61145:15:0;;;;-1:-1:-1;;;;;61145:30:0;;;:15;;:30;61121:54;61118:386;;;61196:23;;;:36;;61222:10;-1:-1:-1;;;;;;61196:36:0;;;;;;;61251:16;;;:23;;;61293:19;;;:33;;;;;-1:-1:-1;;;;;61293:33:0;;;;;61118:386;;;61367:22;;;:35;;61392:10;-1:-1:-1;;;;;;61367:35:0;;;;;;;-1:-1:-1;61421:12:0;;:19;;;61459:15;;;:29;;;;;-1:-1:-1;;;;;61459:29:0;;;;;61118:386;61518:12;;;:19;;;61588:15;;;;-1:-1:-1;;;;;61588:15:0;61552:23;61578:26;;;:9;:26;;;;;61622:20;;;;:24;;;;:54;;;61675:1;61650:7;:22;;;:26;61622:54;61619:265;;;61711:58;61746:7;:22;;;61711:30;61720:7;:20;;;61711:4;:8;;:30;;;;:::i;:58::-;61697:11;;;:72;61619:265;;;61824:44;61852:15;;61824:23;61833:13;;61824:4;:8;;:23;;;;:::i;:44::-;61810:11;;;:58;61619:265;61898:39;;-1:-1:-1;;61898:39:0;61914:23;61898:39;;;61980:15;;;;61957:56;;13932:25:1;;;61997:9:0;;-1:-1:-1;;;;;61980:15:0;;;;61957:56;;;;;;13920:2:1;13905:18;61957:56:0;;;;;;;59985:2040;58718:3314;;;;;:::o;66549:1186::-;-1:-1:-1;;;;;66627:23:0;;66619:65;;;;-1:-1:-1;;;66619:65:0;;15575:2:1;66619:65:0;;;15557:21:1;15614:2;15594:18;;;15587:30;15653:31;15633:18;;;15626:59;15702:18;;66619:65:0;15547:179:1;66619:65:0;66712:1;66703:6;:10;66695:37;;;;-1:-1:-1;;;66695:37:0;;16361:2:1;66695:37:0;;;16343:21:1;16400:2;16380:18;;;16373:30;-1:-1:-1;;;16419:18:1;;;16412:44;16473:18;;66695:37:0;16333:164:1;66695:37:0;66760:14;;:62;;-1:-1:-1;;;66760:62:0;;66788:10;66760:62;;;11945:34:1;66808:4:0;11995:18:1;;;11988:43;12047:18;;;12040:34;;;66745:12:0;;-1:-1:-1;;;;;66760:14:0;;:27;;11880:18:1;;66760:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66745:77;;66836:7;66833:895;;;66875:12;;:24;;66892:6;66875:16;:24::i;:::-;66860:12;:39;66967:10;66914:18;66959:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;66959:30:0;;;;;;;;;:37;:41;66955:102;;-1:-1:-1;67037:4:0;66955:102;67119:10;67111:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;67111:30:0;;;;;;;;;:37;:49;;67153:6;67111:41;:49::i;:::-;67079:10;67071:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;67071:30:0;;;;;;;;;:89;67238:14;;67223:29;;:12;:29;:::i;:::-;67183:10;67175:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;67175:30:0;;;;;;;;;:45;;:77;;;;67300:19;:30;;;;:42;;67335:6;67300:34;:42::i;:::-;-1:-1:-1;;;;;67267:30:0;;;;;;:19;:30;;;;;:75;67361:22;;;;:93;;-1:-1:-1;;;;;;67404:28:0;;;;;;:17;:28;;;;;;;;;67387:58;;;;;;;;;;;;;;;;;;;;;;67404:28;67387:58;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67387:58:0;;;;;;;;;;;;;;;;;;;;67434:10;67387:16;:58::i;:::-;:67;67361:93;67357:179;;;-1:-1:-1;;;;;67475:28:0;;;;;;:17;:28;;;;;;;:45;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67475:45:0;67509:10;67475:45;;;67357:179;67562:10;67593:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;67555:84:0;;67593:30;;;;;;;;;;:45;;;67555:84;;28586:25:1;;;28627:18;;;28620:34;67555:84:0;;67562:10;67555:84;;28559:18:1;67555:84:0;;;;;;;66833:895;;;;67672:44;;-1:-1:-1;;;67672:44:0;;23291:2:1;67672:44:0;;;23273:21:1;23330:2;23310:18;;;23303:30;23369:34;23349:18;;;23342:62;-1:-1:-1;;;23420:18:1;;;23413:32;23462:19;;67672:44:0;23263:224:1;69126:1264:0;6384:10;69179:14;69245:18;;;:10;:18;;;;;;;;69264:19;:27;;;;;;69245:47;;;;;;;69311:13;;;;-1:-1:-1;;;;;69311:13:0;69303:99;;;;-1:-1:-1;;;69303:99:0;;15933:2:1;69303:99:0;;;15915:21:1;15972:2;15952:18;;;15945:30;16011:34;15991:18;;;15984:62;16082:29;16062:18;;;16055:57;16129:19;;69303:99:0;15905:249:1;69303:99:0;69438:23;69421:13;;;;:40;;;;;;-1:-1:-1;;;69421:40:0;;;;;;;;;;69413:118;;;;-1:-1:-1;;;69413:118:0;;;;;;;:::i;:::-;69566:6;69550:7;:12;;;:22;69542:87;;;;-1:-1:-1;;;69542:87:0;;16704:2:1;69542:87:0;;;16686:21:1;16743:2;16723:18;;;16716:30;16782:34;16762:18;;;16755:62;-1:-1:-1;;;16833:18:1;;;16826:50;16893:19;;69542:87:0;16676:242:1;69542:87:0;69711:13;;;;-1:-1:-1;;;;;69711:13:0;69803:61;69711:13;69834:6;69850:4;69857:6;69803:30;:61::i;:::-;69894:7;:12;;;69880:7;:11;;;:26;69877:222;;;70045:15;;;;70074:11;;;;70010:77;;-1:-1:-1;;;;;70045:15:0;;70063:23;;:6;;:10;:23::i;:::-;-1:-1:-1;;;;;70010:26:0;;;:77;:26;:77::i;:::-;70160:42;;-1:-1:-1;;70160:42:0;70176:26;70160:42;;;70251:17;;;;70234:15;;;;70218:59;;13932:25:1;;;-1:-1:-1;;;;;70234:15:0;;;;70218:59;;;;;13920:2:1;13905:18;70218:59:0;13887:76:1;13778:149:0;12971:7;12998:12;;;;;;;;;;:22;;;10953:16;10964:4;10953:10;:16::i;:::-;13893:26:::1;13905:4;13911:7;13893:11;:26::i;67743:988::-:0;67832:1;67823:6;:10;67815:39;;;;-1:-1:-1;;;67815:39:0;;19559:2:1;67815:39:0;;;19541:21:1;19598:2;19578:18;;;19571:30;-1:-1:-1;;;19617:18:1;;;19610:46;19673:18;;67815:39:0;19531:166:1;67815:39:0;67881:10;67873:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;67873:30:0;;;;;;;;;:37;:47;-1:-1:-1;67873:47:0;67865:127;;;;-1:-1:-1;;;67865:127:0;;24873:2:1;67865:127:0;;;24855:21:1;24912:2;24892:18;;;24885:30;24951:34;24931:18;;;24924:62;25022:34;25002:18;;;24995:62;-1:-1:-1;;;25073:19:1;;;25066:34;25117:19;;67865:127:0;24845:297:1;67865:127:0;68052:10;68044:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;68044:30:0;;;;;;;;;:45;;;68093:12;-1:-1:-1;68044:61:0;68036:124;;;;-1:-1:-1;;;68036:124:0;;21586:2:1;68036:124:0;;;21568:21:1;21625:2;21605:18;;;21598:30;21664:34;21644:18;;;21637:62;-1:-1:-1;;;21715:18:1;;;21708:48;21773:19;;68036:124:0;21558:240:1;68036:124:0;68273:14;;:43;;-1:-1:-1;;;68273:43:0;;68297:10;68273:43;;;12259:51:1;12326:18;;;12319:34;;;68258:12:0;;-1:-1:-1;;;;;68273:14:0;;:23;;12232:18:1;;68273:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68258:58;;68330:7;68327:397;;;68370:6;68354:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;68439:10:0;68431:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;68431:30:0;;;;;;;;;:37;:46;;68471:6;;68431:46;:::i;:::-;68399:10;68391:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;68391:30:0;;;;;;;;;:86;;;;68525:19;:30;;;;:39;;68558:6;;68525:39;:::i;:::-;-1:-1:-1;;;;;68492:30:0;;;;;;:19;:30;;;;;;;:72;;;;68584:39;;68593:10;;68584:39;;;;68616:6;13932:25:1;;13920:2;13905:18;;13887:76;68584:39:0;;;;;;;;68327:397;;;68656:56;;-1:-1:-1;;;68656:56:0;;17125:2:1;68656:56:0;;;17107:21:1;17164:2;17144:18;;;17137:30;17203:34;17183:18;;;17176:62;-1:-1:-1;;;17254:18:1;;;17247:44;17308:19;;68656:56:0;17097:236:1;66389:152:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66502:20:0;;;;:10;:20;;;;;:31;;;;;;;;66495:38;;;;;;;;;;-1:-1:-1;;66495:38:0;;;;;;;;;;;;-1:-1:-1;;;66495:38:0;;;;;;;;;;;;;;;-1:-1:-1;;;66495:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66495:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66495:38:0;;;;;;;;;;;;;;;;-1:-1:-1;;;66495:38:0;;;-1:-1:-1;;66495:38:0;;;;-1:-1:-1;;;;;66495:38:0;;;;;;;;-1:-1:-1;;;66495:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66389:152:0;;;;:::o;48396:251::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;;;;;;48537:18:0;;::::1;48510:24;48537:18:::0;;;:9:::1;:18;::::0;;;;48566:23:::1;::::0;::::1;:31:::0;;;;48608:23:::1;;:31:::0;48396:251::o;46266:158::-;10507:4;10953:16;10507:4;10953:10;:16::i;:::-;-1:-1:-1;46363:15:0::1;:23:::0;;;;46397:11:::1;:19:::0;46266:158::o;50259:1475::-;-1:-1:-1;;;;;50466:29:0;;;50392:24;50466:29;;;:19;:29;;;;;;;50434;;;;;;;;50419:12;;50363:16;;50466:29;50419:44;;;:::i;:::-;:76;;;;:::i;:::-;-1:-1:-1;;;;;50554:18:0;;;50506:13;50554:18;;;:9;:18;;;;;:36;50392:103;;-1:-1:-1;50506:13:0;50554:36;50605:22;;;50601:72;;50644:17;50660:1;50644:17;;:::i;:::-;;;50601:72;-1:-1:-1;;;;;50687:22:0;;;50683:72;;50726:17;50742:1;50726:17;;:::i;:::-;;;50683:72;50765:23;50805:12;50791:27;;;;;;-1:-1:-1;;;50791:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50791:27:0;;50765:53;;50835:6;50831:872;50849:6;:13;50845:1;:17;50831:872;;;50903:16;50892:8;:6;:8::i;:::-;:27;;;;:::i;:::-;50884:35;;50938:6;50934:758;-1:-1:-1;;;;;50952:18:0;;;;;;:9;:18;;;;;:36;50948:40;;50934:758;;;-1:-1:-1;;;;;51018:18:0;;;;;;;:9;:18;;;;;:32;;:44;;;;51048:1;;51018:32;;;;-1:-1:-1;;;51018:32:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51018:32:0;:44;;;;:92;;-1:-1:-1;;;;;;51066:18:0;;;;;;;:9;:18;;;;;:32;;:44;;;;51096:1;;51066:32;;;;-1:-1:-1;;;51066:32:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51066:32:0;:44;;51018:92;51014:663;;;-1:-1:-1;;;;;51164:18:0;;;;;;:9;:18;;;;;:32;;51139:58;;51156:6;;51194:1;;51164:32;;;;-1:-1:-1;;;51164:32:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51164:32:0;51139:16;:58::i;:::-;51135:523;;-1:-1:-1;;;;;51268:18:0;;51248:53;51268:18;;;:9;:18;;;;;:32;;51248:19;;:53;51268:18;51298:1;;51268:32;;;;-1:-1:-1;;;51268:32:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51268:32:0;51248:53;;;;;;;;;;;;;51239:62;;51235:311;;-1:-1:-1;;;;;51346:18:0;;;;;;:9;:18;;;;;:32;;51376:1;;51346:32;;;;-1:-1:-1;;;51346:32:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51346:32:0;51334:6;51341:1;51334:9;;;;;;-1:-1:-1;;;51334:9:0;;;;;;;;;-1:-1:-1;;;;;51334:44:0;;;:9;;;;;;;;;;:44;;;;51449:18;;;51429:53;51449:18;;;:9;:18;;;;;;:32;;51429:19;;:53;51449:18;51479:1;;51449:32;;;;-1:-1:-1;;;51449:32:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51449:32:0;51429:53;;;;;;;;;;;;;51409:73;;;;:::i;:::-;;;51513:5;;51235:311;-1:-1:-1;;;;;51601:18:0;;51581:53;51601:18;;;:9;:18;;;;;:32;;51581:19;;:53;51601:18;51631:1;;51601:32;;;;-1:-1:-1;;;51601:32:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51601:32:0;51581:53;;;;;;;;;;;;;51572:62;;;;:::i;:::-;;;51135:523;50990:3;;;;:::i;:::-;;;;50934:758;;;-1:-1:-1;50864:3:0;;;;:::i;:::-;;;;50831:872;;;-1:-1:-1;51720:6:0;-1:-1:-1;;;;50259:1475:0;;;;;;:::o;11808:105::-;11875:30;11886:4;6384:10;11875;:30::i;:::-;11808:105;:::o;16079:238::-;16163:22;16171:4;16177:7;16163;:22::i;:::-;16158:152;;16202:6;:12;;;;;;;;;;;-1:-1:-1;;;;;16202:29:0;;;;;;;;;:36;;-1:-1:-1;;16202:36:0;16234:4;16202:36;;;16285:12;6384:10;6304:98;;16285:12;-1:-1:-1;;;;;16258:40:0;16276:7;-1:-1:-1;;;;;16258:40:0;16270:4;16258:40;;;;;;;;;;16079:238;;:::o;16497:239::-;16581:22;16589:4;16595:7;16581;:22::i;:::-;16577:152;;;16652:5;16620:12;;;;;;;;;;;-1:-1:-1;;;;;16620:29:0;;;;;;;;;;:37;;-1:-1:-1;;16620:37:0;;;16677:40;6384:10;;16620:12;;16677:40;;16652:5;16677:40;16497:239;;:::o;51742:1413::-;-1:-1:-1;;;;;51867:18:0;;51903:1;51867:18;;;:9;:18;;;;;:33;;;51859:85;;;;-1:-1:-1;;;51859:85:0;;14810:2:1;51859:85:0;;;14792:21:1;14849:2;14829:18;;;14822:30;14888:34;14868:18;;;14861:62;-1:-1:-1;;;14939:18:1;;;14932:33;14982:19;;51859:85:0;14782:225:1;51859:85:0;51974:10;52016:1;51963:22;;;:10;:22;;;;;;;;:33;;;;;;;;:41;;;-1:-1:-1;;;;;51963:41:0;:55;51955:114;;;;-1:-1:-1;;;51955:114:0;;25765:2:1;51955:114:0;;;25747:21:1;25804:2;25784:18;;;25777:30;25843:34;25823:18;;;25816:62;-1:-1:-1;;;25894:18:1;;;25887:44;25948:19;;51955:114:0;25737:236:1;51955:114:0;52118:585;;;;;;;;;;-1:-1:-1;52118:585:0;;;;52188:1;52118:585;;;;52214:1;52118:585;;;;52237:5;-1:-1:-1;;;;;52118:585:0;;;;;52282:1;-1:-1:-1;;;;;52118:585:0;;;;;52329:1;-1:-1:-1;;;;;52118:585:0;;;;;52352:1;52118:585;;;;52377:7;-1:-1:-1;;;;;52118:585:0;;;;;52410:9;52118:585;;;;52446:12;52118:585;;;;52489:52;52509:7;52526:1;52538;52489:19;:52::i;:::-;52118:585;;52580:1;52118:585;;;;;;;;;;;;;;;;;;;;;;;;;;;52093:10;52082:22;;:10;:22;;;;;:33;;;;;;:621;;;;:33;;-1:-1:-1;;52082:621:0;52118:585;52082:621;;;;;;;-1:-1:-1;;;52082:621:0;;;;;;;;;;;;;-1:-1:-1;52082:621:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52082:621:0;;;-1:-1:-1;;;;;;52082:621:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;52082:621:0;;;;;;;;;;;;;;;;-1:-1:-1;;;52082:621:0;;;-1:-1:-1;;;;;;52082:621:0;;;-1:-1:-1;;;;;52082:621:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52731:10;52082:621;52763:22;;;;;;;;;;;:33;;;;;;;;;52719:99;;52752:9;;52719:99;;;;;;;;52763:48;;;52813:4;;;;52719:99;:::i;:::-;;;;;;;;52854:10;52875:1;52834:31;;;52896:10;52834:31;52896:22;;;;;;;52834:19;52919:31;;;;;;52896:55;;;;;;;:61;52961:23;;52896:61;;:88;;;;;;-1:-1:-1;;;52896:88:0;;;;;;;;;;52893:190;;;53023:10;53012:22;;;;:10;:22;;;;;;;;53035:19;:31;;;;;;53012:55;;;;;;;53005:62;;-1:-1:-1;;53005:62:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53005:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53012:55;53005:62;;;;53012:22;53005:62;:::i;:::-;-1:-1:-1;53005:62:0;;;;;-1:-1:-1;;;;;;53005:62:0;;;;;;;;;;;;;;;;;52893:190;-1:-1:-1;;53124:10:0;53104:31;;;;:19;:31;;;;;:43;-1:-1:-1;;51742:1413:0:o;45854:268::-;45942:4;;45959:133;45977:5;:12;45973:1;:16;45959:133;;;46027:6;-1:-1:-1;;;;;46015:18:0;:5;46021:1;46015:8;;;;;;-1:-1:-1;;;46015:8:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;46015:18:0;;46011:70;;;46061:4;46054:11;;;;;46011:70;45991:3;;;;:::i;:::-;;;;45959:133;;;-1:-1:-1;46109:5:0;;45854:268;-1:-1:-1;;;45854:268:0:o;49554:454::-;49670:4;;49687:291;49705:4;:11;49701:1;:15;49687:291;;;49752:6;-1:-1:-1;;;;;49741:17:0;:4;49746:1;49741:7;;;;;;-1:-1:-1;;;49741:7:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;49741:17:0;;49738:229;;;49827:25;49842:10;49827:12;:25;:::i;:::-;49810:11;49814:7;49810:1;:11;:::i;:::-;49809:44;;:123;;;;-1:-1:-1;49924:7:0;49910:11;49924:7;49910:1;:11;:::i;:::-;:21;;;;:::i;:::-;49880:25;49895:10;49880:12;:25;:::i;:::-;49879:53;49809:123;49779:172;;;;;49738:229;49718:3;;;;:::i;:::-;;;;49687:291;;;;49995:5;49988:12;;49554:454;;;;;;;:::o;56473:1499::-;-1:-1:-1;;;;;56610:20:0;;;56584:23;56610:20;;;:10;:20;;;;;;;;:31;;;;;;;;56702:15;;;;;;;56692:26;;:9;:26;;;;;56702:15;56692:41;;56676:11;;;;:67;;56739:3;;56676:58;;:15;:58::i;:67::-;56793:22;;;;56817:23;;;;56857:13;;;;56652:91;;-1:-1:-1;56754:21:0;;56778:93;;-1:-1:-1;;;;;56793:22:0;;;;56817:23;;;56652:91;;56857:13;56778:14;:93::i;:::-;56754:117;-1:-1:-1;56885:9:0;;56882:109;;56924:22;;;;56948:23;;;;56911:68;;-1:-1:-1;;;;;56924:22:0;;;;56948:23;56973:5;56911:12;:68::i;:::-;57006:19;57003:962;;57096:15;;;;-1:-1:-1;;;;;57096:15:0;57042:25;57086:26;;;:9;:26;;;;;:41;;;57070:11;;;;:67;;57133:3;;57070:58;;:15;:58::i;:67::-;57155:13;;;;57042:95;;-1:-1:-1;;;;;;57155:13:0;57152:483;;57211:15;;;;57203:52;;-1:-1:-1;;;;;57211:15:0;;;;57203:52;;;;;57237:17;;57211:15;57203:52;57211:15;57203:52;57237:17;57211:15;57203:52;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57274:12:0;;57296:11;;;;-1:-1:-1;;;;;57274:12:0;;;;:70;;57326:17;;57296:27;;57310:13;;57296:27;:::i;:::-;:47;;;;:::i;:::-;57274:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57152:483;;;57415:13;;;;57471:15;;;;57448:58;;-1:-1:-1;;;57448:58:0;;-1:-1:-1;;;;;57471:15:0;;;57448:58;;;12259:51:1;12326:18;;;12319:34;;;57415:13:0;;;;;57448:22;;12232:18:1;;57448:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;57556:12:0;;57571:11;;;;-1:-1:-1;;;;;57525:22:0;;;;;;57556:12;;;57601:17;;57571:27;;57585:13;;57571:27;:::i;:::-;:47;;;;:::i;:::-;57525:94;;-1:-1:-1;;;;;;57525:94:0;;;;;;;-1:-1:-1;;;;;12277:32:1;;;57525:94:0;;;12259:51:1;12326:18;;;12319:34;12232:18;;57525:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;57152:483;;57003:962;;;;57670:13;;;;-1:-1:-1;;;;;57670:13:0;57667:287;;57726:8;-1:-1:-1;;;;;57718:26:0;:55;57759:13;57745:7;:11;;;:27;;;;:::i;:::-;57718:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57667:287;57844:13;;;;57910:11;;;;-1:-1:-1;;;;;57844:13:0;;;;;;57877:22;;57900:8;;57910:27;;57924:13;;57910:27;:::i;:::-;57877:61;;-1:-1:-1;;;;;;57877:61:0;;;;;;;-1:-1:-1;;;;;12277:32:1;;;57877:61:0;;;12259:51:1;12326:18;;;12319:34;12232:18;;57877:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;57667:287;;56473:1499;;;;;;;:::o;20365:98::-;20423:7;20450:5;20454:1;20450;:5;:::i;20764:98::-;20822:7;20849:5;20853:1;20849;:5;:::i;57980:730::-;58056:7;;;58111:427;-1:-1:-1;;;;;58135:28:0;;;;;;:17;:28;;;;;:35;58131:39;;58111:427;;;-1:-1:-1;;;;;58209:28:0;;58192:14;58209:28;;;:17;:28;;;;;:31;;58238:1;;58209:31;;;;-1:-1:-1;;;58209:31:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58339:30:0;;;;;;:19;:30;;;;;;;58209:31;;;;58292:15;;;:7;:15;;;;;:26;;;;;;;;:33;58209:31;;-1:-1:-1;58280:100:0;;58376:3;;58280:91;;58292:78;;58339:30;58280:91;;58376:3;58292:37;:42::i;:78::-;58280:7;;:11;:91::i;:100::-;-1:-1:-1;;;;;58431:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;;;:33;58255:125;;-1:-1:-1;58431:50:0;;58255:125;;58431:50;:::i;:::-;-1:-1:-1;;;;;58395:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;;;:86;58496:30;58512:14;58496:30;;:::i;:::-;;;58111:427;;58172:3;;;;;:::i;:::-;;;;58111:427;;;-1:-1:-1;;;;;;58616:30:0;;;;;;:19;:30;;;;;:46;;58650:12;;58616:30;:46;;58650:12;;58616:46;:::i;:::-;;;;-1:-1:-1;58690:12:0;;57980:730;-1:-1:-1;;;;57980:730:0:o;19627:98::-;19685:7;19712:5;19716:1;19712;:5;:::i;38552:248::-;38723:68;;-1:-1:-1;;;;;11963:15:1;;;38723:68:0;;;11945:34:1;12015:15;;11995:18;;;11988:43;12047:18;;;12040:34;;;38696:96:0;;38716:5;;-1:-1:-1;;;38746:27:0;11880:18:1;;38723:68:0;;;;-1:-1:-1;;38723:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;38723:68:0;-1:-1:-1;;;;;;38723:68:0;;;;;;;;;;38696:19;:96::i;38333:211::-;38477:58;;-1:-1:-1;;;;;12277:32:1;;38477:58:0;;;12259:51:1;12326:18;;;12319:34;;;38450:86:0;;38470:5;;-1:-1:-1;;;38500:23:0;12232:18:1;;38477:58:0;12214:145:1;50016:235:0;50056:7;50207:16;50225:15;50190:51;;;;;;;;11402:19:1;;;11446:2;11437:12;;11430:28;11483:2;11474:12;;11392:100;50190:51:0;;;;;;;;;;;;;50180:62;;;;;;50172:71;;50165:78;;50016:235;:::o;12203:505::-;12292:22;12300:4;12306:7;12292;:22::i;:::-;12287:414;;12480:41;12508:7;-1:-1:-1;;;;;12480:41:0;12518:2;12480:19;:41::i;:::-;12594:38;12622:4;12629:2;12594:19;:38::i;:::-;12385:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;12385:270:0;;;;;;;;;;-1:-1:-1;;;12331:358:0;;;;;;;:::i;55217:620::-;-1:-1:-1;;;;;55492:36:0;;;55344:7;55492:36;;;:19;:36;;;;;;;55452:35;;;;;;;;55344:7;;;;55386:154;;55536:3;;55386:145;;55403:127;;55452:77;;:39;:77::i;:::-;-1:-1:-1;;;;;55403:35:0;;;;;;:19;:35;;;;;;:44;;55443:3;55403:39;:44::i;:127::-;55386:12;;:16;:145::i;:154::-;55364:176;-1:-1:-1;55551:20:0;55574:26;55364:176;55574:12;:26;:::i;:::-;55551:49;;55611:24;55638:47;55650:14;55666:11;55679:5;55638:11;:47::i;:::-;55611:74;;55696:25;55724:49;55736:15;55753:12;55767:5;55724:11;:49::i;:::-;55696:77;-1:-1:-1;55793:36:0;55696:77;55793:16;:36;:::i;:::-;55786:43;55217:620;-1:-1:-1;;;;;;;;;55217:620:0:o;55845:::-;-1:-1:-1;;;;;56071:36:0;;;55951:18;56071:36;;;:19;:36;;;;;;;56031:35;;;;;;;;55951:18;;55972:147;;56115:3;;55972:138;;55982:127;;56031:77;;:35;:39;:77::i;:::-;-1:-1:-1;;;;;55982:35:0;;;;;;:19;:35;;;;;;:44;;56022:3;55982:39;:44::i;:127::-;55972:5;;:9;:138::i;:147::-;55951:168;-1:-1:-1;56130:19:0;56152:18;55951:168;56152:5;:18;:::i;:::-;56130:40;;56181:23;56207:38;56218:14;56234:10;56207;:38::i;:::-;56181:64;;56256:24;56283:40;56294:15;56311:11;56283:10;:40::i;:::-;-1:-1:-1;;;;;56336:35:0;;;;;;:19;:35;;;;;:54;;56256:67;;-1:-1:-1;56375:15:0;;56336:35;;;:54;;56375:15;;56336:54;:::i;:::-;;;;-1:-1:-1;;;;;;;56401:36:0;;;;;;:19;:36;;;;;:56;;56441:16;;56401:36;:56;;56441:16;;56401:56;:::i;:::-;;;;-1:-1:-1;;;;;;;;;55845:620:0:o;41400:716::-;41824:23;41850:69;41878:4;41850:69;;;;;;;;;;;;;;;;;41858:5;-1:-1:-1;;;;;41850:27:0;;;:69;;;;;:::i;:::-;41934:17;;41824:95;;-1:-1:-1;41934:21:0;41930:179;;42031:10;42020:30;;;;;;;;;;;;:::i;:::-;42012:85;;;;-1:-1:-1;;;42012:85:0;;24462:2:1;42012:85:0;;;24444:21:1;24501:2;24481:18;;;24474:30;24540:34;24520:18;;;24513:62;-1:-1:-1;;;24591:18:1;;;24584:40;24641:19;;42012:85:0;24434:232:1;4851:451:0;4926:13;4952:19;4984:10;4988:6;4984:1;:10;:::i;:::-;:14;;4997:1;4984:14;:::i;:::-;4974:25;;;;;;-1:-1:-1;;;4974:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4974:25:0;;4952:47;;-1:-1:-1;;;5010:6:0;5017:1;5010:9;;;;;;-1:-1:-1;;;5010:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;5010:15:0;;;;;;;;;-1:-1:-1;;;5036:6:0;5043:1;5036:9;;;;;;-1:-1:-1;;;5036:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;5036:15:0;;;;;;;;-1:-1:-1;5067:9:0;5079:10;5083:6;5079:1;:10;:::i;:::-;:14;;5092:1;5079:14;:::i;:::-;5067:26;;5062:135;5099:1;5095;:5;5062:135;;;-1:-1:-1;;;5147:5:0;5155:3;5147:11;5134:25;;;;;-1:-1:-1;;;5134:25:0;;;;;;;;;;;;5122:6;5129:1;5122:9;;;;;;-1:-1:-1;;;5122:9:0;;;;;;;;;;;;:37;-1:-1:-1;;;;;5122:37:0;;;;;;;;-1:-1:-1;5184:1:0;5174:11;;;;;5102:3;;;:::i;:::-;;;5062:135;;;-1:-1:-1;5215:10:0;;5207:55;;;;-1:-1:-1;;;5207:55:0;;15214:2:1;5207:55:0;;;15196:21:1;;;15233:18;;;15226:30;15292:34;15272:18;;;15265:62;15344:18;;5207:55:0;15186:182:1;53511:993:0;53599:7;;;-1:-1:-1;;;;;53688:19:0;;;53685:80;;-1:-1:-1;53747:5:0;53685:80;53782:9;53777:690;-1:-1:-1;;;;;53801:28:0;;;;;;:17;:28;;;;;:35;53797:39;;53777:690;;;-1:-1:-1;;;;;53875:28:0;;53858:14;53875:28;;;:17;:28;;;;;:31;;53904:1;;53875:31;;;;-1:-1:-1;;;53875:31:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53875:31:0;;;53949:15;;;:7;:15;;;;;;:26;;;;;;;;;;;54123:19;:30;;;;;;;54091:18;;53875:31;;-1:-1:-1;53949:26:0;;53875:31;54080:84;;54160:3;;54080:75;;54091:63;;54123:30;54080:75;;54160:3;54091:22;:27::i;:63::-;54080:6;;:10;:75::i;:84::-;54055:109;-1:-1:-1;;;;;;54228:19:0;;54225:186;;54268:40;;-1:-1:-1;;;;;54268:24:0;;;:40;;;;;54293:14;;54268:40;;;;54293:14;54268:24;:40;;;;;;;;;;;;;;;;;;;;;54225:186;;;54349:46;;-1:-1:-1;;;54349:46:0;;-1:-1:-1;;;;;12277:32:1;;;54349:46:0;;;12259:51:1;12326:18;;;12319:34;;;54349:22:0;;;;;12232:18:1;;54349:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;54225:186;54425:30;54441:14;54425:30;;:::i;:::-;;;53777:690;;;53838:3;;;;;:::i;:::-;;;;53777:690;;;-1:-1:-1;54484:12:0;;53511:993;-1:-1:-1;;;;;53511:993:0:o;54512:697::-;54583:7;;;54638:534;-1:-1:-1;;;;;54662:28:0;;;;;;:17;:28;;;;;:35;54658:39;;54638:534;;;-1:-1:-1;;;;;54736:28:0;;54719:14;54736:28;;;:17;:28;;;;;:31;;54765:1;;54736:31;;;;-1:-1:-1;;;54736:31:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54928:30:0;;;;;;:19;:30;;;;;;;54736:31;;;;54881:15;;;:7;:15;;;;;:26;;;;;;;;:33;54736:31;;-1:-1:-1;54871:98:0;;54965:3;;54871:89;;54881:78;;54928:30;54871:89;;54965:3;54881:37;:42::i;54871:98::-;-1:-1:-1;;;;;55062:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;;;:33;54846:123;;-1:-1:-1;55062:53:0;;54846:123;55062:37;:53::i;:::-;-1:-1:-1;;;;;55026:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;;;:89;55130:30;55146:14;55130:30;;:::i;:::-;;;54638:534;;54699:3;;;;;:::i;:::-;;;;54638:534;;;-1:-1:-1;55189:12:0;54512:697;-1:-1:-1;;;54512:697:0:o;30665:229::-;30802:12;30834:52;30856:6;30864:4;30870:1;30873:12;30802;-1:-1:-1;;;;;28215:19:0;;;32072:60;;;;-1:-1:-1;;;32072:60:0;;23694:2:1;32072:60:0;;;23676:21:1;23733:2;23713:18;;;23706:30;23772:31;23752:18;;;23745:59;23821:18;;32072:60:0;23666:179:1;32072:60:0;32146:12;32160:23;32187:6;-1:-1:-1;;;;;32187:11:0;32206:5;32213:4;32187:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32145:73;;;;32236:51;32253:7;32262:10;32274:12;32236:16;:51::i;:::-;32229:58;31785:510;-1:-1:-1;;;;;;;31785:510:0:o;34471:762::-;34621:12;34650:7;34646:580;;;-1:-1:-1;34681:10:0;34674:17;;34646:580;34795:17;;:21;34791:424;;35043:10;35037:17;35104:15;35091:10;35087:2;35083:19;35076:44;34991:148;35186:12;35179:20;;-1:-1:-1;;;35179:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:134:1;82:20;;111:31;82:20;111:31;:::i;153:939::-;;260:3;253:4;245:6;241:17;237:27;227:2;;282:5;275;268:20;227:2;322:6;309:20;348:4;371:18;408:2;404;401:10;398:2;;;414:18;;:::i;:::-;460:2;457:1;453:10;492:2;486:9;555:2;551:7;546:2;542;538:11;534:25;526:6;522:38;610:6;598:10;595:22;590:2;578:10;575:18;572:46;569:2;;;621:18;;:::i;:::-;657:2;650:22;707:18;;;741:15;;;;-1:-1:-1;776:15:1;;;810;;;806:24;;803:33;-1:-1:-1;800:2:1;;;853:5;846;839:20;800:2;879:5;870:14;;893:169;907:2;904:1;901:9;893:169;;;964:23;983:3;964:23;:::i;:::-;952:36;;1008:12;;;;925:1;918:9;;;;;1040:12;;893:169;;;-1:-1:-1;1080:6:1;217:875;-1:-1:-1;;;;;;;217:875:1:o;1097:376::-;;;1213:3;1206:4;1198:6;1194:17;1190:27;1180:2;;1238:8;1228;1221:26;1180:2;-1:-1:-1;1268:20:1;;1311:18;1300:30;;1297:2;;;1350:8;1340;1333:26;1297:2;1394:4;1386:6;1382:17;1370:29;;1446:3;1439:4;1430:6;1422;1418:19;1414:30;1411:39;1408:2;;;1463:1;1460;1453:12;1408:2;1170:303;;;;;:::o;1478:257::-;;1590:2;1578:9;1569:7;1565:23;1561:32;1558:2;;;1611:6;1603;1596:22;1558:2;1655:9;1642:23;1674:31;1699:5;1674:31;:::i;2010:398::-;;;2139:2;2127:9;2118:7;2114:23;2110:32;2107:2;;;2160:6;2152;2145:22;2107:2;2204:9;2191:23;2223:31;2248:5;2223:31;:::i;:::-;2273:5;-1:-1:-1;2330:2:1;2315:18;;2302:32;2343:33;2302:32;2343:33;:::i;:::-;2395:7;2385:17;;;2097:311;;;;;:::o;2413:776::-;;;;;;2596:3;2584:9;2575:7;2571:23;2567:33;2564:2;;;2618:6;2610;2603:22;2564:2;2662:9;2649:23;2681:31;2706:5;2681:31;:::i;:::-;2731:5;-1:-1:-1;2788:2:1;2773:18;;2760:32;2801:33;2760:32;2801:33;:::i;:::-;2853:7;-1:-1:-1;2907:2:1;2892:18;;2879:32;;-1:-1:-1;2962:2:1;2947:18;;2934:32;2989:18;2978:30;;2975:2;;;3026:6;3018;3011:22;2975:2;3070:59;3121:7;3112:6;3101:9;3097:22;3070:59;:::i;:::-;2554:635;;;;-1:-1:-1;2554:635:1;;-1:-1:-1;3148:8:1;;3044:85;2554:635;-1:-1:-1;;;2554:635:1:o;3194:640::-;;;;;3382:3;3370:9;3361:7;3357:23;3353:33;3350:2;;;3404:6;3396;3389:22;3350:2;3448:9;3435:23;3467:31;3492:5;3467:31;:::i;:::-;3517:5;-1:-1:-1;3573:2:1;3558:18;;3545:32;3600:18;3589:30;;3586:2;;;3637:6;3629;3622:22;3586:2;3665:61;3718:7;3709:6;3698:9;3694:22;3665:61;:::i;:::-;3340:494;;3655:71;;-1:-1:-1;;;;3773:2:1;3758:18;;3745:32;;3824:2;3809:18;3796:32;;3340:494;-1:-1:-1;3340:494:1:o;3839:325::-;;;3968:2;3956:9;3947:7;3943:23;3939:32;3936:2;;;3989:6;3981;3974:22;3936:2;4033:9;4020:23;4052:31;4077:5;4052:31;:::i;:::-;4102:5;4154:2;4139:18;;;;4126:32;;-1:-1:-1;;;3926:238:1:o;4169:460::-;;;;4312:2;4300:9;4291:7;4287:23;4283:32;4280:2;;;4333:6;4325;4318:22;4280:2;4377:9;4364:23;4396:31;4421:5;4396:31;:::i;:::-;4446:5;-1:-1:-1;4498:2:1;4483:18;;4470:32;;-1:-1:-1;4554:2:1;4539:18;;4526:32;4567:30;4526:32;4567:30;:::i;:::-;4616:7;4606:17;;;4270:359;;;;;:::o;4634:634::-;;;;;4800:2;4788:9;4779:7;4775:23;4771:32;4768:2;;;4821:6;4813;4806:22;4768:2;4865:9;4852:23;4884:31;4909:5;4884:31;:::i;:::-;4934:5;-1:-1:-1;4986:2:1;4971:18;;4958:32;;-1:-1:-1;5041:2:1;5026:18;;5013:32;5068:18;5057:30;;5054:2;;;5105:6;5097;5090:22;5054:2;5149:59;5200:7;5191:6;5180:9;5176:22;5149:59;:::i;:::-;4758:510;;;;-1:-1:-1;5227:8:1;-1:-1:-1;;;;4758:510:1:o;5273:543::-;;;;;5444:3;5432:9;5423:7;5419:23;5415:33;5412:2;;;5466:6;5458;5451:22;5412:2;5510:9;5497:23;5529:31;5554:5;5529:31;:::i;:::-;5579:5;-1:-1:-1;5631:2:1;5616:18;;5603:32;;-1:-1:-1;5682:2:1;5667:18;;5654:32;;-1:-1:-1;5738:2:1;5723:18;;5710:32;5751:33;5710:32;5751:33;:::i;:::-;5402:414;;;;-1:-1:-1;5402:414:1;;-1:-1:-1;;5402:414:1:o;6151:393::-;;;;6297:2;6285:9;6276:7;6272:23;6268:32;6265:2;;;6318:6;6310;6303:22;6265:2;6362:9;6349:23;6381:31;6406:5;6381:31;:::i;:::-;6431:5;6483:2;6468:18;;6455:32;;-1:-1:-1;6534:2:1;6519:18;;;6506:32;;6255:289;-1:-1:-1;;;6255:289:1:o;6549:368::-;;6686:2;6674:9;6665:7;6661:23;6657:32;6654:2;;;6707:6;6699;6692:22;6654:2;6752:9;6739:23;6785:18;6777:6;6774:30;6771:2;;;6822:6;6814;6807:22;6771:2;6850:61;6903:7;6894:6;6883:9;6879:22;6850:61;:::i;6922:255::-;;7042:2;7030:9;7021:7;7017:23;7013:32;7010:2;;;7063:6;7055;7048:22;7010:2;7100:9;7094:16;7119:28;7141:5;7119:28;:::i;7182:190::-;;7294:2;7282:9;7273:7;7269:23;7265:32;7262:2;;;7315:6;7307;7300:22;7262:2;-1:-1:-1;7343:23:1;;7252:120;-1:-1:-1;7252:120:1:o;7377:325::-;;;7506:2;7494:9;7485:7;7481:23;7477:32;7474:2;;;7527:6;7519;7512:22;7474:2;7568:9;7555:23;7545:33;;7628:2;7617:9;7613:18;7600:32;7641:31;7666:5;7641:31;:::i;7707:306::-;;7818:2;7806:9;7797:7;7793:23;7789:32;7786:2;;;7839:6;7831;7824:22;7786:2;7870:23;;-1:-1:-1;;;;;;7922:32:1;;7912:43;;7902:2;;7974:6;7966;7959:22;8213:258;;;8342:2;8330:9;8321:7;8317:23;8313:32;8310:2;;;8363:6;8355;8348:22;8310:2;-1:-1:-1;;8391:23:1;;;8461:2;8446:18;;;8433:32;;-1:-1:-1;8300:171:1:o;8593:463::-;;8684:5;8678:12;8711:6;8706:3;8699:19;8737:4;8766:2;8761:3;8757:12;8750:19;;8803:2;8796:5;8792:14;8824:3;8836:195;8850:6;8847:1;8844:13;8836:195;;;8915:13;;-1:-1:-1;;;;;8911:39:1;8899:52;;8971:12;;;;9006:15;;;;8947:1;8865:9;8836:195;;;-1:-1:-1;9047:3:1;;8654:402;-1:-1:-1;;;;;8654:402:1:o;9061:501::-;;9160:5;9154:12;9187:6;9182:3;9175:19;9213:4;9242:2;9237:3;9233:12;9226:19;;9266:5;9261:3;9254:18;9310:2;9305:3;9295:18;9331:3;9343:194;9357:6;9354:1;9351:13;9343:194;;;9422:13;;-1:-1:-1;;;;;9418:39:1;9406:52;;9478:12;;;;9454:1;9513:14;;;;9372:9;9343:194;;9663:233;9740:1;9733:5;9730:12;9720:2;;9785:10;9780:3;9776:20;9773:1;9766:31;9820:4;9817:1;9810:15;9848:4;9845:1;9838:15;9720:2;9872:18;;9710:186::o;9901:269::-;;9990:6;9985:3;9978:19;10042:6;10035:5;10028:4;10023:3;10019:14;10006:43;10094:3;10087:4;10078:6;10073:3;10069:16;10065:27;10058:40;10159:4;10152:2;10148:7;10143:2;10135:6;10131:15;10127:29;10122:3;10118:39;10114:50;10107:57;;9968:202;;;;;:::o;10175:274::-;;10342:6;10336:13;10358:53;10404:6;10399:3;10392:4;10384:6;10380:17;10358:53;:::i;:::-;10427:16;;;;;10312:137;-1:-1:-1;;10312:137:1:o;10454:786::-;;10865:25;10860:3;10853:38;10920:6;10914:13;10936:62;10991:6;10986:2;10981:3;10977:12;10970:4;10962:6;10958:17;10936:62;:::i;:::-;-1:-1:-1;;;11057:2:1;11017:16;;;11049:11;;;11042:40;11107:13;;11129:63;11107:13;11178:2;11170:11;;11163:4;11151:17;;11129:63;:::i;:::-;11212:17;11231:2;11208:26;;10843:397;-1:-1:-1;;;;10843:397:1:o;12364:266::-;;12540:2;12529:9;12522:21;12560:64;12620:2;12609:9;12605:18;12597:6;12560:64;:::i;12635:456::-;;12869:2;12858:9;12851:21;12895:64;12955:2;12944:9;12940:18;12932:6;12895:64;:::i;:::-;13007:9;12999:6;12995:22;12990:2;12979:9;12975:18;12968:50;13035;13078:6;13070;13062;13035:50;:::i;:::-;13027:58;12841:250;-1:-1:-1;;;;;;12841:250:1:o;13096:493::-;;13373:2;13362:9;13355:21;13399:64;13459:2;13448:9;13444:18;13436:6;13399:64;:::i;:::-;13499:22;;;13494:2;13479:18;;;13472:50;13531:20;;;13568:15;;13345:244;-1:-1:-1;13345:244:1:o;13968:247::-;;14127:2;14116:9;14109:21;14147:62;14205:2;14194:9;14190:18;14182:6;14174;14147:62;:::i;14220:383::-;;14369:2;14358:9;14351:21;14401:6;14395:13;14444:6;14439:2;14428:9;14424:18;14417:34;14460:66;14519:6;14514:2;14503:9;14499:18;14494:2;14486:6;14482:15;14460:66;:::i;:::-;14587:2;14566:15;-1:-1:-1;;14562:29:1;14547:45;;;;14594:2;14543:54;;14341:262;-1:-1:-1;;14341:262:1:o;19702:411::-;19904:2;19886:21;;;19943:2;19923:18;;;19916:30;19982:34;19977:2;19962:18;;19955:62;-1:-1:-1;;;20048:2:1;20033:18;;20026:45;20103:3;20088:19;;19876:237::o;20538:409::-;20740:2;20722:21;;;20779:2;20759:18;;;20752:30;20818:34;20813:2;20798:18;;20791:62;-1:-1:-1;;;20884:2:1;20869:18;;20862:43;20937:3;20922:19;;20712:235::o;20952:427::-;21154:2;21136:21;;;21193:2;21173:18;;;21166:30;21232:34;21227:2;21212:18;;21205:62;21303:33;21298:2;21283:18;;21276:61;21369:3;21354:19;;21126:253::o;22213:469::-;22415:2;22397:21;;;22454:2;22434:18;;;22427:30;22493:34;22488:2;22473:18;;22466:62;22564:34;22559:2;22544:18;;22537:62;-1:-1:-1;;;22630:3:1;22615:19;;22608:32;22672:3;22657:19;;22387:295::o;22687:397::-;22889:2;22871:21;;;22928:2;22908:18;;;22901:30;22967:34;22962:2;22947:18;;22940:62;-1:-1:-1;;;23033:2:1;23018:18;;23011:31;23074:3;23059:19;;22861:223::o;25978:1949::-;;26157:2;26146:9;26139:21;26169:56;26221:2;26210:9;26206:18;26197:6;26191:13;26169:56;:::i;:::-;26279:2;26271:6;26267:15;26261:22;26256:2;26245:9;26241:18;26234:50;26338:2;26330:6;26326:15;26320:22;26315:2;26304:9;26300:18;26293:50;26390:2;26382:6;26378:15;26372:22;26403:61;26459:3;26448:9;26444:19;26430:12;-1:-1:-1;;;;;8550:31:1;8538:44;;8528:60;26403:61;-1:-1:-1;26513:3:1;26501:16;;26495:23;-1:-1:-1;;;;;8550:31:1;;26585:3;26570:19;;8538:44;-1:-1:-1;26639:3:1;26627:16;;26621:23;-1:-1:-1;;;;;8550:31:1;;26711:3;26696:19;;8538:44;26653:63;26771:3;26763:6;26759:16;26753:23;26747:3;26736:9;26732:19;26725:52;26826:3;26818:6;26814:16;26808:23;26850:3;26862:62;26920:2;26909:9;26905:18;26889:14;-1:-1:-1;;;;;8550:31:1;8538:44;;8528:60;26862:62;26949:15;;26943:22;26984:3;27003:18;;;26996:30;;;;27051:15;;27045:22;27086:3;27105:18;;;27098:30;;;;27165:15;;27159:22;27200:6;27225:3;27244:18;;;27237:30;;;27159:22;;-1:-1:-1;27200:6:1;27290:65;27350:3;27335:19;;27159:22;27290:65;:::i;:::-;27392:15;;;27386:22;27276:79;;-1:-1:-1;27427:3:1;27439:62;27482:18;;;27386:22;-1:-1:-1;;;;;8550:31:1;8538:44;;8528:60;27439:62;27538:15;;27532:22;;-1:-1:-1;27573:3:1;27585:51;27617:18;;;27532:22;9637:13;9630:21;9618:34;;9608:50;27585:51;27673:15;;27667:22;;-1:-1:-1;27709:3:1;27721:63;27764:19;;;27667:22;-1:-1:-1;;;;;8550:31:1;8538:44;;8528:60;27721:63;27821:16;;;27815:23;9637:13;9630:21;27879:18;;9618:34;;;;-1:-1:-1;27915:6:1;;-1:-1:-1;26129:1798:1:o;28665:128::-;;28736:1;28732:6;28729:1;28726:13;28723:2;;;28742:18;;:::i;:::-;-1:-1:-1;28778:9:1;;28713:80::o;28798:120::-;;28864:1;28854:2;;28869:18;;:::i;:::-;-1:-1:-1;28903:9:1;;28844:74::o;28923:168::-;;29029:1;29025;29021:6;29017:14;29014:1;29011:21;29006:1;28999:9;28992:17;28988:45;28985:2;;;29036:18;;:::i;:::-;-1:-1:-1;29076:9:1;;28975:116::o;29096:125::-;;29164:1;29161;29158:8;29155:2;;;29169:18;;:::i;:::-;-1:-1:-1;29206:9:1;;29145:76::o;29226:258::-;29298:1;29308:113;29322:6;29319:1;29316:13;29308:113;;;29398:11;;;29392:18;29379:11;;;29372:39;29344:2;29337:10;29308:113;;;29439:6;29436:1;29433:13;29430:2;;;-1:-1:-1;;29474:1:1;29456:16;;29449:27;29279:205::o;29489:136::-;;29556:5;29546:2;;29565:18;;:::i;:::-;-1:-1:-1;;;29601:18:1;;29536:89::o;29630:135::-;;-1:-1:-1;;29690:17:1;;29687:2;;;29710:18;;:::i;:::-;-1:-1:-1;29757:1:1;29746:13;;29677:88::o;29770:112::-;;29828:1;29818:2;;29833:18;;:::i;:::-;-1:-1:-1;29867:9:1;;29808:74::o;29887:127::-;29948:10;29943:3;29939:20;29936:1;29929:31;29979:4;29976:1;29969:15;30003:4;30000:1;29993:15;30019:127;30080:10;30075:3;30071:20;30068:1;30061:31;30111:4;30108:1;30101:15;30135:4;30132:1;30125:15;30151:127;30212:10;30207:3;30203:20;30200:1;30193:31;30243:4;30240:1;30233:15;30267:4;30264:1;30257:15;30283:131;-1:-1:-1;;;;;30358:31:1;;30348:42;;30338:2;;30404:1;30401;30394:12;30419:118;30505:5;30498:13;30491:21;30484:5;30481:32;30471:2;;30527:1;30524;30517:12
Swarm Source
ipfs://3ec26f75fe81ee04fa38f77f93a68abe326b6185e8d4f2251d84b9db6a534eef
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.