Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 382951 | 5 days ago | IN | 0 S | 0.00005556 |
Loading...
Loading
Contract Name:
FateAdventureToken
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-13 */ // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * * ```solidity * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // File: @openzeppelin/contracts/interfaces/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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/interfaces/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/interfaces/IERC1363.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } // File: @openzeppelin/contracts/utils/Errors.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol pragma solidity >=0.8.0; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol pragma solidity ^0.8.20; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppCore.sol pragma solidity ^0.8.20; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol pragma solidity ^0.8.20; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol pragma solidity >=0.8.0; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.sol pragma solidity ^0.8.20; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppReceiver.sol pragma solidity ^0.8.20; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OApp.sol pragma solidity ^0.8.20; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import // @dev Import the 'Origin' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import /** * @title OApp * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality. */ abstract contract OApp is OAppSender, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppOptionsType3.sol pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); } // File: @layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol pragma solidity ^0.8.20; /** * @title OAppOptionsType3 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options. */ abstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable { uint16 internal constant OPTION_TYPE_3 = 3; // @dev The "msgType" should be defined in the child contract. mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions; /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner { _setEnforcedOptions(_enforcedOptions); } /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual { for (uint256 i = 0; i < _enforcedOptions.length; i++) { // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining. _assertOptionsType3(_enforcedOptions[i].options); enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options; } emit EnforcedOptionSet(_enforcedOptions); } /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OAPP message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. * * @dev If there is an enforced lzReceive option: * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether} * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function. * @dev This presence of duplicated options is handled off-chain in the verifier/executor. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) public view virtual returns (bytes memory) { bytes memory enforced = enforcedOptions[_eid][_msgType]; // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options. if (enforced.length == 0) return _extraOptions; // No caller options, return enforced if (_extraOptions.length == 0) return enforced; // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined. if (_extraOptions.length >= 2) { _assertOptionsType3(_extraOptions); // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced. return bytes.concat(enforced, _extraOptions[2:]); } // No valid set of options was found. revert InvalidOptions(_extraOptions); } /** * @dev Internal function to assert that options are of type 3. * @param _options The options to be checked. */ function _assertOptionsType3(bytes memory _options) internal pure virtual { uint16 optionsType; assembly { optionsType := mload(add(_options, 2)) } if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppMsgInspector.sol pragma solidity ^0.8.20; /** * @title IOAppMsgInspector * @dev Interface for the OApp Message Inspector, allowing examination of message and options contents. */ interface IOAppMsgInspector { // Custom error message for inspection failure error InspectionFailed(bytes message, bytes options); /** * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid. * @param _message The message payload to be inspected. * @param _options Additional options or parameters for inspection. * @return valid A boolean indicating whether the inspection passed (true) or failed (false). * * @dev Optionally done as a revert, OR use the boolean provided to handle the failure. */ function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid); } // File: @layerzerolabs/oapp-evm/contracts/precrime/interfaces/IPreCrime.sol pragma solidity ^0.8.20; struct PreCrimePeer { uint32 eid; bytes32 preCrime; bytes32 oApp; } // TODO not done yet interface IPreCrime { error OnlyOffChain(); // for simulate() error PacketOversize(uint256 max, uint256 actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for preCrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory); function simulate( bytes[] calldata _packets, uint256[] calldata _packetMsgValues ) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function preCrime( bytes[] calldata _packets, uint256[] calldata _packetMsgValues, bytes[] calldata _simulations ) external; function version() external view returns (uint64 major, uint8 minor); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol pragma solidity >=0.8.0; enum MessageLibType { Send, Receive, SendAndReceive } interface IMessageLib is IERC165 { function setConfig(address _oapp, SetConfigParam[] calldata _config) external; function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config); function isSupportedEid(uint32 _eid) external view returns (bool); // message libs of same major version are compatible function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion); function messageLibType() external view returns (MessageLibType); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol pragma solidity >=0.8.0; struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } interface ISendLib is IMessageLib { function send( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external returns (MessagingFee memory, bytes memory encodedPacket); function quote( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); function setTreasury(address _treasury) external; function withdrawFee(address _to, uint256 _amount) external; function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external; } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol pragma solidity ^0.8.20; library AddressCast { error AddressCast_InvalidSizeForAddress(); error AddressCast_InvalidAddress(); function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { if (_addressBytes.length > 32) revert AddressCast_InvalidAddress(); result = bytes32(_addressBytes); unchecked { uint256 offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint256(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) { if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress(); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint256(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { if (_addressBytes.length != 20) revert AddressCast_InvalidAddress(); result = address(bytes20(_addressBytes)); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol pragma solidity ^0.8.20; library PacketV1Codec { using AddressCast for address; using AddressCast for bytes32; uint8 internal constant PACKET_VERSION = 1; // header (version + nonce + path) // version uint256 private constant PACKET_VERSION_OFFSET = 0; // nonce uint256 private constant NONCE_OFFSET = 1; // path uint256 private constant SRC_EID_OFFSET = 9; uint256 private constant SENDER_OFFSET = 13; uint256 private constant DST_EID_OFFSET = 45; uint256 private constant RECEIVER_OFFSET = 49; // payload (guid + message) uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path) uint256 private constant MESSAGE_OFFSET = 113; function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) { encodedPacket = abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver, _packet.guid, _packet.message ); } function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver ); } function encodePayload(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked(_packet.guid, _packet.message); } function header(bytes calldata _packet) internal pure returns (bytes calldata) { return _packet[0:GUID_OFFSET]; } function version(bytes calldata _packet) internal pure returns (uint8) { return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET])); } function nonce(bytes calldata _packet) internal pure returns (uint64) { return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET])); } function srcEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET])); } function sender(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]); } function senderAddressB20(bytes calldata _packet) internal pure returns (address) { return sender(_packet).toAddress(); } function dstEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET])); } function receiver(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]); } function receiverB20(bytes calldata _packet) internal pure returns (address) { return receiver(_packet).toAddress(); } function guid(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]); } function message(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[MESSAGE_OFFSET:]); } function payload(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[GUID_OFFSET:]); } function payloadHash(bytes calldata _packet) internal pure returns (bytes32) { return keccak256(payload(_packet)); } } // File: @layerzerolabs/oapp-evm/contracts/precrime/libs/Packet.sol pragma solidity ^0.8.20; /** * @title InboundPacket * @dev Structure representing an inbound packet received by the contract. */ struct InboundPacket { Origin origin; // Origin information of the packet. uint32 dstEid; // Destination endpointId of the packet. address receiver; // Receiver address for the packet. bytes32 guid; // Unique identifier of the packet. uint256 value; // msg.value of the packet. address executor; // Executor address for the packet. bytes message; // Message payload of the packet. bytes extraData; // Additional arbitrary data for the packet. } /** * @title PacketDecoder * @dev Library for decoding LayerZero packets. */ library PacketDecoder { using PacketV1Codec for bytes; /** * @dev Decode an inbound packet from the given packet data. * @param _packet The packet data to decode. * @return packet An InboundPacket struct representing the decoded packet. */ function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } /** * @dev Decode multiple inbound packets from the given packet data and associated message values. * @param _packets An array of packet data to decode. * @param _packetMsgValues An array of associated message values for each packet. * @return packets An array of InboundPacket structs representing the decoded packets. */ function decode( bytes[] calldata _packets, uint256[] memory _packetMsgValues ) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint256 i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); // @dev Allows the verifier to specify the msg.value that gets passed in lzReceive. packets[i].value = _packetMsgValues[i]; } } } // File: @layerzerolabs/oapp-evm/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol pragma solidity ^0.8.20; // @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers. // solhint-disable-next-line no-unused-import /** * @title IOAppPreCrimeSimulator Interface * @dev Interface for the preCrime simulation functionality in an OApp. */ interface IOAppPreCrimeSimulator { // @dev simulation result used in PreCrime implementation error SimulationResult(bytes result); error OnlySelf(); /** * @dev Emitted when the preCrime contract address is set. * @param preCrimeAddress The address of the preCrime contract. */ event PreCrimeSet(address preCrimeAddress); /** * @dev Retrieves the address of the preCrime contract implementation. * @return The address of the preCrime contract. */ function preCrime() external view returns (address); /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. */ function oApp() external view returns (address); /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) external; /** * @dev Mocks receiving a packet, then reverts with a series of data to infer the state/result. * @param _packets An array of LayerZero InboundPacket objects representing received packets. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool); } // File: @layerzerolabs/oapp-evm/contracts/precrime/OAppPreCrimeSimulator.sol pragma solidity ^0.8.20; /** * @title OAppPreCrimeSimulator * @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp. */ abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable { // The address of the preCrime implementation. address public preCrime; /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. * * @dev The simulator contract is the base contract for the OApp by default. * @dev If the simulator is a separate contract, override this function. */ function oApp() external view virtual returns (address) { return address(this); } /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) public virtual onlyOwner { preCrime = _preCrime; emit PreCrimeSet(_preCrime); } /** * @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results. * @param _packets An array of InboundPacket objects representing received packets to be delivered. * * @dev WARNING: MUST revert at the end with the simulation results. * @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function, * WITHOUT actually executing them. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual { for (uint256 i = 0; i < _packets.length; i++) { InboundPacket calldata packet = _packets[i]; // Ignore packets that are not from trusted peers. if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; // @dev Because a verifier is calling this function, it doesnt have access to executor params: // - address _executor // - bytes calldata _extraData // preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive(). // They are instead stubbed to default values, address(0) and bytes("") // @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit, // which would cause the revert to be ignored. this.lzReceiveSimulate{ value: packet.value }( packet.origin, packet.guid, packet.message, packet.executor, packet.extraData ); } // @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult(). revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult()); } /** * @dev Is effectively an internal function because msg.sender must be address(this). * Allows resetting the call stack for 'internal' calls. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier of the packet. * @param _message The message payload of the packet. * @param _executor The executor address for the packet. * @param _extraData Additional data for the packet. */ function lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable virtual { // @dev Ensure ONLY can be called 'internally'. if (msg.sender != address(this)) revert OnlySelf(); _lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The GUID of the LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); } // File: @layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol pragma solidity ^0.8.20; /** * @dev Struct representing token parameters for the OFT send() operation. */ struct SendParam { uint32 dstEid; // Destination endpoint ID. bytes32 to; // Recipient address. uint256 amountLD; // Amount to send in local decimals. uint256 minAmountLD; // Minimum amount to send in local decimals. bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. bytes composeMsg; // The composed message for the send() operation. bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations. } /** * @dev Struct representing OFT limit information. * @dev These amounts can change dynamically and are up the specific oft implementation. */ struct OFTLimit { uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient. uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient. } /** * @dev Struct representing OFT receipt information. */ struct OFTReceipt { uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals. // @dev In non-default implementations, the amountReceivedLD COULD differ from this value. uint256 amountReceivedLD; // Amount of tokens to be received on the remote side. } /** * @dev Struct representing OFT fee details. * @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI. */ struct OFTFeeDetail { int256 feeAmountLD; // Amount of the fee in local decimals. string description; // Description of the fee. } /** * @title IOFT * @dev Interface for the OftChain (OFT) token. * @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well. * @dev This specific interface ID is '0x02e49c2c'. */ interface IOFT { // Custom error messages error InvalidLocalDecimals(); error SlippageExceeded(uint256 amountLD, uint256 minAmountLD); // Events event OFTSent( bytes32 indexed guid, // GUID of the OFT message. uint32 dstEid, // Destination Endpoint ID. address indexed fromAddress, // Address of the sender on the src chain. uint256 amountSentLD, // Amount of tokens sent in local decimals. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); event OFTReceived( bytes32 indexed guid, // GUID of the OFT message. uint32 srcEid, // Source Endpoint ID. address indexed toAddress, // Address of the recipient on the dst chain. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external view returns (bytes4 interfaceId, uint64 version); /** * @notice Retrieves the address of the token associated with the OFT. * @return token The address of the ERC20 token implementation. */ function token() external view returns (address); /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev Allows things like wallet implementers to determine integration requirements, * without understanding the underlying token implementation. */ function approvalRequired() external view returns (bool); /** * @notice Retrieves the shared decimals of the OFT. * @return sharedDecimals The shared decimals of the OFT. */ function sharedDecimals() external view returns (uint8); /** * @notice Provides the fee breakdown and settings data for an OFT. Unused in the default implementation. * @param _sendParam The parameters for the send operation. * @return limit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return receipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory); /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return fee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory); /** * @notice Executes the send() operation. * @param _sendParam The parameters for the send operation. * @param _fee The fee information supplied by the caller. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds from fees etc. on the src. * @return receipt The LayerZero messaging receipt from the send() operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory, OFTReceipt memory); } // File: @layerzerolabs/oft-evm/contracts/libs/OFTMsgCodec.sol pragma solidity ^0.8.20; library OFTMsgCodec { // Offset constants for encoding and decoding OFT messages uint8 private constant SEND_TO_OFFSET = 32; uint8 private constant SEND_AMOUNT_SD_OFFSET = 40; /** * @dev Encodes an OFT LayerZero message. * @param _sendTo The recipient address. * @param _amountShared The amount in shared decimals. * @param _composeMsg The composed message. * @return _msg The encoded message. * @return hasCompose A boolean indicating whether the message has a composed payload. */ function encode( bytes32 _sendTo, uint64 _amountShared, bytes memory _composeMsg ) internal view returns (bytes memory _msg, bool hasCompose) { hasCompose = _composeMsg.length > 0; // @dev Remote chains will want to know the composed function caller ie. msg.sender on the src. _msg = hasCompose ? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg) : abi.encodePacked(_sendTo, _amountShared); } /** * @dev Checks if the OFT message is composed. * @param _msg The OFT message. * @return A boolean indicating whether the message is composed. */ function isComposed(bytes calldata _msg) internal pure returns (bool) { return _msg.length > SEND_AMOUNT_SD_OFFSET; } /** * @dev Retrieves the recipient address from the OFT message. * @param _msg The OFT message. * @return The recipient address. */ function sendTo(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[:SEND_TO_OFFSET]); } /** * @dev Retrieves the amount in shared decimals from the OFT message. * @param _msg The OFT message. * @return The amount in shared decimals. */ function amountSD(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET])); } /** * @dev Retrieves the composed message from the OFT message. * @param _msg The OFT message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[SEND_AMOUNT_SD_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } } // File: @layerzerolabs/oft-evm/contracts/libs/OFTComposeMsgCodec.sol pragma solidity ^0.8.20; library OFTComposeMsgCodec { // Offset constants for decoding composed messages uint8 private constant NONCE_OFFSET = 8; uint8 private constant SRC_EID_OFFSET = 12; uint8 private constant AMOUNT_LD_OFFSET = 44; uint8 private constant COMPOSE_FROM_OFFSET = 76; /** * @dev Encodes a OFT composed message. * @param _nonce The nonce value. * @param _srcEid The source endpoint ID. * @param _amountLD The amount in local decimals. * @param _composeMsg The composed message. * @return _msg The encoded Composed message. */ function encode( uint64 _nonce, uint32 _srcEid, uint256 _amountLD, bytes memory _composeMsg // 0x[composeFrom][composeMsg] ) internal pure returns (bytes memory _msg) { _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg); } /** * @dev Retrieves the nonce for the composed message. * @param _msg The message. * @return The nonce value. */ function nonce(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[:NONCE_OFFSET])); } /** * @dev Retrieves the source endpoint ID for the composed message. * @param _msg The message. * @return The source endpoint ID. */ function srcEid(bytes calldata _msg) internal pure returns (uint32) { return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET])); } /** * @dev Retrieves the amount in local decimals from the composed message. * @param _msg The message. * @return The amount in local decimals. */ function amountLD(bytes calldata _msg) internal pure returns (uint256) { return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET])); } /** * @dev Retrieves the composeFrom value from the composed message. * @param _msg The message. * @return The composeFrom value. */ function composeFrom(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]); } /** * @dev Retrieves the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[COMPOSE_FROM_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } } // File: @layerzerolabs/oft-evm/contracts/OFTCore.sol pragma solidity ^0.8.20; /** * @title OFTCore * @dev Abstract contract for the OftChain (OFT) token. */ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3 { using OFTMsgCodec for bytes; using OFTMsgCodec for bytes32; // @notice Provides a conversion rate when swapping between denominations of SD and LD // - shareDecimals == SD == shared Decimals // - localDecimals == LD == local decimals // @dev Considers that tokens have different decimal amounts on various chains. // @dev eg. // For a token // - locally with 4 decimals --> 1.2345 => uint(12345) // - remotely with 2 decimals --> 1.23 => uint(123) // - The conversion rate would be 10 ** (4 - 2) = 100 // @dev If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the remote, // you can only display 1.23 -> uint(123). // @dev To preserve the dust that would otherwise be lost on that conversion, // we need to unify a denomination that can be represented on ALL chains inside of the OFT mesh uint256 public immutable decimalConversionRate; // @notice Msg types that are used to identify the various OFT operations. // @dev This can be extended in child contracts for non-default oft operations // @dev These values are used in things like combineOptions() in OAppOptionsType3.sol. uint16 public constant SEND = 1; uint16 public constant SEND_AND_CALL = 2; // Address of an optional contract to inspect both 'message' and 'options' address public msgInspector; event MsgInspectorSet(address inspector); /** * @dev Constructor. * @param _localDecimals The decimals of the token on the local chain (this chain). * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(uint8 _localDecimals, address _endpoint, address _delegate) OApp(_endpoint, _delegate) { if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals(); decimalConversionRate = 10 ** (_localDecimals - sharedDecimals()); } /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) { return (type(IOFT).interfaceId, 1); } /** * @dev Retrieves the shared decimals of the OFT. * @return The shared decimals of the OFT. * * @dev Sets an implicit cap on the amount of tokens, over uint64.max() will need some sort of outbound cap / totalSupply cap * Lowest common decimal denominator between chains. * Defaults to 6 decimal places to provide up to 18,446,744,073,709.551615 units (max uint64). * For tokens exceeding this totalSupply(), they will need to override the sharedDecimals function with something smaller. * ie. 4 sharedDecimals would be 1,844,674,407,370,955.1615 */ function sharedDecimals() public view virtual returns (uint8) { return 6; } /** * @dev Sets the message inspector address for the OFT. * @param _msgInspector The address of the message inspector. * * @dev This is an optional contract that can be used to inspect both 'message' and 'options'. * @dev Set it to address(0) to disable it, or set it to a contract address to enable it. */ function setMsgInspector(address _msgInspector) public virtual onlyOwner { msgInspector = _msgInspector; emit MsgInspectorSet(_msgInspector); } /** * @notice Provides the fee breakdown and settings data for an OFT. Unused in the default implementation. * @param _sendParam The parameters for the send operation. * @return oftLimit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return oftReceipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view virtual returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt) { uint256 minAmountLD = 0; // Unused in the default implementation. uint256 maxAmountLD = IERC20(this.token()).totalSupply(); // Unused in the default implementation. oftLimit = OFTLimit(minAmountLD, maxAmountLD); // Unused in the default implementation; reserved for future complex fee details. oftFeeDetails = new OFTFeeDetail[](0); // @dev This is the same as the send() operation, but without the actual send. // - amountSentLD is the amount in local decimals that would be sent from the sender. // - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance. // @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does. (uint256 amountSentLD, uint256 amountReceivedLD) = _debitView( _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); } /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return msgFee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend( SendParam calldata _sendParam, bool _payInLzToken ) external view virtual returns (MessagingFee memory msgFee) { // @dev mock the amount to receive, this is the same operation used in the send(). // The quote is as similar as possible to the actual send() operation. (, uint256 amountReceivedLD) = _debitView(_sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Calculates the LayerZero fee for the send() operation. return _quote(_sendParam.dstEid, message, options, _payInLzToken); } /** * @dev Executes the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for the send operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { return _send(_sendParam, _fee, _refundAddress); } /** * @dev Internal function to execute the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for the send operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { // @dev Applies the token transfers regarding this send() operation. // - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender. // - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance. (uint256 amountSentLD, uint256 amountReceivedLD) = _debit( msg.sender, _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Sends the message to the LayerZero endpoint and returns the LayerZero msg receipt. msgReceipt = _lzSend(_sendParam.dstEid, message, options, _fee, _refundAddress); // @dev Formulate the OFT receipt. oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); emit OFTSent(msgReceipt.guid, _sendParam.dstEid, msg.sender, amountSentLD, amountReceivedLD); } /** * @dev Internal function to build the message and options. * @param _sendParam The parameters for the send() operation. * @param _amountLD The amount in local decimals. * @return message The encoded message. * @return options The encoded options. */ function _buildMsgAndOptions( SendParam calldata _sendParam, uint256 _amountLD ) internal view virtual returns (bytes memory message, bytes memory options) { bool hasCompose; // @dev This generated message has the msg.sender encoded into the payload so the remote knows who the caller is. (message, hasCompose) = OFTMsgCodec.encode( _sendParam.to, _toSD(_amountLD), // @dev Must be include a non empty bytes if you want to compose, EVEN if you dont need it on the remote. // EVEN if you dont require an arbitrary payload to be sent... eg. '0x01' _sendParam.composeMsg ); // @dev Change the msg type depending if its composed or not. uint16 msgType = hasCompose ? SEND_AND_CALL : SEND; // @dev Combine the callers _extraOptions with the enforced options via the OAppOptionsType3. options = combineOptions(_sendParam.dstEid, msgType, _sendParam.extraOptions); // @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector. // @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean address inspector = msgInspector; // caches the msgInspector to avoid potential double storage read if (inspector != address(0)) IOAppMsgInspector(inspector).inspect(message, options); } /** * @dev Internal function to handle the receive on the LayerZero endpoint. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The encoded message. * @dev _executor The address of the executor. * @dev _extraData Additional data. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address /*_executor*/, // @dev unused in the default implementation. bytes calldata /*_extraData*/ // @dev unused in the default implementation. ) internal virtual override { // @dev The src sending chain doesnt know the address length on this chain (potentially non-evm) // Thus everything is bytes32() encoded in flight. address toAddress = _message.sendTo().bytes32ToAddress(); // @dev Credit the amountLD to the recipient and return the ACTUAL amount the recipient received in local decimals uint256 amountReceivedLD = _credit(toAddress, _toLD(_message.amountSD()), _origin.srcEid); if (_message.isComposed()) { // @dev Proprietary composeMsg format for the OFT. bytes memory composeMsg = OFTComposeMsgCodec.encode( _origin.nonce, _origin.srcEid, amountReceivedLD, _message.composeMsg() ); // @dev Stores the lzCompose payload that will be executed in a separate tx. // Standardizes functionality for executing arbitrary contract invocation on some non-evm chains. // @dev The off-chain executor will listen and process the msg based on the src-chain-callers compose options passed. // @dev The index is used when a OApp needs to compose multiple msgs on lzReceive. // For default OFT implementation there is only 1 compose msg per lzReceive, thus its always 0. endpoint.sendCompose(toAddress, _guid, 0 /* the index of the composed message*/, composeMsg); } emit OFTReceived(_guid, _origin.srcEid, toAddress, amountReceivedLD); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual override { _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Check if the peer is considered 'trusted' by the OApp. * @param _eid The endpoint ID to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. * * @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) { return peers[_eid] == _peer; } /** * @dev Internal function to remove dust from the given local decimal amount. * @param _amountLD The amount in local decimals. * @return amountLD The amount after removing dust. * * @dev Prevents the loss of dust when moving amounts between chains with different decimals. * @dev eg. uint(123) with a conversion rate of 100 becomes uint(100). */ function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) { return (_amountLD / decimalConversionRate) * decimalConversionRate; } /** * @dev Internal function to convert an amount from shared decimals into local decimals. * @param _amountSD The amount in shared decimals. * @return amountLD The amount in local decimals. */ function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) { return _amountSD * decimalConversionRate; } /** * @dev Internal function to convert an amount from local decimals into shared decimals. * @param _amountLD The amount in local decimals. * @return amountSD The amount in shared decimals. */ function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) { return uint64(_amountLD / decimalConversionRate); } /** * @dev Internal function to mock the amount mutation from a OFT debit() operation. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @dev _dstEid The destination endpoint ID. * @return amountSentLD The amount sent, in local decimals. * @return amountReceivedLD The amount to be received on the remote chain, in local decimals. * * @dev This is where things like fees would be calculated and deducted from the amount to be received on the remote. */ function _debitView( uint256 _amountLD, uint256 _minAmountLD, uint32 /*_dstEid*/ ) internal view virtual returns (uint256 amountSentLD, uint256 amountReceivedLD) { // @dev Remove the dust so nothing is lost on the conversion between chains with different decimals for the token. amountSentLD = _removeDust(_amountLD); // @dev The amount to send is the same as amount received in the default implementation. amountReceivedLD = amountSentLD; // @dev Check for slippage. if (amountReceivedLD < _minAmountLD) { revert SlippageExceeded(amountReceivedLD, _minAmountLD); } } /** * @dev Internal function to perform a debit operation. * @param _from The address to debit. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination endpoint ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual returns (uint256 amountSentLD, uint256 amountReceivedLD); /** * @dev Internal function to perform a credit operation. * @param _to The address to credit. * @param _amountLD The amount to credit in local decimals. * @param _srcEid The source endpoint ID. * @return amountReceivedLD The amount ACTUALLY received in local decimals. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _credit( address _to, uint256 _amountLD, uint32 _srcEid ) internal virtual returns (uint256 amountReceivedLD); } // File: @layerzerolabs/oft-evm/contracts/OFT.sol pragma solidity ^0.8.20; /** * @title OFT Contract * @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract. */ abstract contract OFT is OFTCore, ERC20 { /** * @dev Constructor for the OFT contract. * @param _name The name of the OFT. * @param _symbol The symbol of the OFT. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _delegate) {} /** * @dev Retrieves the address of the underlying ERC20 implementation. * @return The address of the OFT token. * * @dev In the case of OFT, address(this) and erc20 are the same contract. */ function token() public view returns (address) { return address(this); } /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev In the case of OFT where the contract IS the token, approval is NOT required. */ function approvalRequired() external pure virtual returns (bool) { return false; } /** * @dev Burns tokens from the sender's specified balance. * @param _from The address to debit the tokens from. * @param _amountLD The amount of tokens to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination chain ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid); // @dev In NON-default OFT, amountSentLD could be 100, with a 10% fee, the amountReceivedLD amount is 90, // therefore amountSentLD CAN differ from amountReceivedLD. // @dev Default OFT burns on src. _burn(_from, amountSentLD); } /** * @dev Credits tokens to the specified address. * @param _to The address to credit the tokens to. * @param _amountLD The amount of tokens to credit in local decimals. * @dev _srcEid The source chain ID. * @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals. */ function _credit( address _to, uint256 _amountLD, uint32 /*_srcEid*/ ) internal virtual override returns (uint256 amountReceivedLD) { if (_to == address(0x0)) _to = address(0xdead); // _mint(...) does not support address(0x0) // @dev Default OFT mints on dst. _mint(_to, _amountLD); // @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD. return _amountLD; } } // File: Token/Fate Adventure Token.sol pragma solidity ^0.8.22; /// @notice OFT is an ERC-20 token that extends the OFTCore contract. contract FateAdventureToken is OFT { uint256 public constant MAX_SUPPLY = 10_000_000 * 10**18; // Fixed supply: 10 million tokens (18 decimals) constructor( ) OFT("Fate Adventure", //token name "FA", //token symbol 0x6F475642a6e85809B1c36Fa62763669b1b48DD5B, //lzEndpoint msg.sender //deligate ) Ownable( msg.sender //owner ) { _mint(msg.sender, MAX_SUPPLY); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_CALL","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"}],"name":"quoteOFT","outputs":[{"components":[{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"uint256","name":"maxAmountLD","type":"uint256"}],"internalType":"struct OFTLimit","name":"oftLimit","type":"tuple"},{"components":[{"internalType":"int256","name":"feeAmountLD","type":"int256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct OFTFeeDetail[]","name":"oftFeeDetails","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"send","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405234801562000010575f80fd5b506040518060400160405280600e81526020017f4661746520416476656e747572650000000000000000000000000000000000008152506040518060400160405280600281526020017f4641000000000000000000000000000000000000000000000000000000000000815250736f475642a6e85809b1c36fa62763669b1b48dd5b338383620000a56200030d60201b60201c565b848481818181335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200011f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001169190620006d2565b60405180910390fd5b62000130816200031560201b60201c565b508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620001cb576040517fb586360400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60805173ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b8152600401620002089190620006d2565b5f604051808303815f87803b15801562000220575f80fd5b505af115801562000233573d5f803e3d5ffd5b50505050505050506200024b620003d660201b60201c565b60ff168360ff1610156200028b576040517f1e9714b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200029b620003d660201b60201c565b83620002a8919062000726565b600a620002b69190620008ba565b60a081815250505050508160089081620002d1919062000b65565b508060099081620002e3919062000b65565b5050505050505062000307336a084595161401484a000000620003de60201b60201c565b62000cea565b5f6012905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6006905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000451575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401620004489190620006d2565b60405180910390fd5b620004645f83836200046860201b60201c565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620004bc578060075f828254620004af919062000c49565b925050819055506200058f565b5f60055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101562000549578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401620005409392919062000c94565b60405180910390fd5b81810360055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620005d8578060075f828254039250508190555062000623565b8060055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000682919062000ccf565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620006ba826200068f565b9050919050565b620006cc81620006ae565b82525050565b5f602082019050620006e75f830184620006c1565b92915050565b5f60ff82169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6200073282620006ed565b91506200073f83620006ed565b9250828203905060ff8111156200075b576200075a620006f9565b5b92915050565b5f8160011c9050919050565b5f808291508390505b6001851115620007be57808604811115620007965762000795620006f9565b5b6001851615620007a65780820291505b8081029050620007b68562000761565b945062000776565b94509492505050565b5f82620007d85760019050620008aa565b81620007e7575f9050620008aa565b81600181146200080057600281146200080b5762000841565b6001915050620008aa565b60ff84111562000820576200081f620006f9565b5b8360020a9150848211156200083a5762000839620006f9565b5b50620008aa565b5060208310610133831016604e8410600b84101617156200087b5782820a905083811115620008755762000874620006f9565b5b620008aa565b6200088a84848460016200076d565b92509050818404811115620008a457620008a3620006f9565b5b81810290505b9392505050565b5f819050919050565b5f620008c682620008b1565b9150620008d383620006ed565b9250620009027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620007c7565b905092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200098657607f821691505b6020821081036200099c576200099b62000941565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830262000a007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620009c3565b62000a0c8683620009c3565b95508019841693508086168417925050509392505050565b5f819050919050565b5f62000a4d62000a4762000a4184620008b1565b62000a24565b620008b1565b9050919050565b5f819050919050565b62000a688362000a2d565b62000a8062000a778262000a54565b848454620009cf565b825550505050565b5f90565b62000a9662000a88565b62000aa381848462000a5d565b505050565b5b8181101562000aca5762000abe5f8262000a8c565b60018101905062000aa9565b5050565b601f82111562000b195762000ae381620009a2565b62000aee84620009b4565b8101602085101562000afe578190505b62000b1662000b0d85620009b4565b83018262000aa8565b50505b505050565b5f82821c905092915050565b5f62000b3b5f198460080262000b1e565b1980831691505092915050565b5f62000b55838362000b2a565b9150826002028217905092915050565b62000b70826200090a565b67ffffffffffffffff81111562000b8c5762000b8b62000914565b5b62000b9882546200096e565b62000ba582828562000ace565b5f60209050601f83116001811462000bdb575f841562000bc6578287015190505b62000bd2858262000b48565b86555062000c41565b601f19841662000beb86620009a2565b5f5b8281101562000c145784890151825560018201915060208501945060208101905062000bed565b8683101562000c34578489015162000c30601f89168262000b2a565b8355505b6001600288020188555050505b505050505050565b5f62000c5582620008b1565b915062000c6283620008b1565b925082820190508082111562000c7d5762000c7c620006f9565b5b92915050565b62000c8e81620008b1565b82525050565b5f60608201905062000ca95f830186620006c1565b62000cb8602083018562000c83565b62000cc7604083018462000c83565b949350505050565b5f60208201905062000ce45f83018462000c83565b92915050565b60805160a05161513962000d595f395f81816111b10152818161258e015281816125af0152818161265301526129a201525f8181610cc201528181610fb20152818161165301528181611a9d01528181611f9901528181612a9c01528181612cee0152612de601526151395ff3fe60806040526004361061025b575f3560e01c8063715018a611610143578063bb0b6a53116100b5578063d045a0dc11610079578063d045a0dc1461091c578063d424388514610938578063dd62ed3e14610960578063f2fde38b1461099c578063fc0c546a146109c4578063ff7bd03d146109ee5761025b565b8063bb0b6a531461082f578063bc70b3541461086b578063bd815db0146108a7578063c7c7f5b3146108c3578063ca5eb5e1146108f45761025b565b806395d89b411161010757806395d89b4114610723578063963efcaa1461074d5780639f68b96414610777578063a9059cbb146107a1578063b731ea0a146107dd578063b98bd070146108075761025b565b8063715018a6146106415780637d25a05e1461065757806382413eac14610693578063857749b0146106cf5780638da5cb5b146106f95761025b565b806323b872dd116101dc57806352ae2879116101a057806352ae2879146105115780635535d4611461053b5780635a0dfe4d146105775780635e280f11146105b35780636fc1b31e146105dd57806370a08231146106055761025b565b806323b872dd1461041d578063313ce5671461045957806332cb6b0c146104835780633400288b146104ad5780633b6f743b146104d55761025b565b8063134d4f2511610223578063134d4f2514610349578063156a0d0f1461037357806317442b701461039e57806318160ddd146103c95780631f5e1334146103f35761025b565b806306fdde031461025f578063095ea7b3146102895780630d35b415146102c5578063111ecdad1461030357806313137d651461032d575b5f80fd5b34801561026a575f80fd5b50610273610a2a565b604051610280919061306b565b60405180910390f35b348015610294575f80fd5b506102af60048036038101906102aa9190613129565b610aba565b6040516102bc9190613181565b60405180910390f35b3480156102d0575f80fd5b506102eb60048036038101906102e691906131bc565b610adc565b6040516102fa939291906133c1565b60405180910390f35b34801561030e575f80fd5b50610317610c84565b604051610324919061340c565b60405180910390f35b610347600480360381019061034291906134d7565b610ca9565b005b348015610354575f80fd5b5061035d610dc9565b60405161036a91906135aa565b60405180910390f35b34801561037e575f80fd5b50610387610dce565b60405161039592919061361f565b60405180910390f35b3480156103a9575f80fd5b506103b2610dfb565b6040516103c0929190613646565b60405180910390f35b3480156103d4575f80fd5b506103dd610e09565b6040516103ea919061367c565b60405180910390f35b3480156103fe575f80fd5b50610407610e12565b60405161041491906135aa565b60405180910390f35b348015610428575f80fd5b50610443600480360381019061043e9190613695565b610e17565b6040516104509190613181565b60405180910390f35b348015610464575f80fd5b5061046d610e45565b60405161047a9190613700565b60405180910390f35b34801561048e575f80fd5b50610497610e4d565b6040516104a4919061367c565b60405180910390f35b3480156104b8575f80fd5b506104d360048036038101906104ce9190613752565b610e5c565b005b3480156104e0575f80fd5b506104fb60048036038101906104f691906137ba565b610e72565b6040516105089190613841565b60405180910390f35b34801561051c575f80fd5b50610525610eda565b604051610532919061340c565b60405180910390f35b348015610546575f80fd5b50610561600480360381019061055c9190613884565b610ee1565b60405161056e9190613914565b60405180910390f35b348015610582575f80fd5b5061059d60048036038101906105989190613752565b610f87565b6040516105aa9190613181565b60405180910390f35b3480156105be575f80fd5b506105c7610fb0565b6040516105d4919061398f565b60405180910390f35b3480156105e8575f80fd5b5061060360048036038101906105fe91906139a8565b610fd4565b005b348015610610575f80fd5b5061062b600480360381019061062691906139a8565b611056565b604051610638919061367c565b60405180910390f35b34801561064c575f80fd5b5061065561109c565b005b348015610662575f80fd5b5061067d60048036038101906106789190613752565b6110af565b60405161068a91906139d3565b60405180910390f35b34801561069e575f80fd5b506106b960048036038101906106b491906139ec565b6110b6565b6040516106c69190613181565b60405180910390f35b3480156106da575f80fd5b506106e36110f0565b6040516106f09190613700565b60405180910390f35b348015610704575f80fd5b5061070d6110f8565b60405161071a919061340c565b60405180910390f35b34801561072e575f80fd5b5061073761111f565b604051610744919061306b565b60405180910390f35b348015610758575f80fd5b506107616111af565b60405161076e919061367c565b60405180910390f35b348015610782575f80fd5b5061078b6111d3565b6040516107989190613181565b60405180910390f35b3480156107ac575f80fd5b506107c760048036038101906107c29190613129565b6111d7565b6040516107d49190613181565b60405180910390f35b3480156107e8575f80fd5b506107f16111f9565b6040516107fe919061340c565b60405180910390f35b348015610812575f80fd5b5061082d60048036038101906108289190613ab2565b61121e565b005b34801561083a575f80fd5b5061085560048036038101906108509190613afd565b61123f565b6040516108629190613b37565b60405180910390f35b348015610876575f80fd5b50610891600480360381019061088c9190613b50565b611254565b60405161089e9190613914565b60405180910390f35b6108c160048036038101906108bc9190613c16565b611456565b005b6108dd60048036038101906108d89190613c7f565b611622565b6040516108eb929190613d76565b60405180910390f35b3480156108ff575f80fd5b5061091a600480360381019061091591906139a8565b611649565b005b610936600480360381019061093191906134d7565b6116da565b005b348015610943575f80fd5b5061095e600480360381019061095991906139a8565b611757565b005b34801561096b575f80fd5b5061098660048036038101906109819190613d9d565b6117d9565b604051610993919061367c565b60405180910390f35b3480156109a7575f80fd5b506109c260048036038101906109bd91906139a8565b61185b565b005b3480156109cf575f80fd5b506109d86118df565b6040516109e5919061340c565b60405180910390f35b3480156109f9575f80fd5b50610a146004803603810190610a0f9190613ddb565b6118e6565b604051610a219190613181565b60405180910390f35b606060088054610a3990613e33565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6590613e33565b8015610ab05780601f10610a8757610100808354040283529160200191610ab0565b820191905f5260205f20905b815481529060010190602001808311610a9357829003601f168201915b5050505050905090565b5f80610ac4611923565b9050610ad181858561192a565b600191505092915050565b610ae4612f4e565b6060610aee612f66565b5f803073ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190613e77565b73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc99190613eb6565b905060405180604001604052808381526020018281525094505f67ffffffffffffffff811115610bfc57610bfb613ee1565b5b604051908082528060200260200182016040528015610c3557816020015b610c22612f7e565b815260200190600190039081610c1a5790505b5093505f80610c5e886040013589606001358a5f016020810190610c599190613afd565b61193c565b915091506040518060400160405280838152602001828152509450505050509193909250565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614610d3957336040517f91ac5e4f000000000000000000000000000000000000000000000000000000008152600401610d30919061340c565b60405180910390fd5b8660200135610d58885f016020810190610d539190613afd565b61199b565b14610db157865f016020810190610d6f9190613afd565b87602001356040517fc26bebcc000000000000000000000000000000000000000000000000000000008152600401610da8929190613f1d565b60405180910390fd5b610dc087878787878787611a0c565b50505050505050565b600281565b5f807f02e49c2c000000000000000000000000000000000000000000000000000000006001915091509091565b5f8060016002915091509091565b5f600754905090565b600181565b5f80610e21611923565b9050610e2e858285611b96565b610e39858585611c28565b60019150509392505050565b5f6012905090565b6a084595161401484a00000081565b610e64611d18565b610e6e8282611d9f565b5050565b610e7a612f97565b5f610e9f84604001358560600135865f016020810190610e9a9190613afd565b61193c565b9150505f80610eae8684611dfe565b91509150610ecf865f016020810190610ec79190613afd565b838388611f8f565b935050505092915050565b5f30905090565b6003602052815f5260405f20602052805f5260405f205f91509150508054610f0890613e33565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3490613e33565b8015610f7f5780601f10610f5657610100808354040283529160200191610f7f565b820191905f5260205f20905b815481529060010190602001808311610f6257829003601f168201915b505050505081565b5f8160015f8563ffffffff1663ffffffff1681526020019081526020015f205414905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b610fdc611d18565b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d44141978160405161104b919061340c565b60405180910390a150565b5f60055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6110a4611d18565b6110ad5f612070565b565b5f92915050565b5f3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b5f6006905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606009805461112e90613e33565b80601f016020809104026020016040519081016040528092919081815260200182805461115a90613e33565b80156111a55780601f1061117c576101008083540402835291602001916111a5565b820191905f5260205f20905b81548152906001019060200180831161118857829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f90565b5f806111e1611923565b90506111ee818585611c28565b600191505092915050565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611226611d18565b61123b8282906112369190614175565b612131565b5050565b6001602052805f5260405f205f915090505481565b60605f60035f8763ffffffff1663ffffffff1681526020019081526020015f205f8661ffff1661ffff1681526020019081526020015f20805461129690613e33565b80601f01602080910402602001604051908101604052809291908181526020018280546112c290613e33565b801561130d5780601f106112e45761010080835404028352916020019161130d565b820191905f5260205f20905b8154815290600101906020018083116112f057829003601f168201915b505050505090505f8151036113685783838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505091505061144e565b5f848490500361137b578091505061144e565b6002848490501061140f576113d284848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612246565b80848460029080926113e693929190614191565b6040516020016113f893929190614229565b60405160208183030381529060405291505061144e565b83836040517f9a6d49cd00000000000000000000000000000000000000000000000000000000815260040161144592919061427a565b60405180910390fd5b949350505050565b5f5b8282905081101561157557368383838181106114775761147661429c565b5b905060200281019061148991906142d5565b90506114ae815f015f0160208101906114a29190613afd565b825f0160200135610f87565b6114b85750611568565b3073ffffffffffffffffffffffffffffffffffffffff1663d045a0dc8260c00135835f018460a00135858061010001906114f291906142fd565b8760e001602081019061150591906139a8565b8880610120019061151691906142fd565b6040518963ffffffff1660e01b81526004016115389796959493929190614432565b5f604051808303818588803b15801561154f575f80fd5b505af1158015611561573d5f803e3d5ffd5b5050505050505b8080600101915050611458565b503373ffffffffffffffffffffffffffffffffffffffff16638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa1580156115be573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906115e69190614503565b6040517f8351eea70000000000000000000000000000000000000000000000000000000081526004016116199190613914565b60405180910390fd5b61162a612faf565b611632612f66565b61163d85858561229f565b91509150935093915050565b611651611d18565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b81526004016116aa919061340c565b5f604051808303815f87803b1580156116c1575f80fd5b505af11580156116d3573d5f803e3d5ffd5b5050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461173f576040517f14d4a4e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61174e878787878787876123a4565b50505050505050565b61175f611d18565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760816040516117ce919061340c565b60405180910390a150565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b611863611d18565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118d3575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016118ca919061340c565b60405180910390fd5b6118dc81612070565b50565b5f30905090565b5f816020013560015f845f0160208101906119019190613afd565b63ffffffff1663ffffffff1681526020019081526020015f2054149050919050565b5f33905090565b61193783838360016123bc565b505050565b5f806119478561258b565b9150819050838110156119935780846040517f71c4efed00000000000000000000000000000000000000000000000000000000815260040161198a92919061454a565b60405180910390fd5b935093915050565b5f8060015f8463ffffffff1663ffffffff1681526020019081526020015f205490505f801b8103611a0357826040517ff6ff4fb70000000000000000000000000000000000000000000000000000000081526004016119fa9190614571565b60405180910390fd5b80915050919050565b5f611a1f611a1a87876125ea565b612614565b90505f611a4f82611a38611a338a8a61261f565b612650565b8b5f016020810190611a4a9190613afd565b61268e565b9050611a5b87876126dc565b15611b29575f611a998a6040016020810190611a77919061458a565b8b5f016020810190611a899190613afd565b84611a948c8c6126ef565b612751565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637cb59012848b5f856040518563ffffffff1660e01b8152600401611afa94939291906145ee565b5f604051808303815f87803b158015611b11575f80fd5b505af1158015611b23573d5f803e3d5ffd5b50505050505b8173ffffffffffffffffffffffffffffffffffffffff16887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c8b5f016020810190611b749190613afd565b84604051611b83929190614638565b60405180910390a3505050505050505050565b5f611ba184846117d9565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c225781811015611c13578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611c0a9392919061465f565b60405180910390fd5b611c2184848484035f6123bc565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c98575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611c8f919061340c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d08575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611cff919061340c565b60405180910390fd5b611d13838383612783565b505050565b611d20611923565b73ffffffffffffffffffffffffffffffffffffffff16611d3e6110f8565b73ffffffffffffffffffffffffffffffffffffffff1614611d9d57611d61611923565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611d94919061340c565b60405180910390fd5b565b8060015f8463ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b8282604051611df2929190613f1d565b60405180910390a15050565b6060805f611e6a8560200135611e138661299f565b878060a00190611e2391906142fd565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506129d3565b80925081945050505f81611e7f576001611e82565b60025b9050611eaf865f016020810190611e999190613afd565b82888060800190611eaa91906142fd565b611254565b92505f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f85578073ffffffffffffffffffffffffffffffffffffffff1663043a78eb86866040518363ffffffff1660e01b8152600401611f44929190614694565b602060405180830381865afa158015611f5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8391906146dd565b505b5050509250929050565b611f97612f97565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ddc28c586040518060a001604052808863ffffffff168152602001611ff38961199b565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016120289291906147d9565b6040805180830381865afa158015612042573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120669190614854565b9050949350505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5b815181101561220b576121638282815181106121525761215161429c565b5b602002602001015160400151612246565b8181815181106121765761217561429c565b5b60200260200101516040015160035f8484815181106121985761219761429c565b5b60200260200101515f015163ffffffff1663ffffffff1681526020019081526020015f205f8484815181106121d0576121cf61429c565b5b60200260200101516020015161ffff1661ffff1681526020019081526020015f2090816121fd9190614a13565b508080600101915050612133565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748160405161223b9190614bf9565b60405180910390a150565b5f60028201519050600361ffff168161ffff161461229b57816040517f9a6d49cd0000000000000000000000000000000000000000000000000000000081526004016122929190613914565b60405180910390fd5b5050565b6122a7612faf565b6122af612f66565b5f806122d633886040013589606001358a5f0160208101906122d19190613afd565b612a41565b915091505f806122e68984611dfe565b91509150612318895f0160208101906122ff9190613afd565b83838b8036038101906123129190614c66565b8b612a69565b955060405180604001604052808581526020018481525094503373ffffffffffffffffffffffffffffffffffffffff16865f01517f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a8b5f01602081019061237f9190613afd565b878760405161239093929190614c91565b60405180910390a350505050935093915050565b6123b387878787878787611a0c565b50505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361242c575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401612423919061340c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361249c575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401612493919061340c565b60405180910390fd5b8160065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015612585578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161257c919061367c565b60405180910390a35b50505050565b5f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000836125d99190614d20565b6125e39190614d50565b9050919050565b5f82825f90602060ff169261260193929190614191565b9061260c9190614d9b565b905092915050565b5f815f1c9050919050565b5f8282602060ff1690602860ff169261263a93929190614191565b906126459190614e24565b60c01c905092915050565b5f7f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff166126879190614d50565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036126c85761dead93505b6126d28484612b7f565b8290509392505050565b5f602860ff168383905011905092915050565b60608282602860ff1690809261270793929190614191565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050905092915050565b60608484848460405160200161276a9493929190614f0a565b6040516020818303038152906040529050949350505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127d3578060075f8282546127c79190614f53565b925050819055506128a3565b5f60055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561285d578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016128549392919061465f565b60405180910390fd5b81810360055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036128ea578060075f8282540392505081905550612935565b8060055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612992919061367c565b60405180910390a3505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000826129cc9190614d20565b9050919050565b60605f80835111905080612a085784846040516020016129f4929190614fa6565b604051602081830303815290604052612a37565b8484612a1333612bfe565b85604051602001612a279493929190614fd1565b6040516020818303038152906040525b9150935093915050565b5f80612a4e85858561193c565b8092508193505050612a608683612c1f565b94509492505050565b612a71612faf565b5f612a7e845f0151612c9e565b90505f84602001511115612a9a57612a998460200151612ceb565b5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632637a450826040518060a001604052808b63ffffffff168152602001612af78c61199b565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612b329291906147d9565b60806040518083038185885af1158015612b4e573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612b7391906150a3565b91505095945050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612bef575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401612be6919061340c565b60405180910390fd5b612bfa5f8383612783565b5050565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c8f575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401612c86919061340c565b60405180910390fd5b612c9a825f83612783565b5050565b5f813414612ce357346040517f9f704120000000000000000000000000000000000000000000000000000000008152600401612cda919061367c565b60405180910390fd5b819050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d799190613e77565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612de0576040517f5373352a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e2d337f0000000000000000000000000000000000000000000000000000000000000000848473ffffffffffffffffffffffffffffffffffffffff16612e31909392919063ffffffff16565b5050565b612ead848573ffffffffffffffffffffffffffffffffffffffff166323b872dd868686604051602401612e66939291906150ce565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612eb3565b50505050565b5f8060205f8451602086015f885af180612ed2576040513d5f823e3d81fd5b3d92505f519150505f8214612eeb576001811415612f06565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15612f4857836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401612f3f919061340c565b60405180910390fd5b50505050565b60405180604001604052805f81526020015f81525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052805f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180606001604052805f80191681526020015f67ffffffffffffffff168152602001612fdb612f97565b81525090565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613018578082015181840152602081019050612ffd565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61303d82612fe1565b6130478185612feb565b9350613057818560208601612ffb565b61306081613023565b840191505092915050565b5f6020820190508181035f8301526130838184613033565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6130c58261309c565b9050919050565b6130d5816130bb565b81146130df575f80fd5b50565b5f813590506130f0816130cc565b92915050565b5f819050919050565b613108816130f6565b8114613112575f80fd5b50565b5f81359050613123816130ff565b92915050565b5f806040838503121561313f5761313e613094565b5b5f61314c858286016130e2565b925050602061315d85828601613115565b9150509250929050565b5f8115159050919050565b61317b81613167565b82525050565b5f6020820190506131945f830184613172565b92915050565b5f80fd5b5f60e082840312156131b3576131b261319a565b5b81905092915050565b5f602082840312156131d1576131d0613094565b5b5f82013567ffffffffffffffff8111156131ee576131ed613098565b5b6131fa8482850161319e565b91505092915050565b61320c816130f6565b82525050565b604082015f8201516132265f850182613203565b5060208201516132396020850182613203565b50505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f819050919050565b61327a81613268565b82525050565b5f82825260208201905092915050565b5f61329a82612fe1565b6132a48185613280565b93506132b4818560208601612ffb565b6132bd81613023565b840191505092915050565b5f604083015f8301516132dd5f860182613271565b50602083015184820360208601526132f58282613290565b9150508091505092915050565b5f61330d83836132c8565b905092915050565b5f602082019050919050565b5f61332b8261323f565b6133358185613249565b93508360208202850161334785613259565b805f5b8581101561338257848403895281516133638582613302565b945061336e83613315565b925060208a0199505060018101905061334a565b50829750879550505050505092915050565b604082015f8201516133a85f850182613203565b5060208201516133bb6020850182613203565b50505050565b5f60a0820190506133d45f830186613212565b81810360408301526133e68185613321565b90506133f56060830184613394565b949350505050565b613406816130bb565b82525050565b5f60208201905061341f5f8301846133fd565b92915050565b5f6060828403121561343a5761343961319a565b5b81905092915050565b5f819050919050565b61345581613443565b811461345f575f80fd5b50565b5f813590506134708161344c565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261349757613496613476565b5b8235905067ffffffffffffffff8111156134b4576134b361347a565b5b6020830191508360018202830111156134d0576134cf61347e565b5b9250929050565b5f805f805f805f60e0888a0312156134f2576134f1613094565b5b5f6134ff8a828b01613425565b97505060606135108a828b01613462565b965050608088013567ffffffffffffffff81111561353157613530613098565b5b61353d8a828b01613482565b955095505060a06135508a828b016130e2565b93505060c088013567ffffffffffffffff81111561357157613570613098565b5b61357d8a828b01613482565b925092505092959891949750929550565b5f61ffff82169050919050565b6135a48161358e565b82525050565b5f6020820190506135bd5f83018461359b565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6135f7816135c3565b82525050565b5f67ffffffffffffffff82169050919050565b613619816135fd565b82525050565b5f6040820190506136325f8301856135ee565b61363f6020830184613610565b9392505050565b5f6040820190506136595f830185613610565b6136666020830184613610565b9392505050565b613676816130f6565b82525050565b5f60208201905061368f5f83018461366d565b92915050565b5f805f606084860312156136ac576136ab613094565b5b5f6136b9868287016130e2565b93505060206136ca868287016130e2565b92505060406136db86828701613115565b9150509250925092565b5f60ff82169050919050565b6136fa816136e5565b82525050565b5f6020820190506137135f8301846136f1565b92915050565b5f63ffffffff82169050919050565b61373181613719565b811461373b575f80fd5b50565b5f8135905061374c81613728565b92915050565b5f806040838503121561376857613767613094565b5b5f6137758582860161373e565b925050602061378685828601613462565b9150509250929050565b61379981613167565b81146137a3575f80fd5b50565b5f813590506137b481613790565b92915050565b5f80604083850312156137d0576137cf613094565b5b5f83013567ffffffffffffffff8111156137ed576137ec613098565b5b6137f98582860161319e565b925050602061380a858286016137a6565b9150509250929050565b604082015f8201516138285f850182613203565b50602082015161383b6020850182613203565b50505050565b5f6040820190506138545f830184613814565b92915050565b6138638161358e565b811461386d575f80fd5b50565b5f8135905061387e8161385a565b92915050565b5f806040838503121561389a57613899613094565b5b5f6138a78582860161373e565b92505060206138b885828601613870565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f6138e6826138c2565b6138f081856138cc565b9350613900818560208601612ffb565b61390981613023565b840191505092915050565b5f6020820190508181035f83015261392c81846138dc565b905092915050565b5f819050919050565b5f61395761395261394d8461309c565b613934565b61309c565b9050919050565b5f6139688261393d565b9050919050565b5f6139798261395e565b9050919050565b6139898161396f565b82525050565b5f6020820190506139a25f830184613980565b92915050565b5f602082840312156139bd576139bc613094565b5b5f6139ca848285016130e2565b91505092915050565b5f6020820190506139e65f830184613610565b92915050565b5f805f8060a08587031215613a0457613a03613094565b5b5f613a1187828801613425565b945050606085013567ffffffffffffffff811115613a3257613a31613098565b5b613a3e87828801613482565b93509350506080613a51878288016130e2565b91505092959194509250565b5f8083601f840112613a7257613a71613476565b5b8235905067ffffffffffffffff811115613a8f57613a8e61347a565b5b602083019150836020820283011115613aab57613aaa61347e565b5b9250929050565b5f8060208385031215613ac857613ac7613094565b5b5f83013567ffffffffffffffff811115613ae557613ae4613098565b5b613af185828601613a5d565b92509250509250929050565b5f60208284031215613b1257613b11613094565b5b5f613b1f8482850161373e565b91505092915050565b613b3181613443565b82525050565b5f602082019050613b4a5f830184613b28565b92915050565b5f805f8060608587031215613b6857613b67613094565b5b5f613b758782880161373e565b9450506020613b8687828801613870565b935050604085013567ffffffffffffffff811115613ba757613ba6613098565b5b613bb387828801613482565b925092505092959194509250565b5f8083601f840112613bd657613bd5613476565b5b8235905067ffffffffffffffff811115613bf357613bf261347a565b5b602083019150836020820283011115613c0f57613c0e61347e565b5b9250929050565b5f8060208385031215613c2c57613c2b613094565b5b5f83013567ffffffffffffffff811115613c4957613c48613098565b5b613c5585828601613bc1565b92509250509250929050565b5f60408284031215613c7657613c7561319a565b5b81905092915050565b5f805f60808486031215613c9657613c95613094565b5b5f84013567ffffffffffffffff811115613cb357613cb2613098565b5b613cbf8682870161319e565b9350506020613cd086828701613c61565b9250506060613ce1868287016130e2565b9150509250925092565b613cf481613443565b82525050565b613d03816135fd565b82525050565b604082015f820151613d1d5f850182613203565b506020820151613d306020850182613203565b50505050565b608082015f820151613d4a5f850182613ceb565b506020820151613d5d6020850182613cfa565b506040820151613d706040850182613d09565b50505050565b5f60c082019050613d895f830185613d36565b613d966080830184613394565b9392505050565b5f8060408385031215613db357613db2613094565b5b5f613dc0858286016130e2565b9250506020613dd1858286016130e2565b9150509250929050565b5f60608284031215613df057613def613094565b5b5f613dfd84828501613425565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680613e4a57607f821691505b602082108103613e5d57613e5c613e06565b5b50919050565b5f81519050613e71816130cc565b92915050565b5f60208284031215613e8c57613e8b613094565b5b5f613e9984828501613e63565b91505092915050565b5f81519050613eb0816130ff565b92915050565b5f60208284031215613ecb57613eca613094565b5b5f613ed884828501613ea2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613f1781613719565b82525050565b5f604082019050613f305f830185613f0e565b613f3d6020830184613b28565b9392505050565b613f4d82613023565b810181811067ffffffffffffffff82111715613f6c57613f6b613ee1565b5b80604052505050565b5f613f7e61308b565b9050613f8a8282613f44565b919050565b5f67ffffffffffffffff821115613fa957613fa8613ee1565b5b602082029050602081019050919050565b5f80fd5b5f80fd5b5f80fd5b5f67ffffffffffffffff821115613fe057613fdf613ee1565b5b613fe982613023565b9050602081019050919050565b828183375f83830152505050565b5f61401661401184613fc6565b613f75565b90508281526020810184848401111561403257614031613fc2565b5b61403d848285613ff6565b509392505050565b5f82601f83011261405957614058613476565b5b8135614069848260208601614004565b91505092915050565b5f6060828403121561408757614086613fba565b5b6140916060613f75565b90505f6140a08482850161373e565b5f8301525060206140b384828501613870565b602083015250604082013567ffffffffffffffff8111156140d7576140d6613fbe565b5b6140e384828501614045565b60408301525092915050565b5f6141016140fc84613f8f565b613f75565b905080838252602082019050602084028301858111156141245761412361347e565b5b835b8181101561416b57803567ffffffffffffffff81111561414957614148613476565b5b8086016141568982614072565b85526020850194505050602081019050614126565b5050509392505050565b5f6141813684846140ef565b905092915050565b5f80fd5b5f80fd5b5f80858511156141a4576141a3614189565b5b838611156141b5576141b461418d565b5b6001850283019150848603905094509492505050565b5f81905092915050565b5f6141df826138c2565b6141e981856141cb565b93506141f9818560208601612ffb565b80840191505092915050565b5f61421083856141cb565b935061421d838584613ff6565b82840190509392505050565b5f61423482866141d5565b9150614241828486614205565b9150819050949350505050565b5f61425983856138cc565b9350614266838584613ff6565b61426f83613023565b840190509392505050565b5f6020820190508181035f83015261429381848661424e565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f82356001610140038336030381126142f1576142f06142c9565b5b80830191505092915050565b5f8083356001602003843603038112614319576143186142c9565b5b80840192508235915067ffffffffffffffff82111561433b5761433a6142cd565b5b602083019250600182023603831315614357576143566142d1565b5b509250929050565b5f61436d602084018461373e565b905092915050565b61437e81613719565b82525050565b5f6143926020840184613462565b905092915050565b6143a3816135fd565b81146143ad575f80fd5b50565b5f813590506143be8161439a565b92915050565b5f6143d260208401846143b0565b905092915050565b606082016143ea5f83018361435f565b6143f65f850182614375565b506144046020830183614384565b6144116020850182613ceb565b5061441f60408301836143c4565b61442c6040850182613cfa565b50505050565b5f60e0820190506144455f83018a6143da565b6144526060830189613b28565b818103608083015261446581878961424e565b905061447460a08301866133fd565b81810360c083015261448781848661424e565b905098975050505050505050565b5f6144a76144a284613fc6565b613f75565b9050828152602081018484840111156144c3576144c2613fc2565b5b6144ce848285612ffb565b509392505050565b5f82601f8301126144ea576144e9613476565b5b81516144fa848260208601614495565b91505092915050565b5f6020828403121561451857614517613094565b5b5f82015167ffffffffffffffff81111561453557614534613098565b5b614541848285016144d6565b91505092915050565b5f60408201905061455d5f83018561366d565b61456a602083018461366d565b9392505050565b5f6020820190506145845f830184613f0e565b92915050565b5f6020828403121561459f5761459e613094565b5b5f6145ac848285016143b0565b91505092915050565b5f819050919050565b5f6145d86145d36145ce846145b5565b613934565b61358e565b9050919050565b6145e8816145be565b82525050565b5f6080820190506146015f8301876133fd565b61460e6020830186613b28565b61461b60408301856145df565b818103606083015261462d81846138dc565b905095945050505050565b5f60408201905061464b5f830185613f0e565b614658602083018461366d565b9392505050565b5f6060820190506146725f8301866133fd565b61467f602083018561366d565b61468c604083018461366d565b949350505050565b5f6040820190508181035f8301526146ac81856138dc565b905081810360208301526146c081846138dc565b90509392505050565b5f815190506146d781613790565b92915050565b5f602082840312156146f2576146f1613094565b5b5f6146ff848285016146c9565b91505092915050565b5f82825260208201905092915050565b5f614722826138c2565b61472c8185614708565b935061473c818560208601612ffb565b61474581613023565b840191505092915050565b61475981613167565b82525050565b5f60a083015f8301516147745f860182614375565b5060208301516147876020860182613ceb565b506040830151848203604086015261479f8282614718565b915050606083015184820360608601526147b98282614718565b91505060808301516147ce6080860182614750565b508091505092915050565b5f6040820190508181035f8301526147f1818561475f565b905061480060208301846133fd565b9392505050565b5f6040828403121561481c5761481b613fba565b5b6148266040613f75565b90505f61483584828501613ea2565b5f83015250602061484884828501613ea2565b60208301525092915050565b5f6040828403121561486957614868613094565b5b5f61487684828501614807565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026148db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148a0565b6148e586836148a0565b95508019841693508086168417925050509392505050565b5f61491761491261490d846130f6565b613934565b6130f6565b9050919050565b5f819050919050565b614930836148fd565b61494461493c8261491e565b8484546148ac565b825550505050565b5f90565b61495861494c565b614963818484614927565b505050565b5b818110156149865761497b5f82614950565b600181019050614969565b5050565b601f8211156149cb5761499c8161487f565b6149a584614891565b810160208510156149b4578190505b6149c86149c085614891565b830182614968565b50505b505050565b5f82821c905092915050565b5f6149eb5f19846008026149d0565b1980831691505092915050565b5f614a0383836149dc565b9150826002028217905092915050565b614a1c826138c2565b67ffffffffffffffff811115614a3557614a34613ee1565b5b614a3f8254613e33565b614a4a82828561498a565b5f60209050601f831160018114614a7b575f8415614a69578287015190505b614a7385826149f8565b865550614ada565b601f198416614a898661487f565b5f5b82811015614ab057848901518255600182019150602085019450602081019050614a8b565b86831015614acd5784890151614ac9601f8916826149dc565b8355505b6001600288020188555050505b505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b614b148161358e565b82525050565b5f606083015f830151614b2f5f860182614375565b506020830151614b426020860182614b0b565b5060408301518482036040860152614b5a8282614718565b9150508091505092915050565b5f614b728383614b1a565b905092915050565b5f602082019050919050565b5f614b9082614ae2565b614b9a8185614aec565b935083602082028501614bac85614afc565b805f5b85811015614be75784840389528151614bc88582614b67565b9450614bd383614b7a565b925060208a01995050600181019050614baf565b50829750879550505050505092915050565b5f6020820190508181035f830152614c118184614b86565b905092915050565b5f60408284031215614c2e57614c2d613fba565b5b614c386040613f75565b90505f614c4784828501613115565b5f830152506020614c5a84828501613115565b60208301525092915050565b5f60408284031215614c7b57614c7a613094565b5b5f614c8884828501614c19565b91505092915050565b5f606082019050614ca45f830186613f0e565b614cb1602083018561366d565b614cbe604083018461366d565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614d2a826130f6565b9150614d35836130f6565b925082614d4557614d44614cc6565b5b828204905092915050565b5f614d5a826130f6565b9150614d65836130f6565b9250828202614d73816130f6565b91508282048414831517614d8a57614d89614cf3565b5b5092915050565b5f82905092915050565b5f614da68383614d91565b82614db18135613443565b92506020821015614df157614dec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026148a0565b831692505b505092915050565b5f7fffffffffffffffff00000000000000000000000000000000000000000000000082169050919050565b5f614e2f8383614d91565b82614e3a8135614df9565b92506008821015614e7a57614e757fffffffffffffffff000000000000000000000000000000000000000000000000836008036008026148a0565b831692505b505092915050565b5f8160c01b9050919050565b5f614e9882614e82565b9050919050565b614eb0614eab826135fd565b614e8e565b82525050565b5f8160e01b9050919050565b5f614ecc82614eb6565b9050919050565b614ee4614edf82613719565b614ec2565b82525050565b5f819050919050565b614f04614eff826130f6565b614eea565b82525050565b5f614f158287614e9f565b600882019150614f258286614ed3565b600482019150614f358285614ef3565b602082019150614f4582846141d5565b915081905095945050505050565b5f614f5d826130f6565b9150614f68836130f6565b9250828201905080821115614f8057614f7f614cf3565b5b92915050565b5f819050919050565b614fa0614f9b82613443565b614f86565b82525050565b5f614fb18285614f8f565b602082019150614fc18284614e9f565b6008820191508190509392505050565b5f614fdc8287614f8f565b602082019150614fec8286614e9f565b600882019150614ffc8285614f8f565b60208201915061500c82846141d5565b915081905095945050505050565b5f815190506150288161344c565b92915050565b5f8151905061503c8161439a565b92915050565b5f6080828403121561505757615056613fba565b5b6150616060613f75565b90505f6150708482850161501a565b5f8301525060206150838482850161502e565b602083015250604061509784828501614807565b60408301525092915050565b5f608082840312156150b8576150b7613094565b5b5f6150c584828501615042565b91505092915050565b5f6060820190506150e15f8301866133fd565b6150ee60208301856133fd565b6150fb604083018461366d565b94935050505056fea2646970667358221220622fbd590948ecab9ea959072ad9fa78ce94f7cfcc6e3cddbf038626189bbb2664736f6c63430008160033
Deployed Bytecode
0x60806040526004361061025b575f3560e01c8063715018a611610143578063bb0b6a53116100b5578063d045a0dc11610079578063d045a0dc1461091c578063d424388514610938578063dd62ed3e14610960578063f2fde38b1461099c578063fc0c546a146109c4578063ff7bd03d146109ee5761025b565b8063bb0b6a531461082f578063bc70b3541461086b578063bd815db0146108a7578063c7c7f5b3146108c3578063ca5eb5e1146108f45761025b565b806395d89b411161010757806395d89b4114610723578063963efcaa1461074d5780639f68b96414610777578063a9059cbb146107a1578063b731ea0a146107dd578063b98bd070146108075761025b565b8063715018a6146106415780637d25a05e1461065757806382413eac14610693578063857749b0146106cf5780638da5cb5b146106f95761025b565b806323b872dd116101dc57806352ae2879116101a057806352ae2879146105115780635535d4611461053b5780635a0dfe4d146105775780635e280f11146105b35780636fc1b31e146105dd57806370a08231146106055761025b565b806323b872dd1461041d578063313ce5671461045957806332cb6b0c146104835780633400288b146104ad5780633b6f743b146104d55761025b565b8063134d4f2511610223578063134d4f2514610349578063156a0d0f1461037357806317442b701461039e57806318160ddd146103c95780631f5e1334146103f35761025b565b806306fdde031461025f578063095ea7b3146102895780630d35b415146102c5578063111ecdad1461030357806313137d651461032d575b5f80fd5b34801561026a575f80fd5b50610273610a2a565b604051610280919061306b565b60405180910390f35b348015610294575f80fd5b506102af60048036038101906102aa9190613129565b610aba565b6040516102bc9190613181565b60405180910390f35b3480156102d0575f80fd5b506102eb60048036038101906102e691906131bc565b610adc565b6040516102fa939291906133c1565b60405180910390f35b34801561030e575f80fd5b50610317610c84565b604051610324919061340c565b60405180910390f35b610347600480360381019061034291906134d7565b610ca9565b005b348015610354575f80fd5b5061035d610dc9565b60405161036a91906135aa565b60405180910390f35b34801561037e575f80fd5b50610387610dce565b60405161039592919061361f565b60405180910390f35b3480156103a9575f80fd5b506103b2610dfb565b6040516103c0929190613646565b60405180910390f35b3480156103d4575f80fd5b506103dd610e09565b6040516103ea919061367c565b60405180910390f35b3480156103fe575f80fd5b50610407610e12565b60405161041491906135aa565b60405180910390f35b348015610428575f80fd5b50610443600480360381019061043e9190613695565b610e17565b6040516104509190613181565b60405180910390f35b348015610464575f80fd5b5061046d610e45565b60405161047a9190613700565b60405180910390f35b34801561048e575f80fd5b50610497610e4d565b6040516104a4919061367c565b60405180910390f35b3480156104b8575f80fd5b506104d360048036038101906104ce9190613752565b610e5c565b005b3480156104e0575f80fd5b506104fb60048036038101906104f691906137ba565b610e72565b6040516105089190613841565b60405180910390f35b34801561051c575f80fd5b50610525610eda565b604051610532919061340c565b60405180910390f35b348015610546575f80fd5b50610561600480360381019061055c9190613884565b610ee1565b60405161056e9190613914565b60405180910390f35b348015610582575f80fd5b5061059d60048036038101906105989190613752565b610f87565b6040516105aa9190613181565b60405180910390f35b3480156105be575f80fd5b506105c7610fb0565b6040516105d4919061398f565b60405180910390f35b3480156105e8575f80fd5b5061060360048036038101906105fe91906139a8565b610fd4565b005b348015610610575f80fd5b5061062b600480360381019061062691906139a8565b611056565b604051610638919061367c565b60405180910390f35b34801561064c575f80fd5b5061065561109c565b005b348015610662575f80fd5b5061067d60048036038101906106789190613752565b6110af565b60405161068a91906139d3565b60405180910390f35b34801561069e575f80fd5b506106b960048036038101906106b491906139ec565b6110b6565b6040516106c69190613181565b60405180910390f35b3480156106da575f80fd5b506106e36110f0565b6040516106f09190613700565b60405180910390f35b348015610704575f80fd5b5061070d6110f8565b60405161071a919061340c565b60405180910390f35b34801561072e575f80fd5b5061073761111f565b604051610744919061306b565b60405180910390f35b348015610758575f80fd5b506107616111af565b60405161076e919061367c565b60405180910390f35b348015610782575f80fd5b5061078b6111d3565b6040516107989190613181565b60405180910390f35b3480156107ac575f80fd5b506107c760048036038101906107c29190613129565b6111d7565b6040516107d49190613181565b60405180910390f35b3480156107e8575f80fd5b506107f16111f9565b6040516107fe919061340c565b60405180910390f35b348015610812575f80fd5b5061082d60048036038101906108289190613ab2565b61121e565b005b34801561083a575f80fd5b5061085560048036038101906108509190613afd565b61123f565b6040516108629190613b37565b60405180910390f35b348015610876575f80fd5b50610891600480360381019061088c9190613b50565b611254565b60405161089e9190613914565b60405180910390f35b6108c160048036038101906108bc9190613c16565b611456565b005b6108dd60048036038101906108d89190613c7f565b611622565b6040516108eb929190613d76565b60405180910390f35b3480156108ff575f80fd5b5061091a600480360381019061091591906139a8565b611649565b005b610936600480360381019061093191906134d7565b6116da565b005b348015610943575f80fd5b5061095e600480360381019061095991906139a8565b611757565b005b34801561096b575f80fd5b5061098660048036038101906109819190613d9d565b6117d9565b604051610993919061367c565b60405180910390f35b3480156109a7575f80fd5b506109c260048036038101906109bd91906139a8565b61185b565b005b3480156109cf575f80fd5b506109d86118df565b6040516109e5919061340c565b60405180910390f35b3480156109f9575f80fd5b50610a146004803603810190610a0f9190613ddb565b6118e6565b604051610a219190613181565b60405180910390f35b606060088054610a3990613e33565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6590613e33565b8015610ab05780601f10610a8757610100808354040283529160200191610ab0565b820191905f5260205f20905b815481529060010190602001808311610a9357829003601f168201915b5050505050905090565b5f80610ac4611923565b9050610ad181858561192a565b600191505092915050565b610ae4612f4e565b6060610aee612f66565b5f803073ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190613e77565b73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc99190613eb6565b905060405180604001604052808381526020018281525094505f67ffffffffffffffff811115610bfc57610bfb613ee1565b5b604051908082528060200260200182016040528015610c3557816020015b610c22612f7e565b815260200190600190039081610c1a5790505b5093505f80610c5e886040013589606001358a5f016020810190610c599190613afd565b61193c565b915091506040518060400160405280838152602001828152509450505050509193909250565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1614610d3957336040517f91ac5e4f000000000000000000000000000000000000000000000000000000008152600401610d30919061340c565b60405180910390fd5b8660200135610d58885f016020810190610d539190613afd565b61199b565b14610db157865f016020810190610d6f9190613afd565b87602001356040517fc26bebcc000000000000000000000000000000000000000000000000000000008152600401610da8929190613f1d565b60405180910390fd5b610dc087878787878787611a0c565b50505050505050565b600281565b5f807f02e49c2c000000000000000000000000000000000000000000000000000000006001915091509091565b5f8060016002915091509091565b5f600754905090565b600181565b5f80610e21611923565b9050610e2e858285611b96565b610e39858585611c28565b60019150509392505050565b5f6012905090565b6a084595161401484a00000081565b610e64611d18565b610e6e8282611d9f565b5050565b610e7a612f97565b5f610e9f84604001358560600135865f016020810190610e9a9190613afd565b61193c565b9150505f80610eae8684611dfe565b91509150610ecf865f016020810190610ec79190613afd565b838388611f8f565b935050505092915050565b5f30905090565b6003602052815f5260405f20602052805f5260405f205f91509150508054610f0890613e33565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3490613e33565b8015610f7f5780601f10610f5657610100808354040283529160200191610f7f565b820191905f5260205f20905b815481529060010190602001808311610f6257829003601f168201915b505050505081565b5f8160015f8563ffffffff1663ffffffff1681526020019081526020015f205414905092915050565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b81565b610fdc611d18565b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d44141978160405161104b919061340c565b60405180910390a150565b5f60055f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6110a4611d18565b6110ad5f612070565b565b5f92915050565b5f3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b5f6006905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606009805461112e90613e33565b80601f016020809104026020016040519081016040528092919081815260200182805461115a90613e33565b80156111a55780601f1061117c576101008083540402835291602001916111a5565b820191905f5260205f20905b81548152906001019060200180831161118857829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000e8d4a5100081565b5f90565b5f806111e1611923565b90506111ee818585611c28565b600191505092915050565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611226611d18565b61123b8282906112369190614175565b612131565b5050565b6001602052805f5260405f205f915090505481565b60605f60035f8763ffffffff1663ffffffff1681526020019081526020015f205f8661ffff1661ffff1681526020019081526020015f20805461129690613e33565b80601f01602080910402602001604051908101604052809291908181526020018280546112c290613e33565b801561130d5780601f106112e45761010080835404028352916020019161130d565b820191905f5260205f20905b8154815290600101906020018083116112f057829003601f168201915b505050505090505f8151036113685783838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505091505061144e565b5f848490500361137b578091505061144e565b6002848490501061140f576113d284848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612246565b80848460029080926113e693929190614191565b6040516020016113f893929190614229565b60405160208183030381529060405291505061144e565b83836040517f9a6d49cd00000000000000000000000000000000000000000000000000000000815260040161144592919061427a565b60405180910390fd5b949350505050565b5f5b8282905081101561157557368383838181106114775761147661429c565b5b905060200281019061148991906142d5565b90506114ae815f015f0160208101906114a29190613afd565b825f0160200135610f87565b6114b85750611568565b3073ffffffffffffffffffffffffffffffffffffffff1663d045a0dc8260c00135835f018460a00135858061010001906114f291906142fd565b8760e001602081019061150591906139a8565b8880610120019061151691906142fd565b6040518963ffffffff1660e01b81526004016115389796959493929190614432565b5f604051808303818588803b15801561154f575f80fd5b505af1158015611561573d5f803e3d5ffd5b5050505050505b8080600101915050611458565b503373ffffffffffffffffffffffffffffffffffffffff16638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa1580156115be573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906115e69190614503565b6040517f8351eea70000000000000000000000000000000000000000000000000000000081526004016116199190613914565b60405180910390fd5b61162a612faf565b611632612f66565b61163d85858561229f565b91509150935093915050565b611651611d18565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b81526004016116aa919061340c565b5f604051808303815f87803b1580156116c1575f80fd5b505af11580156116d3573d5f803e3d5ffd5b5050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461173f576040517f14d4a4e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61174e878787878787876123a4565b50505050505050565b61175f611d18565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760816040516117ce919061340c565b60405180910390a150565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b611863611d18565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118d3575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016118ca919061340c565b60405180910390fd5b6118dc81612070565b50565b5f30905090565b5f816020013560015f845f0160208101906119019190613afd565b63ffffffff1663ffffffff1681526020019081526020015f2054149050919050565b5f33905090565b61193783838360016123bc565b505050565b5f806119478561258b565b9150819050838110156119935780846040517f71c4efed00000000000000000000000000000000000000000000000000000000815260040161198a92919061454a565b60405180910390fd5b935093915050565b5f8060015f8463ffffffff1663ffffffff1681526020019081526020015f205490505f801b8103611a0357826040517ff6ff4fb70000000000000000000000000000000000000000000000000000000081526004016119fa9190614571565b60405180910390fd5b80915050919050565b5f611a1f611a1a87876125ea565b612614565b90505f611a4f82611a38611a338a8a61261f565b612650565b8b5f016020810190611a4a9190613afd565b61268e565b9050611a5b87876126dc565b15611b29575f611a998a6040016020810190611a77919061458a565b8b5f016020810190611a899190613afd565b84611a948c8c6126ef565b612751565b90507f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff16637cb59012848b5f856040518563ffffffff1660e01b8152600401611afa94939291906145ee565b5f604051808303815f87803b158015611b11575f80fd5b505af1158015611b23573d5f803e3d5ffd5b50505050505b8173ffffffffffffffffffffffffffffffffffffffff16887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c8b5f016020810190611b749190613afd565b84604051611b83929190614638565b60405180910390a3505050505050505050565b5f611ba184846117d9565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c225781811015611c13578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611c0a9392919061465f565b60405180910390fd5b611c2184848484035f6123bc565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c98575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611c8f919061340c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d08575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611cff919061340c565b60405180910390fd5b611d13838383612783565b505050565b611d20611923565b73ffffffffffffffffffffffffffffffffffffffff16611d3e6110f8565b73ffffffffffffffffffffffffffffffffffffffff1614611d9d57611d61611923565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611d94919061340c565b60405180910390fd5b565b8060015f8463ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b8282604051611df2929190613f1d565b60405180910390a15050565b6060805f611e6a8560200135611e138661299f565b878060a00190611e2391906142fd565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506129d3565b80925081945050505f81611e7f576001611e82565b60025b9050611eaf865f016020810190611e999190613afd565b82888060800190611eaa91906142fd565b611254565b92505f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f85578073ffffffffffffffffffffffffffffffffffffffff1663043a78eb86866040518363ffffffff1660e01b8152600401611f44929190614694565b602060405180830381865afa158015611f5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8391906146dd565b505b5050509250929050565b611f97612f97565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663ddc28c586040518060a001604052808863ffffffff168152602001611ff38961199b565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016120289291906147d9565b6040805180830381865afa158015612042573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120669190614854565b9050949350505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5b815181101561220b576121638282815181106121525761215161429c565b5b602002602001015160400151612246565b8181815181106121765761217561429c565b5b60200260200101516040015160035f8484815181106121985761219761429c565b5b60200260200101515f015163ffffffff1663ffffffff1681526020019081526020015f205f8484815181106121d0576121cf61429c565b5b60200260200101516020015161ffff1661ffff1681526020019081526020015f2090816121fd9190614a13565b508080600101915050612133565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748160405161223b9190614bf9565b60405180910390a150565b5f60028201519050600361ffff168161ffff161461229b57816040517f9a6d49cd0000000000000000000000000000000000000000000000000000000081526004016122929190613914565b60405180910390fd5b5050565b6122a7612faf565b6122af612f66565b5f806122d633886040013589606001358a5f0160208101906122d19190613afd565b612a41565b915091505f806122e68984611dfe565b91509150612318895f0160208101906122ff9190613afd565b83838b8036038101906123129190614c66565b8b612a69565b955060405180604001604052808581526020018481525094503373ffffffffffffffffffffffffffffffffffffffff16865f01517f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a8b5f01602081019061237f9190613afd565b878760405161239093929190614c91565b60405180910390a350505050935093915050565b6123b387878787878787611a0c565b50505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361242c575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401612423919061340c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361249c575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401612493919061340c565b60405180910390fd5b8160065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015612585578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161257c919061367c565b60405180910390a35b50505050565b5f7f000000000000000000000000000000000000000000000000000000e8d4a510007f000000000000000000000000000000000000000000000000000000e8d4a51000836125d99190614d20565b6125e39190614d50565b9050919050565b5f82825f90602060ff169261260193929190614191565b9061260c9190614d9b565b905092915050565b5f815f1c9050919050565b5f8282602060ff1690602860ff169261263a93929190614191565b906126459190614e24565b60c01c905092915050565b5f7f000000000000000000000000000000000000000000000000000000e8d4a510008267ffffffffffffffff166126879190614d50565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036126c85761dead93505b6126d28484612b7f565b8290509392505050565b5f602860ff168383905011905092915050565b60608282602860ff1690809261270793929190614191565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050905092915050565b60608484848460405160200161276a9493929190614f0a565b6040516020818303038152906040529050949350505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127d3578060075f8282546127c79190614f53565b925050819055506128a3565b5f60055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561285d578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016128549392919061465f565b60405180910390fd5b81810360055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036128ea578060075f8282540392505081905550612935565b8060055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612992919061367c565b60405180910390a3505050565b5f7f000000000000000000000000000000000000000000000000000000e8d4a51000826129cc9190614d20565b9050919050565b60605f80835111905080612a085784846040516020016129f4929190614fa6565b604051602081830303815290604052612a37565b8484612a1333612bfe565b85604051602001612a279493929190614fd1565b6040516020818303038152906040525b9150935093915050565b5f80612a4e85858561193c565b8092508193505050612a608683612c1f565b94509492505050565b612a71612faf565b5f612a7e845f0151612c9e565b90505f84602001511115612a9a57612a998460200151612ceb565b5b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff16632637a450826040518060a001604052808b63ffffffff168152602001612af78c61199b565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612b329291906147d9565b60806040518083038185885af1158015612b4e573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612b7391906150a3565b91505095945050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612bef575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401612be6919061340c565b60405180910390fd5b612bfa5f8383612783565b5050565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c8f575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401612c86919061340c565b60405180910390fd5b612c9a825f83612783565b5050565b5f813414612ce357346040517f9f704120000000000000000000000000000000000000000000000000000000008152600401612cda919061367c565b60405180910390fd5b819050919050565b5f7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d799190613e77565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612de0576040517f5373352a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e2d337f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b848473ffffffffffffffffffffffffffffffffffffffff16612e31909392919063ffffffff16565b5050565b612ead848573ffffffffffffffffffffffffffffffffffffffff166323b872dd868686604051602401612e66939291906150ce565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612eb3565b50505050565b5f8060205f8451602086015f885af180612ed2576040513d5f823e3d81fd5b3d92505f519150505f8214612eeb576001811415612f06565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15612f4857836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401612f3f919061340c565b60405180910390fd5b50505050565b60405180604001604052805f81526020015f81525090565b60405180604001604052805f81526020015f81525090565b60405180604001604052805f8152602001606081525090565b60405180604001604052805f81526020015f81525090565b60405180606001604052805f80191681526020015f67ffffffffffffffff168152602001612fdb612f97565b81525090565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613018578082015181840152602081019050612ffd565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61303d82612fe1565b6130478185612feb565b9350613057818560208601612ffb565b61306081613023565b840191505092915050565b5f6020820190508181035f8301526130838184613033565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6130c58261309c565b9050919050565b6130d5816130bb565b81146130df575f80fd5b50565b5f813590506130f0816130cc565b92915050565b5f819050919050565b613108816130f6565b8114613112575f80fd5b50565b5f81359050613123816130ff565b92915050565b5f806040838503121561313f5761313e613094565b5b5f61314c858286016130e2565b925050602061315d85828601613115565b9150509250929050565b5f8115159050919050565b61317b81613167565b82525050565b5f6020820190506131945f830184613172565b92915050565b5f80fd5b5f60e082840312156131b3576131b261319a565b5b81905092915050565b5f602082840312156131d1576131d0613094565b5b5f82013567ffffffffffffffff8111156131ee576131ed613098565b5b6131fa8482850161319e565b91505092915050565b61320c816130f6565b82525050565b604082015f8201516132265f850182613203565b5060208201516132396020850182613203565b50505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f819050919050565b61327a81613268565b82525050565b5f82825260208201905092915050565b5f61329a82612fe1565b6132a48185613280565b93506132b4818560208601612ffb565b6132bd81613023565b840191505092915050565b5f604083015f8301516132dd5f860182613271565b50602083015184820360208601526132f58282613290565b9150508091505092915050565b5f61330d83836132c8565b905092915050565b5f602082019050919050565b5f61332b8261323f565b6133358185613249565b93508360208202850161334785613259565b805f5b8581101561338257848403895281516133638582613302565b945061336e83613315565b925060208a0199505060018101905061334a565b50829750879550505050505092915050565b604082015f8201516133a85f850182613203565b5060208201516133bb6020850182613203565b50505050565b5f60a0820190506133d45f830186613212565b81810360408301526133e68185613321565b90506133f56060830184613394565b949350505050565b613406816130bb565b82525050565b5f60208201905061341f5f8301846133fd565b92915050565b5f6060828403121561343a5761343961319a565b5b81905092915050565b5f819050919050565b61345581613443565b811461345f575f80fd5b50565b5f813590506134708161344c565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261349757613496613476565b5b8235905067ffffffffffffffff8111156134b4576134b361347a565b5b6020830191508360018202830111156134d0576134cf61347e565b5b9250929050565b5f805f805f805f60e0888a0312156134f2576134f1613094565b5b5f6134ff8a828b01613425565b97505060606135108a828b01613462565b965050608088013567ffffffffffffffff81111561353157613530613098565b5b61353d8a828b01613482565b955095505060a06135508a828b016130e2565b93505060c088013567ffffffffffffffff81111561357157613570613098565b5b61357d8a828b01613482565b925092505092959891949750929550565b5f61ffff82169050919050565b6135a48161358e565b82525050565b5f6020820190506135bd5f83018461359b565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6135f7816135c3565b82525050565b5f67ffffffffffffffff82169050919050565b613619816135fd565b82525050565b5f6040820190506136325f8301856135ee565b61363f6020830184613610565b9392505050565b5f6040820190506136595f830185613610565b6136666020830184613610565b9392505050565b613676816130f6565b82525050565b5f60208201905061368f5f83018461366d565b92915050565b5f805f606084860312156136ac576136ab613094565b5b5f6136b9868287016130e2565b93505060206136ca868287016130e2565b92505060406136db86828701613115565b9150509250925092565b5f60ff82169050919050565b6136fa816136e5565b82525050565b5f6020820190506137135f8301846136f1565b92915050565b5f63ffffffff82169050919050565b61373181613719565b811461373b575f80fd5b50565b5f8135905061374c81613728565b92915050565b5f806040838503121561376857613767613094565b5b5f6137758582860161373e565b925050602061378685828601613462565b9150509250929050565b61379981613167565b81146137a3575f80fd5b50565b5f813590506137b481613790565b92915050565b5f80604083850312156137d0576137cf613094565b5b5f83013567ffffffffffffffff8111156137ed576137ec613098565b5b6137f98582860161319e565b925050602061380a858286016137a6565b9150509250929050565b604082015f8201516138285f850182613203565b50602082015161383b6020850182613203565b50505050565b5f6040820190506138545f830184613814565b92915050565b6138638161358e565b811461386d575f80fd5b50565b5f8135905061387e8161385a565b92915050565b5f806040838503121561389a57613899613094565b5b5f6138a78582860161373e565b92505060206138b885828601613870565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f6138e6826138c2565b6138f081856138cc565b9350613900818560208601612ffb565b61390981613023565b840191505092915050565b5f6020820190508181035f83015261392c81846138dc565b905092915050565b5f819050919050565b5f61395761395261394d8461309c565b613934565b61309c565b9050919050565b5f6139688261393d565b9050919050565b5f6139798261395e565b9050919050565b6139898161396f565b82525050565b5f6020820190506139a25f830184613980565b92915050565b5f602082840312156139bd576139bc613094565b5b5f6139ca848285016130e2565b91505092915050565b5f6020820190506139e65f830184613610565b92915050565b5f805f8060a08587031215613a0457613a03613094565b5b5f613a1187828801613425565b945050606085013567ffffffffffffffff811115613a3257613a31613098565b5b613a3e87828801613482565b93509350506080613a51878288016130e2565b91505092959194509250565b5f8083601f840112613a7257613a71613476565b5b8235905067ffffffffffffffff811115613a8f57613a8e61347a565b5b602083019150836020820283011115613aab57613aaa61347e565b5b9250929050565b5f8060208385031215613ac857613ac7613094565b5b5f83013567ffffffffffffffff811115613ae557613ae4613098565b5b613af185828601613a5d565b92509250509250929050565b5f60208284031215613b1257613b11613094565b5b5f613b1f8482850161373e565b91505092915050565b613b3181613443565b82525050565b5f602082019050613b4a5f830184613b28565b92915050565b5f805f8060608587031215613b6857613b67613094565b5b5f613b758782880161373e565b9450506020613b8687828801613870565b935050604085013567ffffffffffffffff811115613ba757613ba6613098565b5b613bb387828801613482565b925092505092959194509250565b5f8083601f840112613bd657613bd5613476565b5b8235905067ffffffffffffffff811115613bf357613bf261347a565b5b602083019150836020820283011115613c0f57613c0e61347e565b5b9250929050565b5f8060208385031215613c2c57613c2b613094565b5b5f83013567ffffffffffffffff811115613c4957613c48613098565b5b613c5585828601613bc1565b92509250509250929050565b5f60408284031215613c7657613c7561319a565b5b81905092915050565b5f805f60808486031215613c9657613c95613094565b5b5f84013567ffffffffffffffff811115613cb357613cb2613098565b5b613cbf8682870161319e565b9350506020613cd086828701613c61565b9250506060613ce1868287016130e2565b9150509250925092565b613cf481613443565b82525050565b613d03816135fd565b82525050565b604082015f820151613d1d5f850182613203565b506020820151613d306020850182613203565b50505050565b608082015f820151613d4a5f850182613ceb565b506020820151613d5d6020850182613cfa565b506040820151613d706040850182613d09565b50505050565b5f60c082019050613d895f830185613d36565b613d966080830184613394565b9392505050565b5f8060408385031215613db357613db2613094565b5b5f613dc0858286016130e2565b9250506020613dd1858286016130e2565b9150509250929050565b5f60608284031215613df057613def613094565b5b5f613dfd84828501613425565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680613e4a57607f821691505b602082108103613e5d57613e5c613e06565b5b50919050565b5f81519050613e71816130cc565b92915050565b5f60208284031215613e8c57613e8b613094565b5b5f613e9984828501613e63565b91505092915050565b5f81519050613eb0816130ff565b92915050565b5f60208284031215613ecb57613eca613094565b5b5f613ed884828501613ea2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613f1781613719565b82525050565b5f604082019050613f305f830185613f0e565b613f3d6020830184613b28565b9392505050565b613f4d82613023565b810181811067ffffffffffffffff82111715613f6c57613f6b613ee1565b5b80604052505050565b5f613f7e61308b565b9050613f8a8282613f44565b919050565b5f67ffffffffffffffff821115613fa957613fa8613ee1565b5b602082029050602081019050919050565b5f80fd5b5f80fd5b5f80fd5b5f67ffffffffffffffff821115613fe057613fdf613ee1565b5b613fe982613023565b9050602081019050919050565b828183375f83830152505050565b5f61401661401184613fc6565b613f75565b90508281526020810184848401111561403257614031613fc2565b5b61403d848285613ff6565b509392505050565b5f82601f83011261405957614058613476565b5b8135614069848260208601614004565b91505092915050565b5f6060828403121561408757614086613fba565b5b6140916060613f75565b90505f6140a08482850161373e565b5f8301525060206140b384828501613870565b602083015250604082013567ffffffffffffffff8111156140d7576140d6613fbe565b5b6140e384828501614045565b60408301525092915050565b5f6141016140fc84613f8f565b613f75565b905080838252602082019050602084028301858111156141245761412361347e565b5b835b8181101561416b57803567ffffffffffffffff81111561414957614148613476565b5b8086016141568982614072565b85526020850194505050602081019050614126565b5050509392505050565b5f6141813684846140ef565b905092915050565b5f80fd5b5f80fd5b5f80858511156141a4576141a3614189565b5b838611156141b5576141b461418d565b5b6001850283019150848603905094509492505050565b5f81905092915050565b5f6141df826138c2565b6141e981856141cb565b93506141f9818560208601612ffb565b80840191505092915050565b5f61421083856141cb565b935061421d838584613ff6565b82840190509392505050565b5f61423482866141d5565b9150614241828486614205565b9150819050949350505050565b5f61425983856138cc565b9350614266838584613ff6565b61426f83613023565b840190509392505050565b5f6020820190508181035f83015261429381848661424e565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f82356001610140038336030381126142f1576142f06142c9565b5b80830191505092915050565b5f8083356001602003843603038112614319576143186142c9565b5b80840192508235915067ffffffffffffffff82111561433b5761433a6142cd565b5b602083019250600182023603831315614357576143566142d1565b5b509250929050565b5f61436d602084018461373e565b905092915050565b61437e81613719565b82525050565b5f6143926020840184613462565b905092915050565b6143a3816135fd565b81146143ad575f80fd5b50565b5f813590506143be8161439a565b92915050565b5f6143d260208401846143b0565b905092915050565b606082016143ea5f83018361435f565b6143f65f850182614375565b506144046020830183614384565b6144116020850182613ceb565b5061441f60408301836143c4565b61442c6040850182613cfa565b50505050565b5f60e0820190506144455f83018a6143da565b6144526060830189613b28565b818103608083015261446581878961424e565b905061447460a08301866133fd565b81810360c083015261448781848661424e565b905098975050505050505050565b5f6144a76144a284613fc6565b613f75565b9050828152602081018484840111156144c3576144c2613fc2565b5b6144ce848285612ffb565b509392505050565b5f82601f8301126144ea576144e9613476565b5b81516144fa848260208601614495565b91505092915050565b5f6020828403121561451857614517613094565b5b5f82015167ffffffffffffffff81111561453557614534613098565b5b614541848285016144d6565b91505092915050565b5f60408201905061455d5f83018561366d565b61456a602083018461366d565b9392505050565b5f6020820190506145845f830184613f0e565b92915050565b5f6020828403121561459f5761459e613094565b5b5f6145ac848285016143b0565b91505092915050565b5f819050919050565b5f6145d86145d36145ce846145b5565b613934565b61358e565b9050919050565b6145e8816145be565b82525050565b5f6080820190506146015f8301876133fd565b61460e6020830186613b28565b61461b60408301856145df565b818103606083015261462d81846138dc565b905095945050505050565b5f60408201905061464b5f830185613f0e565b614658602083018461366d565b9392505050565b5f6060820190506146725f8301866133fd565b61467f602083018561366d565b61468c604083018461366d565b949350505050565b5f6040820190508181035f8301526146ac81856138dc565b905081810360208301526146c081846138dc565b90509392505050565b5f815190506146d781613790565b92915050565b5f602082840312156146f2576146f1613094565b5b5f6146ff848285016146c9565b91505092915050565b5f82825260208201905092915050565b5f614722826138c2565b61472c8185614708565b935061473c818560208601612ffb565b61474581613023565b840191505092915050565b61475981613167565b82525050565b5f60a083015f8301516147745f860182614375565b5060208301516147876020860182613ceb565b506040830151848203604086015261479f8282614718565b915050606083015184820360608601526147b98282614718565b91505060808301516147ce6080860182614750565b508091505092915050565b5f6040820190508181035f8301526147f1818561475f565b905061480060208301846133fd565b9392505050565b5f6040828403121561481c5761481b613fba565b5b6148266040613f75565b90505f61483584828501613ea2565b5f83015250602061484884828501613ea2565b60208301525092915050565b5f6040828403121561486957614868613094565b5b5f61487684828501614807565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026148db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148a0565b6148e586836148a0565b95508019841693508086168417925050509392505050565b5f61491761491261490d846130f6565b613934565b6130f6565b9050919050565b5f819050919050565b614930836148fd565b61494461493c8261491e565b8484546148ac565b825550505050565b5f90565b61495861494c565b614963818484614927565b505050565b5b818110156149865761497b5f82614950565b600181019050614969565b5050565b601f8211156149cb5761499c8161487f565b6149a584614891565b810160208510156149b4578190505b6149c86149c085614891565b830182614968565b50505b505050565b5f82821c905092915050565b5f6149eb5f19846008026149d0565b1980831691505092915050565b5f614a0383836149dc565b9150826002028217905092915050565b614a1c826138c2565b67ffffffffffffffff811115614a3557614a34613ee1565b5b614a3f8254613e33565b614a4a82828561498a565b5f60209050601f831160018114614a7b575f8415614a69578287015190505b614a7385826149f8565b865550614ada565b601f198416614a898661487f565b5f5b82811015614ab057848901518255600182019150602085019450602081019050614a8b565b86831015614acd5784890151614ac9601f8916826149dc565b8355505b6001600288020188555050505b505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b614b148161358e565b82525050565b5f606083015f830151614b2f5f860182614375565b506020830151614b426020860182614b0b565b5060408301518482036040860152614b5a8282614718565b9150508091505092915050565b5f614b728383614b1a565b905092915050565b5f602082019050919050565b5f614b9082614ae2565b614b9a8185614aec565b935083602082028501614bac85614afc565b805f5b85811015614be75784840389528151614bc88582614b67565b9450614bd383614b7a565b925060208a01995050600181019050614baf565b50829750879550505050505092915050565b5f6020820190508181035f830152614c118184614b86565b905092915050565b5f60408284031215614c2e57614c2d613fba565b5b614c386040613f75565b90505f614c4784828501613115565b5f830152506020614c5a84828501613115565b60208301525092915050565b5f60408284031215614c7b57614c7a613094565b5b5f614c8884828501614c19565b91505092915050565b5f606082019050614ca45f830186613f0e565b614cb1602083018561366d565b614cbe604083018461366d565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614d2a826130f6565b9150614d35836130f6565b925082614d4557614d44614cc6565b5b828204905092915050565b5f614d5a826130f6565b9150614d65836130f6565b9250828202614d73816130f6565b91508282048414831517614d8a57614d89614cf3565b5b5092915050565b5f82905092915050565b5f614da68383614d91565b82614db18135613443565b92506020821015614df157614dec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026148a0565b831692505b505092915050565b5f7fffffffffffffffff00000000000000000000000000000000000000000000000082169050919050565b5f614e2f8383614d91565b82614e3a8135614df9565b92506008821015614e7a57614e757fffffffffffffffff000000000000000000000000000000000000000000000000836008036008026148a0565b831692505b505092915050565b5f8160c01b9050919050565b5f614e9882614e82565b9050919050565b614eb0614eab826135fd565b614e8e565b82525050565b5f8160e01b9050919050565b5f614ecc82614eb6565b9050919050565b614ee4614edf82613719565b614ec2565b82525050565b5f819050919050565b614f04614eff826130f6565b614eea565b82525050565b5f614f158287614e9f565b600882019150614f258286614ed3565b600482019150614f358285614ef3565b602082019150614f4582846141d5565b915081905095945050505050565b5f614f5d826130f6565b9150614f68836130f6565b9250828201905080821115614f8057614f7f614cf3565b5b92915050565b5f819050919050565b614fa0614f9b82613443565b614f86565b82525050565b5f614fb18285614f8f565b602082019150614fc18284614e9f565b6008820191508190509392505050565b5f614fdc8287614f8f565b602082019150614fec8286614e9f565b600882019150614ffc8285614f8f565b60208201915061500c82846141d5565b915081905095945050505050565b5f815190506150288161344c565b92915050565b5f8151905061503c8161439a565b92915050565b5f6080828403121561505757615056613fba565b5b6150616060613f75565b90505f6150708482850161501a565b5f8301525060206150838482850161502e565b602083015250604061509784828501614807565b60408301525092915050565b5f608082840312156150b8576150b7613094565b5b5f6150c584828501615042565b91505092915050565b5f6060820190506150e15f8301866133fd565b6150ee60208301856133fd565b6150fb604083018461366d565b94935050505056fea2646970667358221220622fbd590948ecab9ea959072ad9fa78ce94f7cfcc6e3cddbf038626189bbb2664736f6c63430008160033
Deployed Bytecode Sourcemap
136816:468:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16186:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18479:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117767:1301;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;114860:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73073:723;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114731:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116029:142;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;75312:243;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;17288:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114693:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19279:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17139:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136858:56;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59928:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119531:787;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96127:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77537:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;128965:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58621:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117236:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17450:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3361:103;;;;;;;;;;;;;:::i;:::-;;72195:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70669:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116790:89;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2686:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16396:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114382:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;134675:96;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17773:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95802:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78402:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58747:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80556:1003;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96971:1358;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;121023:296;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;61493:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98991:419;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96360:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18018;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3619:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;134281:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71444:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16186:91;16231:13;16264:5;16257:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16186:91;:::o;18479:190::-;18552:4;18569:13;18585:12;:10;:12::i;:::-;18569:28;;18608:31;18617:5;18624:7;18633:5;18608:8;:31::i;:::-;18657:4;18650:11;;;18479:190;;;;:::o;117767:1301::-;117899:24;;:::i;:::-;117925:35;117962:28;;:::i;:::-;118008:19;118083;118112:4;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;118105:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;118083:56;;118202:34;;;;;;;;118211:11;118202:34;;;;118224:11;118202:34;;;118191:45;;118375:1;118356:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;118340:37;;118820:20;118842:24;118870:124;118895:10;:19;;;118929:10;:22;;;118966:10;:17;;;;;;;;;;:::i;:::-;118870:10;:124::i;:::-;118819:175;;;;119018:42;;;;;;;;119029:12;119018:42;;;;119043:16;119018:42;;;119005:55;;117997:1071;;;;117767:1301;;;;;:::o;114860:27::-;;;;;;;;;;;;;:::o;73073:723::-;73407:10;73386:31;;73394:8;73386:31;;;73382:68;;73439:10;73426:24;;;;;;;;;;;:::i;:::-;;;;;;;;73382:68;73589:7;:14;;;73553:32;73570:7;:14;;;;;;;;;;:::i;:::-;73553:16;:32::i;:::-;:50;73549:103;;73621:7;:14;;;;;;;;;;:::i;:::-;73637:7;:14;;;73612:40;;;;;;;;;;;;:::i;:::-;;;;;;;;73549:103;73729:59;73740:7;73749:5;73756:8;;73766:9;73777:10;;73729;:59::i;:::-;73073:723;;;;;;;:::o;114731:40::-;114770:1;114731:40;:::o;116029:142::-;116082:18;116102:14;116137:22;116161:1;116129:34;;;;116029:142;;:::o;75312:243::-;75444:20;75466:22;62224:1;69306;75506:41;;;;75312:243;;:::o;17288:99::-;17340:7;17367:12;;17360:19;;17288:99;:::o;114693:31::-;114723:1;114693:31;:::o;19279:249::-;19366:4;19383:15;19401:12;:10;:12::i;:::-;19383:30;;19424:37;19440:4;19446:7;19455:5;19424:15;:37::i;:::-;19472:26;19482:4;19488:2;19492:5;19472:9;:26::i;:::-;19516:4;19509:11;;;19279:249;;;;;:::o;17139:84::-;17188:5;17213:2;17206:9;;17139:84;:::o;136858:56::-;136895:19;136858:56;:::o;59928:110::-;2572:13;:11;:13::i;:::-;60009:21:::1;60018:4;60024:5;60009:8;:21::i;:::-;59928:110:::0;;:::o;119531:787::-;119657:26;;:::i;:::-;119871:24;119899:74;119910:10;:19;;;119931:10;:22;;;119955:10;:17;;;;;;;;;;:::i;:::-;119899:10;:74::i;:::-;119868:105;;;120065:20;120087;120111:49;120131:10;120143:16;120111:19;:49::i;:::-;120064:96;;;;120252:58;120259:10;:17;;;;;;;;;;:::i;:::-;120278:7;120287;120296:13;120252:6;:58::i;:::-;120245:65;;;;;119531:787;;;;:::o;96127:95::-;96174:7;96209:4;96194:20;;96127:95;:::o;77537:93::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;128965:134::-;129047:4;129086:5;129071;:11;129077:4;129071:11;;;;;;;;;;;;;;;;:20;129064:27;;128965:134;;;;:::o;58621:46::-;;;:::o;117236:166::-;2572:13;:11;:13::i;:::-;117335::::1;117320:12;;:28;;;;;;;;;;;;;;;;;;117364:30;117380:13;117364:30;;;;;;:::i;:::-;;;;;;;;117236:166:::0;:::o;17450:118::-;17515:7;17542:9;:18;17552:7;17542:18;;;;;;;;;;;;;;;;17535:25;;17450:118;;;:::o;3361:103::-;2572:13;:11;:13::i;:::-;3426:30:::1;3453:1;3426:18;:30::i;:::-;3361:103::o:0;72195:130::-;72284:12;72195:130;;;;:::o;70669:222::-;70835:4;70878;70859:24;;:7;:24;;;70852:31;;70669:222;;;;;;:::o;116790:89::-;116845:5;116870:1;116863:8;;116790:89;:::o;2686:87::-;2732:7;2759:6;;;;;;;;;;;2752:13;;2686:87;:::o;16396:95::-;16443:13;16476:7;16469:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16396:95;:::o;114382:46::-;;;:::o;134675:96::-;134734:4;134675:96;:::o;17773:182::-;17842:4;17859:13;17875:12;:10;:12::i;:::-;17859:28;;17898:27;17908:5;17915:2;17919:5;17898:9;:27::i;:::-;17943:4;17936:11;;;17773:182;;;;:::o;95802:23::-;;;;;;;;;;;;;:::o;78402:158::-;2572:13;:11;:13::i;:::-;78515:37:::1;78535:16;;78515:37;;;;;:::i;:::-;:19;:37::i;:::-;78402:158:::0;;:::o;58747:48::-;;;;;;;;;;;;;;;;;:::o;80556:1003::-;80703:12;80728:21;80752:15;:21;80768:4;80752:21;;;;;;;;;;;;;;;:31;80774:8;80752:31;;;;;;;;;;;;;;;80728:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80934:1;80915:8;:15;:20;80911:46;;80944:13;;80937:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80911:46;81045:1;81021:13;;:20;;:25;81017:46;;81055:8;81048:15;;;;;81017:46;81213:1;81189:13;;:20;;:25;81185:271;;81231:34;81251:13;;81231:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:19;:34::i;:::-;81416:8;81426:13;;81440:1;81426:17;;;;;;;;;:::i;:::-;81403:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81396:48;;;;;81185:271;81537:13;;81522:29;;;;;;;;;;;;:::i;:::-;;;;;;;;80556:1003;;;;;;;:::o;96971:1358::-;97073:9;97068:1057;97092:8;;:15;;97088:1;:19;97068:1057;;;97129:29;97161:8;;97170:1;97161:11;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;97129:43;;97258:50;97265:6;:13;;:20;;;;;;;;;;:::i;:::-;97287:6;:13;;:20;;;97258:6;:50::i;:::-;97253:65;;97310:8;;;97253:65;97889:4;:22;;;97920:6;:12;;;97953:6;:13;;97985:6;:11;;;98015:6;:14;;;;;;;;:::i;:::-;98048:6;:15;;;;;;;;;;:::i;:::-;98082:6;:16;;;;;;;;:::i;:::-;97889:224;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97114:1011;97068:1057;97109:3;;;;;;;97068:1057;;;;98285:10;98275:43;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98258:63;;;;;;;;;;;:::i;:::-;;;;;;;;121023:296;121188:34;;:::i;:::-;121224:28;;:::i;:::-;121272:39;121278:10;121290:4;121296:14;121272:5;:39::i;:::-;121265:46;;;;121023:296;;;;;;:::o;61493:107::-;2572:13;:11;:13::i;:::-;61561:8:::1;:20;;;61582:9;61561:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;61493:107:::0;:::o;98991:419::-;99300:4;99278:27;;:10;:27;;;99274:50;;99314:10;;;;;;;;;;;;;;99274:50;99335:67;99354:7;99363:5;99370:8;;99380:9;99391:10;;99335:18;:67::i;:::-;98991:419;;;;;;;:::o;96360:142::-;2572:13;:11;:13::i;:::-;96447:9:::1;96436:8;;:20;;;;;;;;;;;;;;;;;;96472:22;96484:9;96472:22;;;;;;:::i;:::-;;;;;;;;96360:142:::0;:::o;18018:::-;18098:7;18125:11;:18;18137:5;18125:18;;;;;;;;;;;;;;;:27;18144:7;18125:27;;;;;;;;;;;;;;;;18118:34;;18018:142;;;;:::o;3619:220::-;2572:13;:11;:13::i;:::-;3724:1:::1;3704:22;;:8;:22;;::::0;3700:93:::1;;3778:1;3750:31;;;;;;;;;;;:::i;:::-;;;;;;;;3700:93;3803:28;3822:8;3803:18;:28::i;:::-;3619:220:::0;:::o;134281:86::-;134319:7;134354:4;134339:20;;134281:86;:::o;71444:151::-;71526:4;71574:6;:13;;;71550:5;:20;71556:6;:13;;;;;;;;;;:::i;:::-;71550:20;;;;;;;;;;;;;;;;:37;71543:44;;71444:151;;;:::o;695:98::-;748:7;775:10;768:17;;695:98;:::o;23338:130::-;23423:37;23432:5;23439:7;23448:5;23455:4;23423:8;:37::i;:::-;23338:130;;;:::o;131026:682::-;131172:20;131194:24;131370:22;131382:9;131370:11;:22::i;:::-;131355:37;;131520:12;131501:31;;131605:12;131586:16;:31;131582:119;;;131658:16;131676:12;131641:48;;;;;;;;;;;;:::i;:::-;;;;;;;;131582:119;131026:682;;;;;;:::o;60946:200::-;61016:7;61036:12;61051:5;:11;61057:4;61051:11;;;;;;;;;;;;;;;;61036:26;;61093:1;61085:10;;61077:4;:18;61073:43;;61111:4;61104:12;;;;;;;;;;;:::i;:::-;;;;;;;;61073:43;61134:4;61127:11;;;60946:200;;;:::o;125693:1837::-;126179:17;126199:36;:17;:8;;:15;:17::i;:::-;:34;:36::i;:::-;126179:56;;126370:24;126397:62;126405:9;126416:26;126422:19;:8;;:17;:19::i;:::-;126416:5;:26::i;:::-;126444:7;:14;;;;;;;;;;:::i;:::-;126397:7;:62::i;:::-;126370:89;;126476:21;:8;;:19;:21::i;:::-;126472:970;;;126578:23;126604:180;126648:7;:13;;;;;;;;;;:::i;:::-;126680:7;:14;;;;;;;;;;:::i;:::-;126713:16;126748:21;:8;;:19;:21::i;:::-;126604:25;:180::i;:::-;126578:206;;127338:8;:20;;;127359:9;127370:5;127377:1;127419:10;127338:92;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126499:943;126472:970;127494:9;127459:63;;127471:5;127459:63;127478:7;:14;;;;;;;;;;:::i;:::-;127505:16;127459:63;;;;;;;:::i;:::-;;;;;;;;126002:1528;;125693:1837;;;;;;;:::o;25070:487::-;25170:24;25197:25;25207:5;25214:7;25197:9;:25::i;:::-;25170:52;;25257:17;25237:16;:37;25233:317;;25314:5;25295:16;:24;25291:132;;;25374:7;25383:16;25401:5;25347:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;25291:132;25466:57;25475:5;25482:7;25510:5;25491:16;:24;25517:5;25466:8;:57::i;:::-;25233:317;25159:398;25070:487;;;:::o;19913:308::-;20013:1;19997:18;;:4;:18;;;19993:88;;20066:1;20039:30;;;;;;;;;;;:::i;:::-;;;;;;;;19993:88;20109:1;20095:16;;:2;:16;;;20091:88;;20164:1;20135:32;;;;;;;;;;;:::i;:::-;;;;;;;;20091:88;20189:24;20197:4;20203:2;20207:5;20189:7;:24::i;:::-;19913:308;;;:::o;2851:166::-;2922:12;:10;:12::i;:::-;2911:23;;:7;:5;:7::i;:::-;:23;;;2907:103;;2985:12;:10;:12::i;:::-;2958:40;;;;;;;;;;;:::i;:::-;;;;;;;;2907:103;2851:166::o;60503:137::-;60591:5;60577;:11;60583:4;60577:11;;;;;;;;;;;;;;;:19;;;;60612:20;60620:4;60626:5;60612:20;;;;;;;:::i;:::-;;;;;;;;60503:137;;:::o;123704:1458::-;123839:20;123861;123894:15;124067:330;124100:10;:13;;;124128:16;124134:9;124128:5;:16::i;:::-;124365:10;:21;;;;;;;;:::i;:::-;124067:330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;:330::i;:::-;124043:354;;;;;;;;124479:14;124496:10;:33;;114723:1;124496:33;;;114770:1;124496:33;124479:50;;124653:67;124668:10;:17;;;;;;;;;;:::i;:::-;124687:7;124696:10;:23;;;;;;;;:::i;:::-;124653:14;:67::i;:::-;124643:77;;124962:17;124982:12;;;;;;;;;;;124962:32;;125096:1;125075:23;;:9;:23;;;125071:83;;125118:9;125100:36;;;125137:7;125146;125100:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;125071:83;123883:1279;;;123704:1458;;;;;:::o;63444:402::-;63616:23;;:::i;:::-;63672:8;:14;;;63705:86;;;;;;;;63721:7;63705:86;;;;;;63730:25;63747:7;63730:16;:25::i;:::-;63705:86;;;;63757:8;63705:86;;;;63767:8;63705:86;;;;63777:13;63705:86;;;;;63818:4;63672:166;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63652:186;;63444:402;;;;;;:::o;3999:191::-;4073:16;4092:6;;;;;;;;;;;4073:25;;4118:8;4109:6;;:17;;;;;;;;;;;;;;;;;;4173:8;4142:40;;4163:8;4142:40;;;;;;;;;;;;4062:128;3999:191;:::o;79261:522::-;79370:9;79365:358;79389:16;:23;79385:1;:27;79365:358;;;79549:48;79569:16;79586:1;79569:19;;;;;;;;:::i;:::-;;;;;;;;:27;;;79549:19;:48::i;:::-;79684:16;79701:1;79684:19;;;;;;;;:::i;:::-;;;;;;;;:27;;;79612:15;:40;79628:16;79645:1;79628:19;;;;;;;;:::i;:::-;;;;;;;;:23;;;79612:40;;;;;;;;;;;;;;;:69;79653:16;79670:1;79653:19;;;;;;;;:::i;:::-;;;;;;;;:27;;;79612:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;;79414:3;;;;;;;79365:358;;;;79740:35;79758:16;79740:35;;;;;;:::i;:::-;;;;;;;;79261:522;:::o;81705:270::-;81790:18;81878:1;81868:8;81864:16;81858:23;81843:38;;77459:1;81906:28;;:11;:28;;;81902:65;;81958:8;81943:24;;;;;;;;;;;:::i;:::-;;;;;;;;81902:65;81779:196;81705:270;:::o;122044:1357::-;122202:34;;:::i;:::-;122238:28;;:::i;:::-;122604:20;122626:24;122654:145;122675:10;122700;:19;;;122734:10;:22;;;122771:10;:17;;;;;;;;;;:::i;:::-;122654:6;:145::i;:::-;122603:196;;;;122891:20;122913;122937:49;122957:10;122969:16;122937:19;:49::i;:::-;122890:96;;;;123112:66;123120:10;:17;;;;;;;;;;:::i;:::-;123139:7;123148;123157:4;123112:66;;;;;;;;;;:::i;:::-;123163:14;123112:7;:66::i;:::-;123099:79;;123246:42;;;;;;;;123257:12;123246:42;;;;123271:16;123246:42;;;123233:55;;123350:10;123306:87;;123314:10;:15;;;123306:87;123331:10;:17;;;;;;;;;;:::i;:::-;123362:12;123376:16;123306:87;;;;;;;;:::i;:::-;;;;;;;;122268:1133;;;;122044:1357;;;;;;:::o;128292:295::-;128520:59;128531:7;128540:5;128547:8;;128557:9;128568:10;;128520;:59::i;:::-;128292:295;;;;;;;:::o;24335:443::-;24465:1;24448:19;;:5;:19;;;24444:91;;24520:1;24491:32;;;;;;;;;;;:::i;:::-;;;;;;;;24444:91;24568:1;24549:21;;:7;:21;;;24545:92;;24622:1;24594:31;;;;;;;;;;;:::i;:::-;;;;;;;;24545:92;24677:5;24647:11;:18;24659:5;24647:18;;;;;;;;;;;;;;;:27;24666:7;24647:27;;;;;;;;;;;;;;;:35;;;;24697:9;24693:78;;;24744:7;24728:31;;24737:5;24728:31;;;24753:5;24728:31;;;;;;:::i;:::-;;;;;;;;24693:78;24335:443;;;;:::o;129503:174::-;129574:16;129648:21;129623;129611:9;:33;;;;:::i;:::-;129610:59;;;;:::i;:::-;129603:66;;129503:174;;;:::o;108677:125::-;108737:7;108772:4;;:21;;107255:2;108772:21;;;;;;;;;:::i;:::-;108764:30;;;;;:::i;:::-;108757:37;;108677:125;;;;:::o;109920:::-;109981:7;110032:2;110024:11;;110001:36;;109920:125;;;:::o;108987:154::-;109049:6;109089:4;;107255:2;109089:42;;;107311:2;109089:42;;;;;;;;;:::i;:::-;109082:50;;;;;:::i;:::-;109075:58;;109068:65;;108987:154;;;;:::o;129908:141::-;129972:16;130020:21;130008:9;:33;;;;;;:::i;:::-;130001:40;;129908:141;;;:::o;136189:472::-;136327:24;136383:3;136368:19;;:3;:19;;;136364:46;;136403:6;136389:21;;136364:46;136508:21;136514:3;136519:9;136508:5;:21::i;:::-;136644:9;136637:16;;136189:472;;;;;:::o;108377:131::-;108441:4;107311:2;108465:35;;:4;;:11;;:35;108458:42;;108377:131;;;;:::o;109308:132::-;109372:12;109404:4;;107311:2;109404:28;;;;;;;;;;;:::i;:::-;109397:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109308:132;;;;:::o;110753:291::-;110942:17;110996:6;111004:7;111013:9;111024:11;110979:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110972:64;;110753:291;;;;;;:::o;20545:1135::-;20651:1;20635:18;;:4;:18;;;20631:552;;20789:5;20773:12;;:21;;;;;;;:::i;:::-;;;;;;;;20631:552;;;20827:19;20849:9;:15;20859:4;20849:15;;;;;;;;;;;;;;;;20827:37;;20897:5;20883:11;:19;20879:117;;;20955:4;20961:11;20974:5;20930:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;20879:117;21151:5;21137:11;:19;21119:9;:15;21129:4;21119:15;;;;;;;;;;;;;;;:37;;;;20812:371;20631:552;21213:1;21199:16;;:2;:16;;;21195:435;;21381:5;21365:12;;:21;;;;;;;;;;;21195:435;;;21598:5;21581:9;:13;21591:2;21581:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;21195:435;21662:2;21647:25;;21656:4;21647:25;;;21666:5;21647:25;;;;;;:::i;:::-;;;;;;;;20545:1135;;;:::o;130280:149::-;130345:15;130399:21;130387:9;:33;;;;:::i;:::-;130373:48;;130280:149;;;:::o;107676:516::-;107814:17;107833:15;107895:1;107874:11;:18;:22;107861:35;;108019:10;:165;;108161:7;108170:13;108144:40;;;;;;;;;:::i;:::-;;;;;;;;;;;;;108019:165;;;108062:7;108071:13;108086:28;108103:10;108086:16;:28::i;:::-;108116:11;108045:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;108019:165;108012:172;;107676:516;;;;;;:::o;135265:580::-;135431:20;135453:24;135525:44;135536:9;135547:12;135561:7;135525:10;:44::i;:::-;135490:79;;;;;;;;135811:26;135817:5;135824:12;135811:5;:26::i;:::-;135265:580;;;;;;;:::o;64621:783::-;64828:31;;:::i;:::-;64995:20;65018:26;65029:4;:14;;;65018:10;:26::i;:::-;64995:49;;65077:1;65059:4;:15;;;:19;65055:53;;;65080:28;65092:4;:15;;;65080:11;:28::i;:::-;65055:53;65201:8;:13;;;65223:12;65256:92;;;;;;;;65272:7;65256:92;;;;;;65281:25;65298:7;65281:16;:25::i;:::-;65256:92;;;;65308:8;65256:92;;;;65318:8;65256:92;;;;65346:1;65328:4;:15;;;:19;65256:92;;;;;65367:14;65201:195;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65121:275;;;64621:783;;;;;;;:::o;22033:213::-;22123:1;22104:21;;:7;:21;;;22100:93;;22178:1;22149:32;;;;;;;;;;;:::i;:::-;;;;;;;;22100:93;22203:35;22219:1;22223:7;22232:5;22203:7;:35::i;:::-;22033:213;;:::o;109615:131::-;109679:7;109730:5;109714:23;;109706:32;;109699:39;;109615:131;;;:::o;22574:211::-;22664:1;22645:21;;:7;:21;;;22641:91;;22717:1;22690:30;;;;;;;;;;;:::i;:::-;;;;;;;;22641:91;22742:35;22750:7;22767:1;22771:5;22742:7;:35::i;:::-;22574:211;;:::o;66113:194::-;66179:17;66226:10;66213:9;:23;66209:62;;66261:9;66245:26;;;;;;;;;;;:::i;:::-;;;;;;;;66209:62;66289:10;66282:17;;66113:194;;;:::o;66693:417::-;66848:15;66866:8;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66848:36;;66918:1;66899:21;;:7;:21;;;66895:54;;66929:20;;;;;;;;;;;;;;66895:54;67026:76;67059:10;67079:8;67090:11;67033:7;67026:32;;;;:76;;;;;;:::i;:::-;66752:358;66693:417;:::o;40049:190::-;40150:81;40170:5;40192;:18;;;40213:4;40219:2;40223:5;40177:53;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40150:19;:81::i;:::-;40049:190;;;;:::o;46235:738::-;46316:18;46345:19;46485:4;46482:1;46475:4;46469:11;46462:4;46456;46452:15;46449:1;46442:5;46435;46430:60;46544:7;46534:180;;46589:4;46583:11;46635:16;46632:1;46627:3;46612:40;46682:16;46677:3;46670:29;46534:180;46742:16;46728:30;;46793:1;46787:8;46772:23;;46400:406;46836:1;46822:10;:15;:68;;46889:1;46874:11;:16;;46822:68;;;46870:1;46848:5;46840:26;;;:31;46822:68;46818:148;;;46947:5;46914:40;;;;;;;;;;;:::i;:::-;;;;;;;;46818:148;46305:668;;46235:738;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;7:99:1:-;59:6;93:5;87:12;77:22;;7:99;;;:::o;112:169::-;196:11;230:6;225:3;218:19;270:4;265:3;261:14;246:29;;112:169;;;;:::o;287:246::-;368:1;378:113;392:6;389:1;386:13;378:113;;;477:1;472:3;468:11;462:18;458:1;453:3;449:11;442:39;414:2;411:1;407:10;402:15;;378:113;;;525:1;516:6;511:3;507:16;500:27;349:184;287:246;;;:::o;539:102::-;580:6;631:2;627:7;622:2;615:5;611:14;607:28;597:38;;539:102;;;:::o;647:377::-;735:3;763:39;796:5;763:39;:::i;:::-;818:71;882:6;877:3;818:71;:::i;:::-;811:78;;898:65;956:6;951:3;944:4;937:5;933:16;898:65;:::i;:::-;988:29;1010:6;988:29;:::i;:::-;983:3;979:39;972:46;;739:285;647:377;;;;:::o;1030:313::-;1143:4;1181:2;1170:9;1166:18;1158:26;;1230:9;1224:4;1220:20;1216:1;1205:9;1201:17;1194:47;1258:78;1331:4;1322:6;1258:78;:::i;:::-;1250:86;;1030:313;;;;:::o;1349:75::-;1382:6;1415:2;1409:9;1399:19;;1349:75;:::o;1430:117::-;1539:1;1536;1529:12;1553:117;1662:1;1659;1652:12;1676:126;1713:7;1753:42;1746:5;1742:54;1731:65;;1676:126;;;:::o;1808:96::-;1845:7;1874:24;1892:5;1874:24;:::i;:::-;1863:35;;1808:96;;;:::o;1910:122::-;1983:24;2001:5;1983:24;:::i;:::-;1976:5;1973:35;1963:63;;2022:1;2019;2012:12;1963:63;1910:122;:::o;2038:139::-;2084:5;2122:6;2109:20;2100:29;;2138:33;2165:5;2138:33;:::i;:::-;2038:139;;;;:::o;2183:77::-;2220:7;2249:5;2238:16;;2183:77;;;:::o;2266:122::-;2339:24;2357:5;2339:24;:::i;:::-;2332:5;2329:35;2319:63;;2378:1;2375;2368:12;2319:63;2266:122;:::o;2394:139::-;2440:5;2478:6;2465:20;2456:29;;2494:33;2521:5;2494:33;:::i;:::-;2394:139;;;;:::o;2539:474::-;2607:6;2615;2664:2;2652:9;2643:7;2639:23;2635:32;2632:119;;;2670:79;;:::i;:::-;2632:119;2790:1;2815:53;2860:7;2851:6;2840:9;2836:22;2815:53;:::i;:::-;2805:63;;2761:117;2917:2;2943:53;2988:7;2979:6;2968:9;2964:22;2943:53;:::i;:::-;2933:63;;2888:118;2539:474;;;;;:::o;3019:90::-;3053:7;3096:5;3089:13;3082:21;3071:32;;3019:90;;;:::o;3115:109::-;3196:21;3211:5;3196:21;:::i;:::-;3191:3;3184:34;3115:109;;:::o;3230:210::-;3317:4;3355:2;3344:9;3340:18;3332:26;;3368:65;3430:1;3419:9;3415:17;3406:6;3368:65;:::i;:::-;3230:210;;;;:::o;3446:117::-;3555:1;3552;3545:12;3593:234;3668:5;3709:3;3700:6;3695:3;3691:16;3687:26;3684:113;;;3716:79;;:::i;:::-;3684:113;3815:6;3806:15;;3593:234;;;;:::o;3833:547::-;3921:6;3970:2;3958:9;3949:7;3945:23;3941:32;3938:119;;;3976:79;;:::i;:::-;3938:119;4124:1;4113:9;4109:17;4096:31;4154:18;4146:6;4143:30;4140:117;;;4176:79;;:::i;:::-;4140:117;4281:82;4355:7;4346:6;4335:9;4331:22;4281:82;:::i;:::-;4271:92;;4067:306;3833:547;;;;:::o;4386:108::-;4463:24;4481:5;4463:24;:::i;:::-;4458:3;4451:37;4386:108;;:::o;4542:523::-;4691:4;4686:3;4682:14;4785:4;4778:5;4774:16;4768:23;4804:63;4861:4;4856:3;4852:14;4838:12;4804:63;:::i;:::-;4706:171;4966:4;4959:5;4955:16;4949:23;4985:63;5042:4;5037:3;5033:14;5019:12;4985:63;:::i;:::-;4887:171;4660:405;4542:523;;:::o;5071:144::-;5168:6;5202:5;5196:12;5186:22;;5071:144;;;:::o;5221:214::-;5350:11;5384:6;5379:3;5372:19;5424:4;5419:3;5415:14;5400:29;;5221:214;;;;:::o;5441:162::-;5538:4;5561:3;5553:11;;5591:4;5586:3;5582:14;5574:22;;5441:162;;;:::o;5609:76::-;5645:7;5674:5;5663:16;;5609:76;;;:::o;5691:105::-;5766:23;5783:5;5766:23;:::i;:::-;5761:3;5754:36;5691:105;;:::o;5802:159::-;5876:11;5910:6;5905:3;5898:19;5950:4;5945:3;5941:14;5926:29;;5802:159;;;;:::o;5967:357::-;6045:3;6073:39;6106:5;6073:39;:::i;:::-;6128:61;6182:6;6177:3;6128:61;:::i;:::-;6121:68;;6198:65;6256:6;6251:3;6244:4;6237:5;6233:16;6198:65;:::i;:::-;6288:29;6310:6;6288:29;:::i;:::-;6283:3;6279:39;6272:46;;6049:275;5967:357;;;;:::o;6380:618::-;6499:3;6535:4;6530:3;6526:14;6629:4;6622:5;6618:16;6612:23;6648:61;6703:4;6698:3;6694:14;6680:12;6648:61;:::i;:::-;6550:169;6808:4;6801:5;6797:16;6791:23;6861:3;6855:4;6851:14;6844:4;6839:3;6835:14;6828:38;6887:73;6955:4;6941:12;6887:73;:::i;:::-;6879:81;;6729:242;6988:4;6981:11;;6504:494;6380:618;;;;:::o;7004:276::-;7133:10;7168:106;7270:3;7262:6;7168:106;:::i;:::-;7154:120;;7004:276;;;;:::o;7286:143::-;7386:4;7418;7413:3;7409:14;7401:22;;7286:143;;;:::o;7489:1151::-;7668:3;7697:84;7775:5;7697:84;:::i;:::-;7797:116;7906:6;7901:3;7797:116;:::i;:::-;7790:123;;7939:3;7984:4;7976:6;7972:17;7967:3;7963:27;8014:86;8094:5;8014:86;:::i;:::-;8123:7;8154:1;8139:456;8164:6;8161:1;8158:13;8139:456;;;8235:9;8229:4;8225:20;8220:3;8213:33;8286:6;8280:13;8314:124;8433:4;8418:13;8314:124;:::i;:::-;8306:132;;8461:90;8544:6;8461:90;:::i;:::-;8451:100;;8580:4;8575:3;8571:14;8564:21;;8199:396;8186:1;8183;8179:9;8174:14;;8139:456;;;8143:14;8611:4;8604:11;;8631:3;8624:10;;7673:967;;;;;7489:1151;;;;:::o;8692:533::-;8845:4;8840:3;8836:14;8940:4;8933:5;8929:16;8923:23;8959:63;9016:4;9011:3;9007:14;8993:12;8959:63;:::i;:::-;8860:172;9126:4;9119:5;9115:16;9109:23;9145:63;9202:4;9197:3;9193:14;9179:12;9145:63;:::i;:::-;9042:176;8814:411;8692:533;;:::o;9231:930::-;9598:4;9636:3;9625:9;9621:19;9613:27;;9650:123;9770:1;9759:9;9755:17;9746:6;9650:123;:::i;:::-;9820:9;9814:4;9810:20;9805:2;9794:9;9790:18;9783:48;9848:168;10011:4;10002:6;9848:168;:::i;:::-;9840:176;;10026:128;10150:2;10139:9;10135:18;10126:6;10026:128;:::i;:::-;9231:930;;;;;;:::o;10167:118::-;10254:24;10272:5;10254:24;:::i;:::-;10249:3;10242:37;10167:118;;:::o;10291:222::-;10384:4;10422:2;10411:9;10407:18;10399:26;;10435:71;10503:1;10492:9;10488:17;10479:6;10435:71;:::i;:::-;10291:222;;;;:::o;10540:230::-;10612:5;10653:2;10644:6;10639:3;10635:16;10631:25;10628:112;;;10659:79;;:::i;:::-;10628:112;10758:6;10749:15;;10540:230;;;;:::o;10776:77::-;10813:7;10842:5;10831:16;;10776:77;;;:::o;10859:122::-;10932:24;10950:5;10932:24;:::i;:::-;10925:5;10922:35;10912:63;;10971:1;10968;10961:12;10912:63;10859:122;:::o;10987:139::-;11033:5;11071:6;11058:20;11049:29;;11087:33;11114:5;11087:33;:::i;:::-;10987:139;;;;:::o;11132:117::-;11241:1;11238;11231:12;11255:117;11364:1;11361;11354:12;11378:117;11487:1;11484;11477:12;11514:552;11571:8;11581:6;11631:3;11624:4;11616:6;11612:17;11608:27;11598:122;;11639:79;;:::i;:::-;11598:122;11752:6;11739:20;11729:30;;11782:18;11774:6;11771:30;11768:117;;;11804:79;;:::i;:::-;11768:117;11918:4;11910:6;11906:17;11894:29;;11972:3;11964:4;11956:6;11952:17;11942:8;11938:32;11935:41;11932:128;;;11979:79;;:::i;:::-;11932:128;11514:552;;;;;:::o;12072:1361::-;12215:6;12223;12231;12239;12247;12255;12263;12312:3;12300:9;12291:7;12287:23;12283:33;12280:120;;;12319:79;;:::i;:::-;12280:120;12439:1;12464:79;12535:7;12526:6;12515:9;12511:22;12464:79;:::i;:::-;12454:89;;12410:143;12592:2;12618:53;12663:7;12654:6;12643:9;12639:22;12618:53;:::i;:::-;12608:63;;12563:118;12748:3;12737:9;12733:19;12720:33;12780:18;12772:6;12769:30;12766:117;;;12802:79;;:::i;:::-;12766:117;12915:64;12971:7;12962:6;12951:9;12947:22;12915:64;:::i;:::-;12897:82;;;;12691:298;13028:3;13055:53;13100:7;13091:6;13080:9;13076:22;13055:53;:::i;:::-;13045:63;;12999:119;13185:3;13174:9;13170:19;13157:33;13217:18;13209:6;13206:30;13203:117;;;13239:79;;:::i;:::-;13203:117;13352:64;13408:7;13399:6;13388:9;13384:22;13352:64;:::i;:::-;13334:82;;;;13128:298;12072:1361;;;;;;;;;;:::o;13439:89::-;13475:7;13515:6;13508:5;13504:18;13493:29;;13439:89;;;:::o;13534:115::-;13619:23;13636:5;13619:23;:::i;:::-;13614:3;13607:36;13534:115;;:::o;13655:218::-;13746:4;13784:2;13773:9;13769:18;13761:26;;13797:69;13863:1;13852:9;13848:17;13839:6;13797:69;:::i;:::-;13655:218;;;;:::o;13879:149::-;13915:7;13955:66;13948:5;13944:78;13933:89;;13879:149;;;:::o;14034:115::-;14119:23;14136:5;14119:23;:::i;:::-;14114:3;14107:36;14034:115;;:::o;14155:101::-;14191:7;14231:18;14224:5;14220:30;14209:41;;14155:101;;;:::o;14262:115::-;14347:23;14364:5;14347:23;:::i;:::-;14342:3;14335:36;14262:115;;:::o;14383:324::-;14500:4;14538:2;14527:9;14523:18;14515:26;;14551:69;14617:1;14606:9;14602:17;14593:6;14551:69;:::i;:::-;14630:70;14696:2;14685:9;14681:18;14672:6;14630:70;:::i;:::-;14383:324;;;;;:::o;14713:::-;14830:4;14868:2;14857:9;14853:18;14845:26;;14881:69;14947:1;14936:9;14932:17;14923:6;14881:69;:::i;:::-;14960:70;15026:2;15015:9;15011:18;15002:6;14960:70;:::i;:::-;14713:324;;;;;:::o;15043:118::-;15130:24;15148:5;15130:24;:::i;:::-;15125:3;15118:37;15043:118;;:::o;15167:222::-;15260:4;15298:2;15287:9;15283:18;15275:26;;15311:71;15379:1;15368:9;15364:17;15355:6;15311:71;:::i;:::-;15167:222;;;;:::o;15395:619::-;15472:6;15480;15488;15537:2;15525:9;15516:7;15512:23;15508:32;15505:119;;;15543:79;;:::i;:::-;15505:119;15663:1;15688:53;15733:7;15724:6;15713:9;15709:22;15688:53;:::i;:::-;15678:63;;15634:117;15790:2;15816:53;15861:7;15852:6;15841:9;15837:22;15816:53;:::i;:::-;15806:63;;15761:118;15918:2;15944:53;15989:7;15980:6;15969:9;15965:22;15944:53;:::i;:::-;15934:63;;15889:118;15395:619;;;;;:::o;16020:86::-;16055:7;16095:4;16088:5;16084:16;16073:27;;16020:86;;;:::o;16112:112::-;16195:22;16211:5;16195:22;:::i;:::-;16190:3;16183:35;16112:112;;:::o;16230:214::-;16319:4;16357:2;16346:9;16342:18;16334:26;;16370:67;16434:1;16423:9;16419:17;16410:6;16370:67;:::i;:::-;16230:214;;;;:::o;16450:93::-;16486:7;16526:10;16519:5;16515:22;16504:33;;16450:93;;;:::o;16549:120::-;16621:23;16638:5;16621:23;:::i;:::-;16614:5;16611:34;16601:62;;16659:1;16656;16649:12;16601:62;16549:120;:::o;16675:137::-;16720:5;16758:6;16745:20;16736:29;;16774:32;16800:5;16774:32;:::i;:::-;16675:137;;;;:::o;16818:472::-;16885:6;16893;16942:2;16930:9;16921:7;16917:23;16913:32;16910:119;;;16948:79;;:::i;:::-;16910:119;17068:1;17093:52;17137:7;17128:6;17117:9;17113:22;17093:52;:::i;:::-;17083:62;;17039:116;17194:2;17220:53;17265:7;17256:6;17245:9;17241:22;17220:53;:::i;:::-;17210:63;;17165:118;16818:472;;;;;:::o;17296:116::-;17366:21;17381:5;17366:21;:::i;:::-;17359:5;17356:32;17346:60;;17402:1;17399;17392:12;17346:60;17296:116;:::o;17418:133::-;17461:5;17499:6;17486:20;17477:29;;17515:30;17539:5;17515:30;:::i;:::-;17418:133;;;;:::o;17557:686::-;17651:6;17659;17708:2;17696:9;17687:7;17683:23;17679:32;17676:119;;;17714:79;;:::i;:::-;17676:119;17862:1;17851:9;17847:17;17834:31;17892:18;17884:6;17881:30;17878:117;;;17914:79;;:::i;:::-;17878:117;18019:82;18093:7;18084:6;18073:9;18069:22;18019:82;:::i;:::-;18009:92;;17805:306;18150:2;18176:50;18218:7;18209:6;18198:9;18194:22;18176:50;:::i;:::-;18166:60;;18121:115;17557:686;;;;;:::o;18299:528::-;18456:4;18451:3;18447:14;18548:4;18541:5;18537:16;18531:23;18567:63;18624:4;18619:3;18615:14;18601:12;18567:63;:::i;:::-;18471:169;18728:4;18721:5;18717:16;18711:23;18747:63;18804:4;18799:3;18795:14;18781:12;18747:63;:::i;:::-;18650:170;18425:402;18299:528;;:::o;18833:342::-;18986:4;19024:2;19013:9;19009:18;19001:26;;19037:131;19165:1;19154:9;19150:17;19141:6;19037:131;:::i;:::-;18833:342;;;;:::o;19181:120::-;19253:23;19270:5;19253:23;:::i;:::-;19246:5;19243:34;19233:62;;19291:1;19288;19281:12;19233:62;19181:120;:::o;19307:137::-;19352:5;19390:6;19377:20;19368:29;;19406:32;19432:5;19406:32;:::i;:::-;19307:137;;;;:::o;19450:470::-;19516:6;19524;19573:2;19561:9;19552:7;19548:23;19544:32;19541:119;;;19579:79;;:::i;:::-;19541:119;19699:1;19724:52;19768:7;19759:6;19748:9;19744:22;19724:52;:::i;:::-;19714:62;;19670:116;19825:2;19851:52;19895:7;19886:6;19875:9;19871:22;19851:52;:::i;:::-;19841:62;;19796:117;19450:470;;;;;:::o;19926:98::-;19977:6;20011:5;20005:12;19995:22;;19926:98;;;:::o;20030:168::-;20113:11;20147:6;20142:3;20135:19;20187:4;20182:3;20178:14;20163:29;;20030:168;;;;:::o;20204:373::-;20290:3;20318:38;20350:5;20318:38;:::i;:::-;20372:70;20435:6;20430:3;20372:70;:::i;:::-;20365:77;;20451:65;20509:6;20504:3;20497:4;20490:5;20486:16;20451:65;:::i;:::-;20541:29;20563:6;20541:29;:::i;:::-;20536:3;20532:39;20525:46;;20294:283;20204:373;;;;:::o;20583:309::-;20694:4;20732:2;20721:9;20717:18;20709:26;;20781:9;20775:4;20771:20;20767:1;20756:9;20752:17;20745:47;20809:76;20880:4;20871:6;20809:76;:::i;:::-;20801:84;;20583:309;;;;:::o;20898:60::-;20926:3;20947:5;20940:12;;20898:60;;;:::o;20964:142::-;21014:9;21047:53;21065:34;21074:24;21092:5;21074:24;:::i;:::-;21065:34;:::i;:::-;21047:53;:::i;:::-;21034:66;;20964:142;;;:::o;21112:126::-;21162:9;21195:37;21226:5;21195:37;:::i;:::-;21182:50;;21112:126;;;:::o;21244:155::-;21323:9;21356:37;21387:5;21356:37;:::i;:::-;21343:50;;21244:155;;;:::o;21405:189::-;21521:66;21581:5;21521:66;:::i;:::-;21516:3;21509:79;21405:189;;:::o;21600:280::-;21722:4;21760:2;21749:9;21745:18;21737:26;;21773:100;21870:1;21859:9;21855:17;21846:6;21773:100;:::i;:::-;21600:280;;;;:::o;21886:329::-;21945:6;21994:2;21982:9;21973:7;21969:23;21965:32;21962:119;;;22000:79;;:::i;:::-;21962:119;22120:1;22145:53;22190:7;22181:6;22170:9;22166:22;22145:53;:::i;:::-;22135:63;;22091:117;21886:329;;;;:::o;22221:218::-;22312:4;22350:2;22339:9;22335:18;22327:26;;22363:69;22429:1;22418:9;22414:17;22405:6;22363:69;:::i;:::-;22221:218;;;;:::o;22445:871::-;22559:6;22567;22575;22583;22632:3;22620:9;22611:7;22607:23;22603:33;22600:120;;;22639:79;;:::i;:::-;22600:120;22759:1;22784:79;22855:7;22846:6;22835:9;22831:22;22784:79;:::i;:::-;22774:89;;22730:143;22940:2;22929:9;22925:18;22912:32;22971:18;22963:6;22960:30;22957:117;;;22993:79;;:::i;:::-;22957:117;23106:64;23162:7;23153:6;23142:9;23138:22;23106:64;:::i;:::-;23088:82;;;;22883:297;23219:3;23246:53;23291:7;23282:6;23271:9;23267:22;23246:53;:::i;:::-;23236:63;;23190:119;22445:871;;;;;;;:::o;23358:607::-;23470:8;23480:6;23530:3;23523:4;23515:6;23511:17;23507:27;23497:122;;23538:79;;:::i;:::-;23497:122;23651:6;23638:20;23628:30;;23681:18;23673:6;23670:30;23667:117;;;23703:79;;:::i;:::-;23667:117;23817:4;23809:6;23805:17;23793:29;;23871:3;23863:4;23855:6;23851:17;23841:8;23837:32;23834:41;23831:128;;;23878:79;;:::i;:::-;23831:128;23358:607;;;;;:::o;23971:637::-;24096:6;24104;24153:2;24141:9;24132:7;24128:23;24124:32;24121:119;;;24159:79;;:::i;:::-;24121:119;24307:1;24296:9;24292:17;24279:31;24337:18;24329:6;24326:30;24323:117;;;24359:79;;:::i;:::-;24323:117;24472:119;24583:7;24574:6;24563:9;24559:22;24472:119;:::i;:::-;24454:137;;;;24250:351;23971:637;;;;;:::o;24614:327::-;24672:6;24721:2;24709:9;24700:7;24696:23;24692:32;24689:119;;;24727:79;;:::i;:::-;24689:119;24847:1;24872:52;24916:7;24907:6;24896:9;24892:22;24872:52;:::i;:::-;24862:62;;24818:116;24614:327;;;;:::o;24947:118::-;25034:24;25052:5;25034:24;:::i;:::-;25029:3;25022:37;24947:118;;:::o;25071:222::-;25164:4;25202:2;25191:9;25187:18;25179:26;;25215:71;25283:1;25272:9;25268:17;25259:6;25215:71;:::i;:::-;25071:222;;;;:::o;25299:813::-;25385:6;25393;25401;25409;25458:2;25446:9;25437:7;25433:23;25429:32;25426:119;;;25464:79;;:::i;:::-;25426:119;25584:1;25609:52;25653:7;25644:6;25633:9;25629:22;25609:52;:::i;:::-;25599:62;;25555:116;25710:2;25736:52;25780:7;25771:6;25760:9;25756:22;25736:52;:::i;:::-;25726:62;;25681:117;25865:2;25854:9;25850:18;25837:32;25896:18;25888:6;25885:30;25882:117;;;25918:79;;:::i;:::-;25882:117;26031:64;26087:7;26078:6;26067:9;26063:22;26031:64;:::i;:::-;26013:82;;;;25808:297;25299:813;;;;;;;:::o;26148:601::-;26254:8;26264:6;26314:3;26307:4;26299:6;26295:17;26291:27;26281:122;;26322:79;;:::i;:::-;26281:122;26435:6;26422:20;26412:30;;26465:18;26457:6;26454:30;26451:117;;;26487:79;;:::i;:::-;26451:117;26601:4;26593:6;26589:17;26577:29;;26655:3;26647:4;26639:6;26635:17;26625:8;26621:32;26618:41;26615:128;;;26662:79;;:::i;:::-;26615:128;26148:601;;;;;:::o;26755:625::-;26874:6;26882;26931:2;26919:9;26910:7;26906:23;26902:32;26899:119;;;26937:79;;:::i;:::-;26899:119;27085:1;27074:9;27070:17;27057:31;27115:18;27107:6;27104:30;27101:117;;;27137:79;;:::i;:::-;27101:117;27250:113;27355:7;27346:6;27335:9;27331:22;27250:113;:::i;:::-;27232:131;;;;27028:345;26755:625;;;;;:::o;27413:236::-;27491:5;27532:2;27523:6;27518:3;27514:16;27510:25;27507:112;;;27538:79;;:::i;:::-;27507:112;27637:6;27628:15;;27413:236;;;;:::o;27655:902::-;27793:6;27801;27809;27858:3;27846:9;27837:7;27833:23;27829:33;27826:120;;;27865:79;;:::i;:::-;27826:120;28013:1;28002:9;27998:17;27985:31;28043:18;28035:6;28032:30;28029:117;;;28065:79;;:::i;:::-;28029:117;28170:82;28244:7;28235:6;28224:9;28220:22;28170:82;:::i;:::-;28160:92;;27956:306;28301:2;28327:85;28404:7;28395:6;28384:9;28380:22;28327:85;:::i;:::-;28317:95;;28272:150;28461:2;28487:53;28532:7;28523:6;28512:9;28508:22;28487:53;:::i;:::-;28477:63;;28432:118;27655:902;;;;;:::o;28563:108::-;28640:24;28658:5;28640:24;:::i;:::-;28635:3;28628:37;28563:108;;:::o;28677:105::-;28752:23;28769:5;28752:23;:::i;:::-;28747:3;28740:36;28677:105;;:::o;28838:518::-;28985:4;28980:3;28976:14;29077:4;29070:5;29066:16;29060:23;29096:63;29153:4;29148:3;29144:14;29130:12;29096:63;:::i;:::-;29000:169;29257:4;29250:5;29246:16;29240:23;29276:63;29333:4;29328:3;29324:14;29310:12;29276:63;:::i;:::-;29179:170;28954:402;28838:518;;:::o;29420:757::-;29585:4;29580:3;29576:14;29672:4;29665:5;29661:16;29655:23;29691:63;29748:4;29743:3;29739:14;29725:12;29691:63;:::i;:::-;29600:164;29847:4;29840:5;29836:16;29830:23;29866:61;29921:4;29916:3;29912:14;29898:12;29866:61;:::i;:::-;29774:163;30018:4;30011:5;30007:16;30001:23;30037:123;30154:4;30149:3;30145:14;30131:12;30037:123;:::i;:::-;29947:223;29554:623;29420:757;;:::o;30183:582::-;30428:4;30466:3;30455:9;30451:19;30443:27;;30480:139;30616:1;30605:9;30601:17;30592:6;30480:139;:::i;:::-;30629:129;30753:3;30742:9;30738:19;30729:6;30629:129;:::i;:::-;30183:582;;;;;:::o;30771:474::-;30839:6;30847;30896:2;30884:9;30875:7;30871:23;30867:32;30864:119;;;30902:79;;:::i;:::-;30864:119;31022:1;31047:53;31092:7;31083:6;31072:9;31068:22;31047:53;:::i;:::-;31037:63;;30993:117;31149:2;31175:53;31220:7;31211:6;31200:9;31196:22;31175:53;:::i;:::-;31165:63;;31120:118;30771:474;;;;;:::o;31251:381::-;31336:6;31385:2;31373:9;31364:7;31360:23;31356:32;31353:119;;;31391:79;;:::i;:::-;31353:119;31511:1;31536:79;31607:7;31598:6;31587:9;31583:22;31536:79;:::i;:::-;31526:89;;31482:143;31251:381;;;;:::o;31638:180::-;31686:77;31683:1;31676:88;31783:4;31780:1;31773:15;31807:4;31804:1;31797:15;31824:320;31868:6;31905:1;31899:4;31895:12;31885:22;;31952:1;31946:4;31942:12;31973:18;31963:81;;32029:4;32021:6;32017:17;32007:27;;31963:81;32091:2;32083:6;32080:14;32060:18;32057:38;32054:84;;32110:18;;:::i;:::-;32054:84;31875:269;31824:320;;;:::o;32150:143::-;32207:5;32238:6;32232:13;32223:22;;32254:33;32281:5;32254:33;:::i;:::-;32150:143;;;;:::o;32299:351::-;32369:6;32418:2;32406:9;32397:7;32393:23;32389:32;32386:119;;;32424:79;;:::i;:::-;32386:119;32544:1;32569:64;32625:7;32616:6;32605:9;32601:22;32569:64;:::i;:::-;32559:74;;32515:128;32299:351;;;;:::o;32656:143::-;32713:5;32744:6;32738:13;32729:22;;32760:33;32787:5;32760:33;:::i;:::-;32656:143;;;;:::o;32805:351::-;32875:6;32924:2;32912:9;32903:7;32899:23;32895:32;32892:119;;;32930:79;;:::i;:::-;32892:119;33050:1;33075:64;33131:7;33122:6;33111:9;33107:22;33075:64;:::i;:::-;33065:74;;33021:128;32805:351;;;;:::o;33162:180::-;33210:77;33207:1;33200:88;33307:4;33304:1;33297:15;33331:4;33328:1;33321:15;33348:115;33433:23;33450:5;33433:23;:::i;:::-;33428:3;33421:36;33348:115;;:::o;33469:328::-;33588:4;33626:2;33615:9;33611:18;33603:26;;33639:69;33705:1;33694:9;33690:17;33681:6;33639:69;:::i;:::-;33718:72;33786:2;33775:9;33771:18;33762:6;33718:72;:::i;:::-;33469:328;;;;;:::o;33803:281::-;33886:27;33908:4;33886:27;:::i;:::-;33878:6;33874:40;34016:6;34004:10;34001:22;33980:18;33968:10;33965:34;33962:62;33959:88;;;34027:18;;:::i;:::-;33959:88;34067:10;34063:2;34056:22;33846:238;33803:281;;:::o;34090:129::-;34124:6;34151:20;;:::i;:::-;34141:30;;34180:33;34208:4;34200:6;34180:33;:::i;:::-;34090:129;;;:::o;34225:348::-;34339:4;34429:18;34421:6;34418:30;34415:56;;;34451:18;;:::i;:::-;34415:56;34501:4;34493:6;34489:17;34481:25;;34561:4;34555;34551:15;34543:23;;34225:348;;;:::o;34579:117::-;34688:1;34685;34678:12;34702:117;34811:1;34808;34801:12;34825:117;34934:1;34931;34924:12;34948:307;35009:4;35099:18;35091:6;35088:30;35085:56;;;35121:18;;:::i;:::-;35085:56;35159:29;35181:6;35159:29;:::i;:::-;35151:37;;35243:4;35237;35233:15;35225:23;;34948:307;;;:::o;35261:146::-;35358:6;35353:3;35348;35335:30;35399:1;35390:6;35385:3;35381:16;35374:27;35261:146;;;:::o;35413:423::-;35490:5;35515:65;35531:48;35572:6;35531:48;:::i;:::-;35515:65;:::i;:::-;35506:74;;35603:6;35596:5;35589:21;35641:4;35634:5;35630:16;35679:3;35670:6;35665:3;35661:16;35658:25;35655:112;;;35686:79;;:::i;:::-;35655:112;35776:54;35823:6;35818:3;35813;35776:54;:::i;:::-;35496:340;35413:423;;;;;:::o;35855:338::-;35910:5;35959:3;35952:4;35944:6;35940:17;35936:27;35926:122;;35967:79;;:::i;:::-;35926:122;36084:6;36071:20;36109:78;36183:3;36175:6;36168:4;36160:6;36156:17;36109:78;:::i;:::-;36100:87;;35916:277;35855:338;;;;:::o;36233:919::-;36319:5;36363:4;36351:9;36346:3;36342:19;36338:30;36335:117;;;36371:79;;:::i;:::-;36335:117;36470:21;36486:4;36470:21;:::i;:::-;36461:30;;36549:1;36589:48;36633:3;36624:6;36613:9;36609:22;36589:48;:::i;:::-;36582:4;36575:5;36571:16;36564:74;36501:148;36711:2;36752:48;36796:3;36787:6;36776:9;36772:22;36752:48;:::i;:::-;36745:4;36738:5;36734:16;36727:74;36659:153;36902:2;36891:9;36887:18;36874:32;36933:18;36925:6;36922:30;36919:117;;;36955:79;;:::i;:::-;36919:117;37075:58;37129:3;37120:6;37109:9;37105:22;37075:58;:::i;:::-;37068:4;37061:5;37057:16;37050:84;36822:323;36233:919;;;;:::o;37194:1026::-;37327:5;37352:118;37368:101;37462:6;37368:101;:::i;:::-;37352:118;:::i;:::-;37343:127;;37490:5;37519:6;37512:5;37505:21;37553:4;37546:5;37542:16;37535:23;;37606:4;37598:6;37594:17;37586:6;37582:30;37635:3;37627:6;37624:15;37621:122;;;37654:79;;:::i;:::-;37621:122;37769:6;37752:462;37786:6;37781:3;37778:15;37752:462;;;37875:3;37862:17;37911:18;37898:11;37895:35;37892:122;;;37933:79;;:::i;:::-;37892:122;38057:11;38049:6;38045:24;38095:74;38165:3;38153:10;38095:74;:::i;:::-;38090:3;38083:87;38199:4;38194:3;38190:14;38183:21;;37828:386;;37812:4;37807:3;37803:14;37796:21;;37752:462;;;37756:21;37333:887;;37194:1026;;;;;:::o;38226:428::-;38418:9;38517:130;38632:14;38624:6;38617:5;38517:130;:::i;:::-;38495:152;;38226:428;;;;:::o;38660:117::-;38769:1;38766;38759:12;38783:117;38892:1;38889;38882:12;38906:469;39011:9;39022;39060:8;39048:10;39045:24;39042:111;;;39072:79;;:::i;:::-;39042:111;39178:6;39168:8;39165:20;39162:107;;;39188:79;;:::i;:::-;39162:107;39319:1;39307:10;39303:18;39295:6;39291:31;39278:44;;39358:10;39348:8;39344:25;39331:38;;38906:469;;;;;;;:::o;39381:147::-;39482:11;39519:3;39504:18;;39381:147;;;;:::o;39534:386::-;39638:3;39666:38;39698:5;39666:38;:::i;:::-;39720:88;39801:6;39796:3;39720:88;:::i;:::-;39713:95;;39817:65;39875:6;39870:3;39863:4;39856:5;39852:16;39817:65;:::i;:::-;39907:6;39902:3;39898:16;39891:23;;39642:278;39534:386;;;;:::o;39948:327::-;40062:3;40083:88;40164:6;40159:3;40083:88;:::i;:::-;40076:95;;40181:56;40230:6;40225:3;40218:5;40181:56;:::i;:::-;40262:6;40257:3;40253:16;40246:23;;39948:327;;;;;:::o;40281:453::-;40473:3;40495:93;40584:3;40575:6;40495:93;:::i;:::-;40488:100;;40605:103;40704:3;40695:6;40687;40605:103;:::i;:::-;40598:110;;40725:3;40718:10;;40281:453;;;;;;:::o;40762:314::-;40858:3;40879:70;40942:6;40937:3;40879:70;:::i;:::-;40872:77;;40959:56;41008:6;41003:3;40996:5;40959:56;:::i;:::-;41040:29;41062:6;41040:29;:::i;:::-;41035:3;41031:39;41024:46;;40762:314;;;;;:::o;41082:329::-;41203:4;41241:2;41230:9;41226:18;41218:26;;41290:9;41284:4;41280:20;41276:1;41265:9;41261:17;41254:47;41318:86;41399:4;41390:6;41382;41318:86;:::i;:::-;41310:94;;41082:329;;;;;:::o;41417:180::-;41465:77;41462:1;41455:88;41562:4;41559:1;41552:15;41586:4;41583:1;41576:15;41603:117;41712:1;41709;41702:12;41726:117;41835:1;41832;41825:12;41849:117;41958:1;41955;41948:12;41972:401;42071:4;42125:11;42112:25;42227:1;42219:6;42215:14;42204:8;42188:14;42184:29;42180:50;42160:18;42156:75;42146:170;;42235:79;;:::i;:::-;42146:170;42347:18;42337:8;42333:33;42325:41;;42076:297;41972:401;;;;:::o;42379:724::-;42456:4;42462:6;42518:11;42505:25;42618:1;42612:4;42608:12;42597:8;42581:14;42577:29;42573:48;42553:18;42549:73;42539:168;;42626:79;;:::i;:::-;42539:168;42738:18;42728:8;42724:33;42716:41;;42790:4;42777:18;42767:28;;42818:18;42810:6;42807:30;42804:117;;;42840:79;;:::i;:::-;42804:117;42948:2;42942:4;42938:13;42930:21;;43005:4;42997:6;42993:17;42977:14;42973:38;42967:4;42963:49;42960:136;;;43015:79;;:::i;:::-;42960:136;42469:634;42379:724;;;;;:::o;43109:120::-;43160:5;43185:38;43219:2;43214:3;43210:12;43205:3;43185:38;:::i;:::-;43176:47;;43109:120;;;;:::o;43235:105::-;43310:23;43327:5;43310:23;:::i;:::-;43305:3;43298:36;43235:105;;:::o;43346:122::-;43398:5;43423:39;43458:2;43453:3;43449:12;43444:3;43423:39;:::i;:::-;43414:48;;43346:122;;;;:::o;43474:120::-;43546:23;43563:5;43546:23;:::i;:::-;43539:5;43536:34;43526:62;;43584:1;43581;43574:12;43526:62;43474:120;:::o;43600:137::-;43645:5;43683:6;43670:20;43661:29;;43699:32;43725:5;43699:32;:::i;:::-;43600:137;;;;:::o;43743:120::-;43794:5;43819:38;43853:2;43848:3;43844:12;43839:3;43819:38;:::i;:::-;43810:47;;43743:120;;;;:::o;43907:761::-;44054:4;44049:3;44045:14;44126:49;44169:4;44162:5;44158:16;44151:5;44126:49;:::i;:::-;44188:61;44243:4;44238:3;44234:14;44220:12;44188:61;:::i;:::-;44069:190;44326:50;44370:4;44363:5;44359:16;44352:5;44326:50;:::i;:::-;44389:63;44446:4;44441:3;44437:14;44423:12;44389:63;:::i;:::-;44269:193;44528:49;44571:4;44564:5;44560:16;44553:5;44528:49;:::i;:::-;44590:61;44645:4;44640:3;44636:14;44622:12;44590:61;:::i;:::-;44472:189;44023:645;43907:761;;:::o;44674:980::-;44985:4;45023:3;45012:9;45008:19;45000:27;;45037:121;45155:1;45144:9;45140:17;45131:6;45037:121;:::i;:::-;45168:72;45236:2;45225:9;45221:18;45212:6;45168:72;:::i;:::-;45288:9;45282:4;45278:20;45272:3;45261:9;45257:19;45250:49;45316:86;45397:4;45388:6;45380;45316:86;:::i;:::-;45308:94;;45412:73;45480:3;45469:9;45465:19;45456:6;45412:73;:::i;:::-;45533:9;45527:4;45523:20;45517:3;45506:9;45502:19;45495:49;45561:86;45642:4;45633:6;45625;45561:86;:::i;:::-;45553:94;;44674:980;;;;;;;;;;:::o;45660:432::-;45748:5;45773:65;45789:48;45830:6;45789:48;:::i;:::-;45773:65;:::i;:::-;45764:74;;45861:6;45854:5;45847:21;45899:4;45892:5;45888:16;45937:3;45928:6;45923:3;45919:16;45916:25;45913:112;;;45944:79;;:::i;:::-;45913:112;46034:52;46079:6;46074:3;46069;46034:52;:::i;:::-;45754:338;45660:432;;;;;:::o;46111:353::-;46177:5;46226:3;46219:4;46211:6;46207:17;46203:27;46193:122;;46234:79;;:::i;:::-;46193:122;46344:6;46338:13;46369:89;46454:3;46446:6;46439:4;46431:6;46427:17;46369:89;:::i;:::-;46360:98;;46183:281;46111:353;;;;:::o;46470:522::-;46549:6;46598:2;46586:9;46577:7;46573:23;46569:32;46566:119;;;46604:79;;:::i;:::-;46566:119;46745:1;46734:9;46730:17;46724:24;46775:18;46767:6;46764:30;46761:117;;;46797:79;;:::i;:::-;46761:117;46902:73;46967:7;46958:6;46947:9;46943:22;46902:73;:::i;:::-;46892:83;;46695:290;46470:522;;;;:::o;46998:332::-;47119:4;47157:2;47146:9;47142:18;47134:26;;47170:71;47238:1;47227:9;47223:17;47214:6;47170:71;:::i;:::-;47251:72;47319:2;47308:9;47304:18;47295:6;47251:72;:::i;:::-;46998:332;;;;;:::o;47336:218::-;47427:4;47465:2;47454:9;47450:18;47442:26;;47478:69;47544:1;47533:9;47529:17;47520:6;47478:69;:::i;:::-;47336:218;;;;:::o;47560:327::-;47618:6;47667:2;47655:9;47646:7;47642:23;47638:32;47635:119;;;47673:79;;:::i;:::-;47635:119;47793:1;47818:52;47862:7;47853:6;47842:9;47838:22;47818:52;:::i;:::-;47808:62;;47764:116;47560:327;;;;:::o;47893:85::-;47938:7;47967:5;47956:16;;47893:85;;;:::o;47984:156::-;48041:9;48074:60;48091:42;48100:32;48126:5;48100:32;:::i;:::-;48091:42;:::i;:::-;48074:60;:::i;:::-;48061:73;;47984:156;;;:::o;48146:145::-;48240:44;48278:5;48240:44;:::i;:::-;48235:3;48228:57;48146:145;;:::o;48297:654::-;48499:4;48537:3;48526:9;48522:19;48514:27;;48551:71;48619:1;48608:9;48604:17;48595:6;48551:71;:::i;:::-;48632:72;48700:2;48689:9;48685:18;48676:6;48632:72;:::i;:::-;48714:79;48789:2;48778:9;48774:18;48765:6;48714:79;:::i;:::-;48840:9;48834:4;48830:20;48825:2;48814:9;48810:18;48803:48;48868:76;48939:4;48930:6;48868:76;:::i;:::-;48860:84;;48297:654;;;;;;;:::o;48957:328::-;49076:4;49114:2;49103:9;49099:18;49091:26;;49127:69;49193:1;49182:9;49178:17;49169:6;49127:69;:::i;:::-;49206:72;49274:2;49263:9;49259:18;49250:6;49206:72;:::i;:::-;48957:328;;;;;:::o;49291:442::-;49440:4;49478:2;49467:9;49463:18;49455:26;;49491:71;49559:1;49548:9;49544:17;49535:6;49491:71;:::i;:::-;49572:72;49640:2;49629:9;49625:18;49616:6;49572:72;:::i;:::-;49654;49722:2;49711:9;49707:18;49698:6;49654:72;:::i;:::-;49291:442;;;;;;:::o;49739:506::-;49896:4;49934:2;49923:9;49919:18;49911:26;;49983:9;49977:4;49973:20;49969:1;49958:9;49954:17;49947:47;50011:76;50082:4;50073:6;50011:76;:::i;:::-;50003:84;;50134:9;50128:4;50124:20;50119:2;50108:9;50104:18;50097:48;50162:76;50233:4;50224:6;50162:76;:::i;:::-;50154:84;;49739:506;;;;;:::o;50251:137::-;50305:5;50336:6;50330:13;50321:22;;50352:30;50376:5;50352:30;:::i;:::-;50251:137;;;;:::o;50394:345::-;50461:6;50510:2;50498:9;50489:7;50485:23;50481:32;50478:119;;;50516:79;;:::i;:::-;50478:119;50636:1;50661:61;50714:7;50705:6;50694:9;50690:22;50661:61;:::i;:::-;50651:71;;50607:125;50394:345;;;;:::o;50745:158::-;50818:11;50852:6;50847:3;50840:19;50892:4;50887:3;50883:14;50868:29;;50745:158;;;;:::o;50909:353::-;50985:3;51013:38;51045:5;51013:38;:::i;:::-;51067:60;51120:6;51115:3;51067:60;:::i;:::-;51060:67;;51136:65;51194:6;51189:3;51182:4;51175:5;51171:16;51136:65;:::i;:::-;51226:29;51248:6;51226:29;:::i;:::-;51221:3;51217:39;51210:46;;50989:273;50909:353;;;;:::o;51268:99::-;51339:21;51354:5;51339:21;:::i;:::-;51334:3;51327:34;51268:99;;:::o;51429:1223::-;51564:3;51600:4;51595:3;51591:14;51689:4;51682:5;51678:16;51672:23;51708:61;51763:4;51758:3;51754:14;51740:12;51708:61;:::i;:::-;51615:164;51865:4;51858:5;51854:16;51848:23;51884:63;51941:4;51936:3;51932:14;51918:12;51884:63;:::i;:::-;51789:168;52042:4;52035:5;52031:16;52025:23;52095:3;52089:4;52085:14;52078:4;52073:3;52069:14;52062:38;52121:71;52187:4;52173:12;52121:71;:::i;:::-;52113:79;;51967:236;52288:4;52281:5;52277:16;52271:23;52341:3;52335:4;52331:14;52324:4;52319:3;52315:14;52308:38;52367:71;52433:4;52419:12;52367:71;:::i;:::-;52359:79;;52213:236;52539:4;52532:5;52528:16;52522:23;52558:57;52609:4;52604:3;52600:14;52586:12;52558:57;:::i;:::-;52459:166;52642:4;52635:11;;51569:1083;51429:1223;;;;:::o;52658:515::-;52845:4;52883:2;52872:9;52868:18;52860:26;;52932:9;52926:4;52922:20;52918:1;52907:9;52903:17;52896:47;52960:124;53079:4;53070:6;52960:124;:::i;:::-;52952:132;;53094:72;53162:2;53151:9;53147:18;53138:6;53094:72;:::i;:::-;52658:515;;;;;:::o;53206:623::-;53296:5;53340:4;53328:9;53323:3;53319:19;53315:30;53312:117;;;53348:79;;:::i;:::-;53312:117;53447:21;53463:4;53447:21;:::i;:::-;53438:30;;53532:1;53572:60;53628:3;53619:6;53608:9;53604:22;53572:60;:::i;:::-;53565:4;53558:5;53554:16;53547:86;53478:166;53709:2;53750:60;53806:3;53797:6;53786:9;53782:22;53750:60;:::i;:::-;53743:4;53736:5;53732:16;53725:86;53654:168;53206:623;;;;:::o;53835:411::-;53935:6;53984:2;53972:9;53963:7;53959:23;53955:32;53952:119;;;53990:79;;:::i;:::-;53952:119;54110:1;54135:94;54221:7;54212:6;54201:9;54197:22;54135:94;:::i;:::-;54125:104;;54081:158;53835:411;;;;:::o;54252:140::-;54300:4;54323:3;54315:11;;54346:3;54343:1;54336:14;54380:4;54377:1;54367:18;54359:26;;54252:140;;;:::o;54398:93::-;54435:6;54482:2;54477;54470:5;54466:14;54462:23;54452:33;;54398:93;;;:::o;54497:107::-;54541:8;54591:5;54585:4;54581:16;54560:37;;54497:107;;;;:::o;54610:393::-;54679:6;54729:1;54717:10;54713:18;54752:97;54782:66;54771:9;54752:97;:::i;:::-;54870:39;54900:8;54889:9;54870:39;:::i;:::-;54858:51;;54942:4;54938:9;54931:5;54927:21;54918:30;;54991:4;54981:8;54977:19;54970:5;54967:30;54957:40;;54686:317;;54610:393;;;;;:::o;55009:142::-;55059:9;55092:53;55110:34;55119:24;55137:5;55119:24;:::i;:::-;55110:34;:::i;:::-;55092:53;:::i;:::-;55079:66;;55009:142;;;:::o;55157:75::-;55200:3;55221:5;55214:12;;55157:75;;;:::o;55238:269::-;55348:39;55379:7;55348:39;:::i;:::-;55409:91;55458:41;55482:16;55458:41;:::i;:::-;55450:6;55443:4;55437:11;55409:91;:::i;:::-;55403:4;55396:105;55314:193;55238:269;;;:::o;55513:73::-;55558:3;55513:73;:::o;55592:189::-;55669:32;;:::i;:::-;55710:65;55768:6;55760;55754:4;55710:65;:::i;:::-;55645:136;55592:189;;:::o;55787:186::-;55847:120;55864:3;55857:5;55854:14;55847:120;;;55918:39;55955:1;55948:5;55918:39;:::i;:::-;55891:1;55884:5;55880:13;55871:22;;55847:120;;;55787:186;;:::o;55979:541::-;56079:2;56074:3;56071:11;56068:445;;;56113:37;56144:5;56113:37;:::i;:::-;56196:29;56214:10;56196:29;:::i;:::-;56186:8;56182:44;56379:2;56367:10;56364:18;56361:49;;;56400:8;56385:23;;56361:49;56423:80;56479:22;56497:3;56479:22;:::i;:::-;56469:8;56465:37;56452:11;56423:80;:::i;:::-;56083:430;;56068:445;55979:541;;;:::o;56526:117::-;56580:8;56630:5;56624:4;56620:16;56599:37;;56526:117;;;;:::o;56649:169::-;56693:6;56726:51;56774:1;56770:6;56762:5;56759:1;56755:13;56726:51;:::i;:::-;56722:56;56807:4;56801;56797:15;56787:25;;56700:118;56649:169;;;;:::o;56823:295::-;56899:4;57045:29;57070:3;57064:4;57045:29;:::i;:::-;57037:37;;57107:3;57104:1;57100:11;57094:4;57091:21;57083:29;;56823:295;;;;:::o;57123:1390::-;57238:36;57270:3;57238:36;:::i;:::-;57339:18;57331:6;57328:30;57325:56;;;57361:18;;:::i;:::-;57325:56;57405:38;57437:4;57431:11;57405:38;:::i;:::-;57490:66;57549:6;57541;57535:4;57490:66;:::i;:::-;57583:1;57607:4;57594:17;;57639:2;57631:6;57628:14;57656:1;57651:617;;;;58312:1;58329:6;58326:77;;;58378:9;58373:3;58369:19;58363:26;58354:35;;58326:77;58429:67;58489:6;58482:5;58429:67;:::i;:::-;58423:4;58416:81;58285:222;57621:886;;57651:617;57703:4;57699:9;57691:6;57687:22;57737:36;57768:4;57737:36;:::i;:::-;57795:1;57809:208;57823:7;57820:1;57817:14;57809:208;;;57902:9;57897:3;57893:19;57887:26;57879:6;57872:42;57953:1;57945:6;57941:14;57931:24;;58000:2;57989:9;57985:18;57972:31;;57846:4;57843:1;57839:12;57834:17;;57809:208;;;58045:6;58036:7;58033:19;58030:179;;;58103:9;58098:3;58094:19;58088:26;58146:48;58188:4;58180:6;58176:17;58165:9;58146:48;:::i;:::-;58138:6;58131:64;58053:156;58030:179;58255:1;58251;58243:6;58239:14;58235:22;58229:4;58222:36;57658:610;;;57621:886;;57213:1300;;;57123:1390;;:::o;58519:151::-;58623:6;58657:5;58651:12;58641:22;;58519:151;;;:::o;58676:221::-;58812:11;58846:6;58841:3;58834:19;58886:4;58881:3;58877:14;58862:29;;58676:221;;;;:::o;58903:169::-;59007:4;59030:3;59022:11;;59060:4;59055:3;59051:14;59043:22;;58903:169;;;:::o;59078:105::-;59153:23;59170:5;59153:23;:::i;:::-;59148:3;59141:36;59078:105;;:::o;59253:793::-;59386:3;59422:4;59417:3;59413:14;59508:4;59501:5;59497:16;59491:23;59527:61;59582:4;59577:3;59573:14;59559:12;59527:61;:::i;:::-;59437:161;59683:4;59676:5;59672:16;59666:23;59702:61;59757:4;59752:3;59748:14;59734:12;59702:61;:::i;:::-;59608:165;59858:4;59851:5;59847:16;59841:23;59911:3;59905:4;59901:14;59894:4;59889:3;59885:14;59878:38;59937:71;60003:4;59989:12;59937:71;:::i;:::-;59929:79;;59783:236;60036:4;60029:11;;59391:655;59253:793;;;;:::o;60052:304::-;60195:10;60230:120;60346:3;60338:6;60230:120;:::i;:::-;60216:134;;60052:304;;;;:::o;60362:150::-;60469:4;60501;60496:3;60492:14;60484:22;;60362:150;;;:::o;60586:1207::-;60779:3;60808:91;60893:5;60808:91;:::i;:::-;60915:123;61031:6;61026:3;60915:123;:::i;:::-;60908:130;;61064:3;61109:4;61101:6;61097:17;61092:3;61088:27;61139:93;61226:5;61139:93;:::i;:::-;61255:7;61286:1;61271:477;61296:6;61293:1;61290:13;61271:477;;;61367:9;61361:4;61357:20;61352:3;61345:33;61418:6;61412:13;61446:138;61579:4;61564:13;61446:138;:::i;:::-;61438:146;;61607:97;61697:6;61607:97;:::i;:::-;61597:107;;61733:4;61728:3;61724:14;61717:21;;61331:417;61318:1;61315;61311:9;61306:14;;61271:477;;;61275:14;61764:4;61757:11;;61784:3;61777:10;;60784:1009;;;;;60586:1207;;;;:::o;61799:521::-;62016:4;62054:2;62043:9;62039:18;62031:26;;62103:9;62097:4;62093:20;62089:1;62078:9;62074:17;62067:47;62131:182;62308:4;62299:6;62131:182;:::i;:::-;62123:190;;61799:521;;;;:::o;62353:590::-;62432:5;62476:4;62464:9;62459:3;62455:19;62451:30;62448:117;;;62484:79;;:::i;:::-;62448:117;62583:21;62599:4;62583:21;:::i;:::-;62574:30;;62668:1;62708:49;62753:3;62744:6;62733:9;62729:22;62708:49;:::i;:::-;62701:4;62694:5;62690:16;62683:75;62614:155;62834:2;62875:49;62920:3;62911:6;62900:9;62896:22;62875:49;:::i;:::-;62868:4;62861:5;62857:16;62850:75;62779:157;62353:590;;;;:::o;62949:389::-;63038:6;63087:2;63075:9;63066:7;63062:23;63058:32;63055:119;;;63093:79;;:::i;:::-;63055:119;63213:1;63238:83;63313:7;63304:6;63293:9;63289:22;63238:83;:::i;:::-;63228:93;;63184:147;62949:389;;;;:::o;63344:438::-;63491:4;63529:2;63518:9;63514:18;63506:26;;63542:69;63608:1;63597:9;63593:17;63584:6;63542:69;:::i;:::-;63621:72;63689:2;63678:9;63674:18;63665:6;63621:72;:::i;:::-;63703;63771:2;63760:9;63756:18;63747:6;63703:72;:::i;:::-;63344:438;;;;;;:::o;63788:180::-;63836:77;63833:1;63826:88;63933:4;63930:1;63923:15;63957:4;63954:1;63947:15;63974:180;64022:77;64019:1;64012:88;64119:4;64116:1;64109:15;64143:4;64140:1;64133:15;64160:185;64200:1;64217:20;64235:1;64217:20;:::i;:::-;64212:25;;64251:20;64269:1;64251:20;:::i;:::-;64246:25;;64290:1;64280:35;;64295:18;;:::i;:::-;64280:35;64337:1;64334;64330:9;64325:14;;64160:185;;;;:::o;64351:410::-;64391:7;64414:20;64432:1;64414:20;:::i;:::-;64409:25;;64448:20;64466:1;64448:20;:::i;:::-;64443:25;;64503:1;64500;64496:9;64525:30;64543:11;64525:30;:::i;:::-;64514:41;;64704:1;64695:7;64691:15;64688:1;64685:22;64665:1;64658:9;64638:83;64615:139;;64734:18;;:::i;:::-;64615:139;64399:362;64351:410;;;;:::o;64767:96::-;64825:6;64853:3;64843:13;;64767:96;;;;:::o;64961:552::-;65052:5;65083:45;65124:3;65117:5;65083:45;:::i;:::-;65153:5;65177:41;65208:8;65195:22;65177:41;:::i;:::-;65168:50;;65242:2;65234:6;65231:14;65228:278;;;65313:169;65398:66;65368:6;65364:2;65360:15;65357:1;65353:23;65313:169;:::i;:::-;65290:5;65269:227;65260:236;;65228:278;65058:455;;64961:552;;;;:::o;65519:149::-;65555:7;65595:66;65588:5;65584:78;65573:89;;65519:149;;;:::o;65674:548::-;65764:5;65795:45;65836:3;65829:5;65795:45;:::i;:::-;65865:5;65889:40;65919:8;65906:22;65889:40;:::i;:::-;65880:49;;65953:1;65945:6;65942:13;65939:276;;;66023:168;66107:66;66077:6;66074:1;66070:14;66067:1;66063:22;66023:168;:::i;:::-;66000:5;65979:226;65970:235;;65939:276;65770:452;;65674:548;;;;:::o;66228:96::-;66262:8;66311:5;66306:3;66302:15;66281:36;;66228:96;;;:::o;66330:94::-;66368:7;66397:21;66412:5;66397:21;:::i;:::-;66386:32;;66330:94;;;:::o;66430:153::-;66533:43;66552:23;66569:5;66552:23;:::i;:::-;66533:43;:::i;:::-;66528:3;66521:56;66430:153;;:::o;66589:96::-;66623:8;66672:5;66667:3;66663:15;66642:36;;66589:96;;;:::o;66691:94::-;66729:7;66758:21;66773:5;66758:21;:::i;:::-;66747:32;;66691:94;;;:::o;66791:153::-;66894:43;66913:23;66930:5;66913:23;:::i;:::-;66894:43;:::i;:::-;66889:3;66882:56;66791:153;;:::o;66950:79::-;66989:7;67018:5;67007:16;;66950:79;;;:::o;67035:157::-;67140:45;67160:24;67178:5;67160:24;:::i;:::-;67140:45;:::i;:::-;67135:3;67128:58;67035:157;;:::o;67198:684::-;67408:3;67423:73;67492:3;67483:6;67423:73;:::i;:::-;67521:1;67516:3;67512:11;67505:18;;67533:73;67602:3;67593:6;67533:73;:::i;:::-;67631:1;67626:3;67622:11;67615:18;;67643:75;67714:3;67705:6;67643:75;:::i;:::-;67743:2;67738:3;67734:12;67727:19;;67763:93;67852:3;67843:6;67763:93;:::i;:::-;67756:100;;67873:3;67866:10;;67198:684;;;;;;;:::o;67888:191::-;67928:3;67947:20;67965:1;67947:20;:::i;:::-;67942:25;;67981:20;67999:1;67981:20;:::i;:::-;67976:25;;68024:1;68021;68017:9;68010:16;;68045:3;68042:1;68039:10;68036:36;;;68052:18;;:::i;:::-;68036:36;67888:191;;;;:::o;68085:79::-;68124:7;68153:5;68142:16;;68085:79;;;:::o;68170:157::-;68275:45;68295:24;68313:5;68295:24;:::i;:::-;68275:45;:::i;:::-;68270:3;68263:58;68170:157;;:::o;68333:392::-;68471:3;68486:75;68557:3;68548:6;68486:75;:::i;:::-;68586:2;68581:3;68577:12;68570:19;;68599:73;68668:3;68659:6;68599:73;:::i;:::-;68697:1;68692:3;68688:11;68681:18;;68716:3;68709:10;;68333:392;;;;;:::o;68731:689::-;68943:3;68958:75;69029:3;69020:6;68958:75;:::i;:::-;69058:2;69053:3;69049:12;69042:19;;69071:73;69140:3;69131:6;69071:73;:::i;:::-;69169:1;69164:3;69160:11;69153:18;;69181:75;69252:3;69243:6;69181:75;:::i;:::-;69281:2;69276:3;69272:12;69265:19;;69301:93;69390:3;69381:6;69301:93;:::i;:::-;69294:100;;69411:3;69404:10;;68731:689;;;;;;;:::o;69426:143::-;69483:5;69514:6;69508:13;69499:22;;69530:33;69557:5;69530:33;:::i;:::-;69426:143;;;;:::o;69575:141::-;69631:5;69662:6;69656:13;69647:22;;69678:32;69704:5;69678:32;:::i;:::-;69575:141;;;;:::o;69753:817::-;69847:5;69891:4;69879:9;69874:3;69870:19;69866:30;69863:117;;;69899:79;;:::i;:::-;69863:117;69998:21;70014:4;69998:21;:::i;:::-;69989:30;;70078:1;70118:60;70174:3;70165:6;70154:9;70150:22;70118:60;:::i;:::-;70111:4;70104:5;70100:16;70093:86;70029:161;70250:2;70291:59;70346:3;70337:6;70326:9;70322:22;70291:59;:::i;:::-;70284:4;70277:5;70273:16;70266:85;70200:162;70420:2;70461:90;70547:3;70538:6;70527:9;70523:22;70461:90;:::i;:::-;70454:4;70447:5;70443:16;70436:116;70372:191;69753:817;;;;:::o;70576:420::-;70680:6;70729:3;70717:9;70708:7;70704:23;70700:33;70697:120;;;70736:79;;:::i;:::-;70697:120;70856:1;70881:98;70971:7;70962:6;70951:9;70947:22;70881:98;:::i;:::-;70871:108;;70827:162;70576:420;;;;:::o;71002:442::-;71151:4;71189:2;71178:9;71174:18;71166:26;;71202:71;71270:1;71259:9;71255:17;71246:6;71202:71;:::i;:::-;71283:72;71351:2;71340:9;71336:18;71327:6;71283:72;:::i;:::-;71365;71433:2;71422:9;71418:18;71409:6;71365:72;:::i;:::-;71002:442;;;;;;:::o
Swarm Source
ipfs://622fbd590948ecab9ea959072ad9fa78ce94f7cfcc6e3cddbf038626189bbb26
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.