Contract 0xff7bc045e3f016915b0338290a56068b14d52a71

Contract Overview

Balance:
0 MATIC
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x3d2bfe4f1a95c63b5642667f3cf3dc0f55f262b0cf7e399dc4438487e60ef8e80x60806040243409102022-01-28 8:08:05154 days 11 hrs ago0x7be74f23e1b0374ba5a759521326d99dd3960b29 IN  Create: ERC20InvictusFund0 MATIC0.009528485961 1.999999992
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC20InvictusFund

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2022-01-28
*/

// Sources flattened with hardhat v2.6.5 https://hardhat.org

// File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected]

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Upgradeable {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
    /**
     * @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-upgradeable/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


// File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)

pragma solidity ^0.8.0;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
 * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() initializer {}
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        // If the contract is initializing we ignore whether _initialized is set in order to support multiple
        // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
        // contract may have been reentered.
        require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} modifier, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    function _isConstructor() private view returns (bool) {
        return !AddressUpgradeable.isContract(address(this));
    }
}


// File @openzeppelin/contracts-upgradeable/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract ContextUpgradeable is Initializable {
    function __Context_init() internal onlyInitializing {
        __Context_init_unchained();
    }

    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
    uint256[50] private __gap;
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
        __Context_init_unchained();
        __ERC20_init_unchained(name_, symbol_);
    }

    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * 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 override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * 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.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` 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.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
    uint256[45] private __gap;
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {
    function __ERC20Burnable_init() internal onlyInitializing {
        __Context_init_unchained();
        __ERC20Burnable_init_unchained();
    }

    function __ERC20Burnable_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        unchecked {
            _approve(account, _msgSender(), currentAllowance - amount);
        }
        _burn(account, amount);
    }
    uint256[50] private __gap;
}


// File @openzeppelin/contracts-upgradeable/security/[email protected]


// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    function __Pausable_init() internal onlyInitializing {
        __Context_init_unchained();
        __Pausable_init_unchained();
    }

    function __Pausable_init_unchained() internal onlyInitializing {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
    uint256[49] private __gap;
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)

pragma solidity ^0.8.0;



/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {
    function __ERC20Pausable_init() internal onlyInitializing {
        __Context_init_unchained();
        __Pausable_init_unchained();
        __ERC20Pausable_init_unchained();
    }

    function __ERC20Pausable_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
    uint256[50] private __gap;
}


// File @openzeppelin/contracts-upgradeable/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControlUpgradeable {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


// File @openzeppelin/contracts-upgradeable/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}


// File @openzeppelin/contracts-upgradeable/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library StringsUpgradeable {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}


// File @openzeppelin/contracts-upgradeable/utils/introspection/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165Upgradeable {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


// File @openzeppelin/contracts-upgradeable/utils/introspection/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
    function __ERC165_init() internal onlyInitializing {
        __ERC165_init_unchained();
    }

    function __ERC165_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165Upgradeable).interfaceId;
    }
    uint256[50] private __gap;
}


// File @openzeppelin/contracts-upgradeable/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)

pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {
    function __AccessControl_init() internal onlyInitializing {
        __Context_init_unchained();
        __ERC165_init_unchained();
        __AccessControl_init_unchained();
    }

    function __AccessControl_init_unchained() internal onlyInitializing {
    }
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        StringsUpgradeable.toHexString(uint160(account), 20),
                        " is missing role ",
                        StringsUpgradeable.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
    uint256[49] private __gap;
}


// File @openzeppelin/contracts-upgradeable/utils/structs/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSetUpgradeable {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}


// File @openzeppelin/contracts-upgradeable/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)

pragma solidity ^0.8.0;




/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {
    function __AccessControlEnumerable_init() internal onlyInitializing {
        __Context_init_unchained();
        __ERC165_init_unchained();
        __AccessControl_init_unchained();
        __AccessControlEnumerable_init_unchained();
    }

    function __AccessControlEnumerable_init_unchained() internal onlyInitializing {
    }
    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

    mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override {
        super._grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override {
        super._revokeRole(role, account);
        _roleMembers[role].remove(account);
    }
    uint256[49] private __gap;
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/presets/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/presets/ERC20PresetMinterPauser.sol)

pragma solidity ^0.8.0;






/**
 * @dev {ERC20} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 */
contract ERC20PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable {
    function initialize(string memory name, string memory symbol) public virtual initializer {
        __ERC20PresetMinterPauser_init(name, symbol);
    }
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * See {ERC20-constructor}.
     */
    function __ERC20PresetMinterPauser_init(string memory name, string memory symbol) internal onlyInitializing {
        __Context_init_unchained();
        __ERC165_init_unchained();
        __AccessControl_init_unchained();
        __AccessControlEnumerable_init_unchained();
        __ERC20_init_unchained(name, symbol);
        __ERC20Burnable_init_unchained();
        __Pausable_init_unchained();
        __ERC20Pausable_init_unchained();
        __ERC20PresetMinterPauser_init_unchained(name, symbol);
    }

    function __ERC20PresetMinterPauser_init_unchained(string memory name, string memory symbol) internal onlyInitializing {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
    }

    /**
     * @dev Creates `amount` new tokens for `to`.
     *
     * See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to, uint256 amount) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
        _mint(to, amount);
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
        _unpause();
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override(ERC20Upgradeable, ERC20PausableUpgradeable) {
        super._beforeTokenTransfer(from, to, amount);
    }
    uint256[50] private __gap;
}


// File @openzeppelin/contracts-upgradeable/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @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.
 *
 * By default, the owner account will be the one that deploys the contract. 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal onlyInitializing {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal onlyInitializing {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing 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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _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);
    }
    uint256[49] private __gap;
}


// File @openzeppelin/contracts-upgradeable/token/ERC20/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;


/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20Upgradeable {
    using AddressUpgradeable for address;

    function safeTransfer(
        IERC20Upgradeable token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20Upgradeable token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20Upgradeable token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20Upgradeable token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20Upgradeable token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}


// File @openzeppelin/contracts-upgradeable/utils/math/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library MathUpgradeable {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}


// File contracts/InvictusWhitelist.sol


pragma solidity 0.8.11;




/**
 * Manages whitelisted addresses.
 *
 */
contract InvictusWhitelist is Initializable, OwnableUpgradeable, AccessControlUpgradeable {
    bytes32 public constant WHITELIST_USER_ROLE = keccak256('WHITELIST_USER_ROLE');
    bytes32 public constant WHITELIST_ADMIN_ROLE = keccak256('WHITELIST_ADMIN_ROLE');

    function initialize() public initializer {
        __Ownable_init();
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(WHITELIST_ADMIN_ROLE, msg.sender);
        _grantRole(WHITELIST_USER_ROLE, msg.sender);
        _setRoleAdmin(WHITELIST_USER_ROLE, WHITELIST_ADMIN_ROLE);
    }

    function whitelist(address participant) public onlyWhitelistAdmin {
        if (!hasRole(WHITELIST_USER_ROLE, participant)) {
            grantRole(WHITELIST_USER_ROLE, participant);
        }
    }
 
    function removeWhitelist(address account) public onlyWhitelistAdmin {
        revokeRole(WHITELIST_USER_ROLE, account);
    }

    function isWhitelisted(address account) public view returns (bool) {
        return hasRole(WHITELIST_USER_ROLE, account);
    }

    function versionRecipient() external pure returns (string memory) {
        return "1";
    }
    
    modifier onlyWhitelistAdmin() {
        require(hasRole(WHITELIST_ADMIN_ROLE, _msgSender()), 'InvictusWhitelist: must have whitelist admin role');
        _;
    }

}


// File contracts/ERC20InvictusFund.sol


pragma solidity 0.8.11;








contract ERC20InvictusFund is OwnableUpgradeable, ERC20PresetMinterPauserUpgradeable {
  using SafeERC20Upgradeable for ERC20Upgradeable;
  address public constant DEAL_ADDRESS = 0x000000000000000000000000000000000000deA1;
  bytes32 public constant PRICING_ORACLE_ROLE = keccak256("PRICING_ORACLE_ROLE");
  bytes32 public constant INVESTMENT_ORACLE_ROLE = keccak256("INVESTMENT_ORACLE_ROLE");

  struct Investment {
    uint256 amount;
    uint256 timestamp;
    uint256 chainId;
    uint256 index;
    string investmentCurrency;
    string transactionHash;
    address investor;
  }

  struct Redemption {
    uint256 amount;
    uint256 timestamp;
    string ticker;
    address investor;
  }

  struct Ticker {
    Price price;
    address contractAddress;
    uint8 decimals;
  }

  struct Price {
    uint256 numerator;
    uint256 denominator;
  }

  Redemption[] public redemptions;
  Investment[] public investments;
  string[] public supportedTickers;

  mapping(string => mapping(uint256 => bool)) public investmentTxIndex;
  mapping(string => Ticker) public tickers;

  address public whitelistContract;
  address public feeAddress;
  uint256 public minTokenRedemption;
  uint24 public maxDealingsPerTx;
  uint24 public exitFeePercentage;
  uint256 public denominator;

  uint32 public cutOffTime;
  uint24 public dealingNonce;

  event RedemptionRequest(uint256 amount, uint256 timestamp, string ticker, address investor);
  event InvestmentRequest(
    uint256 amount,
    uint256 timestamp,
    string investmentCurrency,
    string transactionHash,
    address investor,
    uint256 chainId,
    uint256 index
  );
  event Dealing(uint256 dealingNonce);
  event AssetPriceUpdated(uint256 numerator, string ticker);
  event RedemptionEvent(
    uint256 eventId,
    uint256 TokenAmount,
    uint256 redemtionCurrencyAmount,
    string ticker,
    address particpant,
    uint128 dealingNonce
  );
  event InvestmentEvent(
    uint256 eventId,
    uint256 investmentCurrencyAmount,
    uint256 tokenAmount,
    string investmentCurrency,
    string transactionHash,
    address investor,
    uint128 dealingNonce
  );
  event IncreaseTokenAmendment(address investor, uint256 amount, string reason, string txHash);
  event DecreaseTokenAmendment(address investor, uint256 amount, string reason, string txHash);
  event RedemptionsLeftInQueue(uint256 dealingNonce);
  event InvestmentsLeftInQueue(uint256 dealingNonce);
  event TokensClaimed(address indexed token, uint256 balance);
  event RemoveLiquidity(address indexed account, uint256 value);
  event UpdateExitFeePercentage(uint24 newExitFeePercentage);

  ////////////////////////////////////////////////////////////////////// Initializer ////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * @dev Initialize the contract.
   * @param name The name of the token.
   * @param symbol The symbol of the token, usually a shorter version of the name.
   * @param whitelistContractInput The whitelist contract address.
   * @param feeAddressInput The fee address used to pay exit fees to.
   * @param _cutOffTime The cut off time for investments and redemptions to be accepted for next dealing
   */
  function initializeInvictusFund(
    string memory name,
    string memory symbol,
    address whitelistContractInput,
    address feeAddressInput,
    uint32 _cutOffTime
  ) public initializer {
    __ERC20PresetMinterPauser_init(name, symbol);
    __Ownable_init();
    __Pausable_init();

    require(whitelistContractInput != address(0), "no whitelist address");

    whitelistContract = whitelistContractInput;
    feeAddress = feeAddressInput;

    minTokenRedemption = 1 ether;
    maxDealingsPerTx = 25;
    exitFeePercentage = 50;
    cutOffTime = _cutOffTime;
    dealingNonce = 0;
    denominator = 1 ether;
  }

  /**
   * @dev Purges the investments and redemption arrays.
   */
  function purgeQueues() external onlyOwner {
    delete redemptions;
    delete investments;
  }

  /**
   * @dev Purges the supported tickers array.
   */
  function purgeSupportedCurrencies() external onlyOwner {
    delete supportedTickers;
  }

  /**
   * @dev Calculates exit fee amount for redemptions.
   * @param redemptionAmount The redemption amount.
   */
  function calculateExitFee(uint256 redemptionAmount) private view returns (uint256) {
    require((redemptionAmount * 10000) / 10000 == redemptionAmount, "too small");
    return (redemptionAmount * exitFeePercentage) / 10000;
  }

  /**
   * @dev Request redemtion in a supported ticker to be processed on the next dealing.
   * @param withdrawAmount The amount of fund tokens to redeem.
   * @param ticker The ticker you would like to recieved your redemption in.
   */
  function queueRedemption(uint256 withdrawAmount, string memory ticker)
    external
    onlyWhitelisted
    onlyRedemptionTickers(ticker)
  {
    require(balanceOf(_msgSender()) >= withdrawAmount, "Balance to low");
    require(withdrawAmount >= minTokenRedemption, "Too few tokens");

    transfer(DEAL_ADDRESS, withdrawAmount);
    redemptions.push(Redemption(withdrawAmount, block.timestamp, ticker, _msgSender()));
    emit RedemptionRequest(withdrawAmount, block.timestamp, ticker, _msgSender());
  }

  /**
   * @dev Returns the length of the redemptions array.
   */
  function redemptionsLength() public view returns (uint256) {
    return redemptions.length;
  }

  /**
   * @dev Returns the length of the investments array.
   */
  function investmentsLength() public view returns (uint256) {
    return investments.length;
  }

  /**
   * @dev Queues investment in a supported ticker to be processed on the next dealing.
   * @param amount The amount that was invested.
   * @param investmentTicker The ticker if the currency you made your investment in.
   * @param transactionHash The transaction hash of your investment.
   * @param investor The address of your wallet that you are receiving the investment in.
   * @param chainId The chain id of the blockchain that the investment was made on.
   * @param index Integer of the transactions index position in the block.
   */
  function queueInvestment(
    uint256 amount,
    string memory investmentTicker,
    string memory transactionHash,
    address investor,
    uint256 chainId,
    uint256 index
  ) external onlyInvestmentOracle {
    require(tickers[investmentTicker].price.numerator != 0, "Invalid ticker");
    require(amount > 0, "Invalid amount");
    require(!investmentTxIndex[transactionHash][index], "Index not unique");

    investmentTxIndex[transactionHash][index] = true;
    investments.push(
      Investment(amount, block.timestamp, chainId, index, investmentTicker, transactionHash, investor)
    );
    emit InvestmentRequest(amount, block.timestamp, investmentTicker, transactionHash, investor, chainId, index);
  }

  /**
   * @dev Initiate dealing. Processes queued up investments and redeptions.
   * @param _rates List of rates for the tickers passed in.
   */
  function dealing(uint256[] calldata _rates) external onlyPricingOracle {
    require(_rates.length > 0, "No rates");
    updateTickerPrices(_rates);

    if (_handleInvestmentsDealing() && _handleRedemptionsDealing()) {
      updateDealingNonce(dealingNonce + 1);
    }

    emit Dealing(dealingNonce);
  }

  /**
   * @dev Allows owner to claim any ERC20 tokens.
   * @param token The ERC20 token that you are trying to claim.
   */
  function claimTokens(ERC20Upgradeable token) external onlyOwner {
    require(address(token) != address(0), "Invalid address");
    uint256 balance = token.balanceOf(address(this));

    token.safeTransfer(owner(), balance);
    emit TokensClaimed(address(token), balance);
  }

  /**
   * @dev Allows owner to transfer any ERC20 token from the contract to the function caller.
   * @param amount The amount of tokens to remove.
   * @param ticker The token ticker that you want remove liquidity for.
   */
  function removeLiquidity(uint256 amount, string memory ticker)
    external
    onlyPricingOracle
    onlyRedemptionTickers(ticker)
  {
    ERC20Upgradeable(tickers[ticker].contractAddress).safeTransfer(_msgSender(), amount);
    emit RemoveLiquidity(_msgSender(), amount);
  }

  /**
   * @dev Set the maximum number of redemptions to be processed per dealing transaction.
   * @param newDealingsPerTx The amount of dealings per dealing transaction. (redemptions and investments)
   */
  function setDealingsPerTx(uint24 newDealingsPerTx) external onlyOwner {
    require(newDealingsPerTx > 0, "Invalid param");
    maxDealingsPerTx = newDealingsPerTx;
  }

  /**
   * @dev Sets exit fee percentage for redemptions.
   * @param newExitFeePercentage The percentage of the redemption amount for exit fees.
   */
  function setExitFeePercentage(uint24 newExitFeePercentage) external onlyOwner {
    require(newExitFeePercentage > 0, "Invalid percentage");
    require(newExitFeePercentage < 3000, "Percentage too high");
    exitFeePercentage = newExitFeePercentage;
    emit UpdateExitFeePercentage(newExitFeePercentage);
  }

  /**
   * @dev Add a stable ticker, all redemption tickers should have the correct contract address. (Usually ticker used for investments)
   * @param ticker The ticker of the token. Please ensure that all tickers are upper case eg. ETH
   * @param contractAddress The token contract address, if its not a redemtion currency the zero address should be used.
   * @param numerator The the current USD price of the token.
   * @param decimals The amount of decimals in the token contract.
   */
  function addTicker(
    string memory ticker,
    address contractAddress,
    uint256 numerator,
    uint8 decimals
  ) external onlyPricingOracle {
    require(numerator > 0, "Invalid numerator");
    tickers[ticker] = Ticker(Price(numerator, denominator), contractAddress, decimals);
    supportedTickers.push(ticker);
  }

  /**
   * @dev Updates the fee address.
   * @param newFeeAddress The new address where fees are sent to.
   */
  function updateFeeAddress(address newFeeAddress) public onlyOwner {
    require(newFeeAddress != address(0), "Invalid address");
    feeAddress = newFeeAddress;
  }

  /**
   * @dev Increase a user's token amount incase of incorrect dealing
   * @param investor The ticker of the token. eg. ETH
   * @param amount The the of tokens to be added to the users address.
   * @param reason The reason for the token amendment.
   * @param txHash The transaction hash for the the dealing event.
   */
  function increaseTokenAmendment(
    address investor,
    uint256 amount,
    string memory reason,
    string memory txHash
  ) external onlyOwner {
    require(amount > 0, "Invalid amount");
    mint(investor, amount);
    emit IncreaseTokenAmendment(investor, amount, reason, txHash);
  }

  /**
   * @dev Decrease user token amount incase of incorrect dealing.
   * @param investor The address that you want to decrease the token amount for.
   * @param amount The the amount you want to decrease it by.
   * @param reason The reason for the decrease.
   * @param originalTxHash The original transaction hash that is being adjusted.
   */
  function decreaseTokenAmendment(
    address investor,
    uint256 amount,
    string memory reason,
    string memory originalTxHash
  ) internal {
    require(amount > 0, "Invalid amount");
    burnFrom(investor, amount);
    emit DecreaseTokenAmendment(investor, amount, reason, originalTxHash);
  }

  /**
   * @dev Overridden function from parent contract.
   * @param account The address you want to burn tokens for.
   * @param amount The the amount of tokens to burn.
   */
  function burnFrom(address account, uint256 amount) public virtual override onlyOwner {
    _burn(account, amount);
  }

  /**
   * @dev Overridden function from parent contract.
   * @param sender The address you want to transfer tokens from.
   * @param recipient The address you want to transfer tokens to.
   * @param amount The the amount of tokens to transfer.
   */
  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) public virtual override onlyPricingOracle returns (bool) {
    _transfer(sender, recipient, amount);
    return true;
  }

  /**
   * @dev Update the rates for the supported tickers.
   * @param _rates The prices in USD, mapped to the _tickers list.
   */
  function updateTickerPrices(uint256[] memory _rates) internal {
    require(_rates.length == supportedTickers.length, "Invalid rates list");
    for (uint256 i = 0; i < _rates.length; i++) {
      require(_rates[i] > 0, "Invalid rate");
      require(tickers[supportedTickers[i]].price.numerator != 0, "Currency not supported");
      tickers[supportedTickers[i]].price = Price(_rates[i], denominator);
      emit AssetPriceUpdated(_rates[i], supportedTickers[i]);
    }
  }

  /**
   * @dev Updates the cutoff time for investment to be processed at next dealing.
   * @param time The next cutoff time.
   */
  function updateCutOfftime(uint32 time) public onlyPricingOracle {
    require(time >= block.timestamp, "Invalid cut off time");
    cutOffTime = time;
  }

  /**
   * @dev Updates the dealing nonce. (Increments at every dealing)
   * @param _dealingNonce New nonce assigned to dealing event.
   */
  function updateDealingNonce(uint24 _dealingNonce) internal {
    dealingNonce = _dealingNonce;
  }

  /**
   * @dev Handles the redeptions triggered by a price update on the dealing event.
   * @param eventId Index of the redemption for a spesific dealing event.
   * @param investor The users address who is doing the redemption.
   * @param redemptionCurrencyAmount The calculated amount to transfered for a redemption.
   * @param tokenAmount The amount of fund tokens being redeemed.
   * @param ticker The ticker requested to recive your redemtion in.
   */
  function dealRedemption(
    uint256 eventId,
    address investor,
    uint256 redemptionCurrencyAmount,
    uint256 tokenAmount,
    string memory ticker
  ) public onlyPricingOracle {
    address stableContract = tickers[ticker].contractAddress;
    if (ERC20Upgradeable(stableContract).balanceOf(address(this)) < redemptionCurrencyAmount) {
      transferFrom(DEAL_ADDRESS, investor, tokenAmount);
    } else {
      uint256 exitFee = calculateExitFee(redemptionCurrencyAmount);
      _burn(DEAL_ADDRESS, tokenAmount);
      ERC20Upgradeable(stableContract).safeTransfer(feeAddress, exitFee);
      ERC20Upgradeable(stableContract).safeTransfer(investor, (redemptionCurrencyAmount - exitFee));
      emit RedemptionEvent(eventId, tokenAmount, redemptionCurrencyAmount, ticker, investor, dealingNonce);
    }
  }

  /**
   * @dev Handles the dealing of fund tokens for an investment.
   * @param eventId Index of the investment for a spesific dealing event.
   * @param investor The users address who is doing the investment.
   * @param investmentCurrencyAmount The amount of tokens sent for investment.
   * @param fundTokenAmount The amount of fund tokens to be minted.
   * @param investmentCurrency The investment token ticker.
   * @param transactionHash The transaction hash for the original investment transcation.
   */
  function dealInvestment(
    uint256 eventId,
    address investor,
    uint256 investmentCurrencyAmount,
    uint256 fundTokenAmount,
    string memory investmentCurrency,
    string memory transactionHash
  ) public onlyPricingOracle {
    _mint(investor, fundTokenAmount);
    emit InvestmentEvent(
      eventId,
      investmentCurrencyAmount,
      fundTokenAmount,
      investmentCurrency,
      transactionHash,
      investor,
      dealingNonce
    );
  }

  ////////////////////////////////////////////////////////////////////// Internal functions ////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * @dev Calculates the amount of fund tokens to mint based off the fund nav and total USD value of the investment.
   * @param investmentTicker The token ticker the investment was made in.
   * @param investmentAmount The ammount of tokens sent for investment.
   */
  function calculateTokenAmount(string memory investmentTicker, uint256 investmentAmount)
    private
    view
    returns (uint256)
  {
    Ticker memory ticker = tickers[investmentTicker];
    Ticker memory contractTicker = tickers[symbol()];
    return (investmentAmount * ticker.price.numerator) / contractTicker.price.numerator;
  }

  /**
   * @dev Calculates the amount of tokens a investor will recieved for their redemption.
   * @param ticker The requested token the investor wants to recieve the redemption in.
   * @param tokenAmount The ammount of fund tokens the investor wants to redeem.
   */
  function calculateRedemptionAmount(string memory ticker, uint256 tokenAmount) private view returns (uint256) {
    Ticker memory redemptionTicker = tickers[ticker];
    Ticker memory contractToken = tickers[symbol()];
    uint256 tokens = ((tokenAmount * contractToken.price.numerator) / redemptionTicker.price.numerator);
    if (redemptionTicker.decimals > contractToken.decimals) {
      return tokens * (10**(redemptionTicker.decimals - contractToken.decimals));
    } else {
      return tokens / (10**(contractToken.decimals - redemptionTicker.decimals));
    }
  }

  function _beforeTokenTransfer(
    address _from,
    address _to,
    uint256 _amount
  ) internal virtual override {
    _checkWhitelist(_to);
    super._beforeTokenTransfer(_from, _to, _amount);
  }

  ////////////////////////////////////////////////////////////////////// Private functions ////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * @dev _handleRedemptionsDealing Handle the redemptions during dealing.
   */
  function _handleRedemptionsDealing() private returns (bool) {
    uint256 numberOfRedemptions = MathUpgradeable.min(redemptionsLength(), maxDealingsPerTx);
    uint256 endingIndex = redemptionsLength() - numberOfRedemptions;
    Redemption memory redemption;
    for (uint256 i = redemptionsLength(); i > endingIndex; i--) {
      redemption = redemptions[i - 1];
      
      if (!InvictusWhitelist(whitelistContract).isWhitelisted(redemption.investor)) {
        redemptions.pop();
      } else if (redemption.timestamp < cutOffTime) {
        redemptions.pop();
        dealRedemption(
          i - 1,
          redemption.investor,
          calculateRedemptionAmount(redemption.ticker, redemption.amount),
          redemption.amount,
          redemption.ticker
        );
      }
    }
    uint256 nextStartingIndex = endingIndex <= 1 ? 0 : endingIndex - 1;
    if (redemptionsLength() != 0 && redemptions[nextStartingIndex].timestamp < cutOffTime) {
      emit RedemptionsLeftInQueue(dealingNonce);
      return false;
    }
    return true;
  }

  /**
   * @dev _handleInvestmentsDealing Handle the investments during dealing.
   */
  function _handleInvestmentsDealing() private returns (bool) {
    uint256 numberOfInvestments = MathUpgradeable.min(investmentsLength(), maxDealingsPerTx);
    uint256 endingIndex = investmentsLength() - numberOfInvestments;
    Investment memory investment;

    for (uint256 i = investmentsLength(); i > endingIndex; i--) {
      investment = investments[i - 1];
      if (!InvictusWhitelist(whitelistContract).isWhitelisted(investment.investor)) {
        investments.pop();
      } else if (investment.timestamp < cutOffTime) {
        investments.pop();
        dealInvestment(
          i - 1,
          investment.investor,
          investment.amount,
          calculateTokenAmount(investment.investmentCurrency, investment.amount),
          investment.investmentCurrency,
          investment.transactionHash
        );
      }
    }

    uint256 nextStartingIndex = endingIndex <= 1 ? 0 : endingIndex - 1;
    if (investmentsLength() != 0 && investments[nextStartingIndex].timestamp < cutOffTime) {
      emit InvestmentsLeftInQueue(dealingNonce);
      return false;
    }
    return true;
  }

  ////////////////////////////////////////////////////////////////////// Modifiers functions ////////////////////////////////////////////////////////////////////////////////////////////

  modifier onlyWhitelisted() {
    _checkWhitelist(_msgSender());
    _;
  }

  modifier onlyPricingOracle() {
    _roleRequire(PRICING_ORACLE_ROLE, "Only pricing oracle", _msgSender());
    _;
  }

  modifier onlyInvestmentOracle() {
    _roleRequire(INVESTMENT_ORACLE_ROLE, "Only investment oracle", _msgSender());
    _;
  }

  modifier onlyRedemptionTickers(string memory ticker) {
    _onlyRedemptionCurrencies(ticker);
    _;
  }

  //check the role with error msg
  function _roleRequire(
    bytes32 role,
    string memory errorMsg,
    address investor
  ) private view {
    require(hasRole(role, investor), errorMsg);
  }

  //check if whitelisted
  function _checkWhitelist(address investor) private view {
    require(InvictusWhitelist(whitelistContract).isWhitelisted(investor), "Not whitelisted");
  }

  function _onlyRedemptionCurrencies(string memory ticker) private view {
    require(address(tickers[ticker].contractAddress) != address(0), "Only redemption tickers");
  }
}

Contract ABI

[{"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":[{"indexed":false,"internalType":"uint256","name":"numerator","type":"uint256"},{"indexed":false,"internalType":"string","name":"ticker","type":"string"}],"name":"AssetPriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dealingNonce","type":"uint256"}],"name":"Dealing","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"string","name":"txHash","type":"string"}],"name":"DecreaseTokenAmendment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"string","name":"txHash","type":"string"}],"name":"IncreaseTokenAmendment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"investmentCurrencyAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"string","name":"investmentCurrency","type":"string"},{"indexed":false,"internalType":"string","name":"transactionHash","type":"string"},{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint128","name":"dealingNonce","type":"uint128"}],"name":"InvestmentEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"string","name":"investmentCurrency","type":"string"},{"indexed":false,"internalType":"string","name":"transactionHash","type":"string"},{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"InvestmentRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dealingNonce","type":"uint256"}],"name":"InvestmentsLeftInQueue","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"TokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redemtionCurrencyAmount","type":"uint256"},{"indexed":false,"internalType":"string","name":"ticker","type":"string"},{"indexed":false,"internalType":"address","name":"particpant","type":"address"},{"indexed":false,"internalType":"uint128","name":"dealingNonce","type":"uint128"}],"name":"RedemptionEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"string","name":"ticker","type":"string"},{"indexed":false,"internalType":"address","name":"investor","type":"address"}],"name":"RedemptionRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dealingNonce","type":"uint256"}],"name":"RedemptionsLeftInQueue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"RemoveLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"TokensClaimed","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"newExitFeePercentage","type":"uint24"}],"name":"UpdateExitFeePercentage","type":"event"},{"inputs":[],"name":"DEAL_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INVESTMENT_ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICING_ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ticker","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"addTicker","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","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":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Upgradeable","name":"token","type":"address"}],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cutOffTime","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"eventId","type":"uint256"},{"internalType":"address","name":"investor","type":"address"},{"internalType":"uint256","name":"investmentCurrencyAmount","type":"uint256"},{"internalType":"uint256","name":"fundTokenAmount","type":"uint256"},{"internalType":"string","name":"investmentCurrency","type":"string"},{"internalType":"string","name":"transactionHash","type":"string"}],"name":"dealInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"eventId","type":"uint256"},{"internalType":"address","name":"investor","type":"address"},{"internalType":"uint256","name":"redemptionCurrencyAmount","type":"uint256"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"string","name":"ticker","type":"string"}],"name":"dealRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_rates","type":"uint256[]"}],"name":"dealing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dealingNonce","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"denominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exitFeePercentage","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"investor","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"string","name":"txHash","type":"string"}],"name":"increaseTokenAmendment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"whitelistContractInput","type":"address"},{"internalType":"address","name":"feeAddressInput","type":"address"},{"internalType":"uint32","name":"_cutOffTime","type":"uint32"}],"name":"initializeInvictusFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"investmentTxIndex","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"investments","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"string","name":"investmentCurrency","type":"string"},{"internalType":"string","name":"transactionHash","type":"string"},{"internalType":"address","name":"investor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investmentsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDealingsPerTx","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTokenRedemption","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"purgeQueues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"purgeSupportedCurrencies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"investmentTicker","type":"string"},{"internalType":"string","name":"transactionHash","type":"string"},{"internalType":"address","name":"investor","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"queueInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawAmount","type":"uint256"},{"internalType":"string","name":"ticker","type":"string"}],"name":"queueRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redemptions","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"string","name":"ticker","type":"string"},{"internalType":"address","name":"investor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redemptionsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"ticker","type":"string"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"newDealingsPerTx","type":"uint24"}],"name":"setDealingsPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"newExitFeePercentage","type":"uint24"}],"name":"setExitFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportedTickers","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"tickers","outputs":[{"components":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"internalType":"struct ERC20InvictusFund.Price","name":"price","type":"tuple"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","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"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"time","type":"uint32"}],"name":"updateCutOfftime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeAddress","type":"address"}],"name":"updateFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50615536806100206000396000f3fe608060405234801561001057600080fd5b50600436106103e65760003560e01c806379cc67901161020a578063bacb61e911610125578063d547741f116100b8578063df8de3e711610087578063df8de3e71461097e578063e63ab1e914610991578063f28c6d0b146109a6578063f2fde38b146109b9578063fd345c8a146109cc57600080fd5b8063d547741f14610922578063d7ac1e9b14610935578063dd62ed3e1461093d578063ddba40421461097657600080fd5b8063ca4370a5116100f4578063ca4370a5146108c8578063d3066a43146108db578063d3ca705d146108f2578063d5391393146108fb57600080fd5b8063bacb61e914610876578063bbcaac381461087f578063beb6589314610892578063ca15c873146108b557600080fd5b806391d148541161019d5780639730cbac1161016c5780639730cbac14610821578063a217fddf14610848578063a457c2d714610850578063a9059cbb1461086357600080fd5b806391d14854146107e957806391edc5c4146107fc57806395d89b411461080f57806396ce07951461081757600080fd5b80638456cb59116101d95780638456cb59146107a957806384900b04146107b15780638da5cb5b146107c55780639010d07c146107d657600080fd5b806379cc679014610731578063800189c41461074457806380488f621461075757806381a3475a1461076a57600080fd5b8063412753581161030557806356b01aa7116102985780636cf29fec116102675780636cf29fec146106ca5780636d605419146106dd57806370946ce1146106f057806370a0823114610700578063715018a61461072957600080fd5b806356b01aa71461068e578063576852c7146106a157806359a747d4146106b45780635c975abb146106be57600080fd5b80634bdd9fe6116102d45780634bdd9fe6146106215780634cd88b761461064c5780634eab48dd1461065f578063560fee551461068557600080fd5b806341275358146105bc57806342966c68146105e857806342bd1b3c146105fb57806342c578cb1461060e57600080fd5b80632f2ff15d1161037d578063395093511161034c57806339509351146105795780633e7d427d1461058c5780633f4ba83a146105a157806340c10f19146105a957600080fd5b80632f2ff15d14610531578063313ce5671461054457806336568abe1461055357806336e24c201461056657600080fd5b806318160ddd116103b957806318160ddd146104505780631953355b1461046257806323b872dd146104fb578063248a9ca31461050e57600080fd5b806301ffc9a7146103eb57806304f95c7a1461041357806306fdde0314610428578063095ea7b31461043d575b600080fd5b6103fe6103f936600461468e565b6109f2565b60405190151581526020015b60405180910390f35b61042661042136600461476f565b610a1d565b005b610430610d7c565b60405161040a9190614858565b6103fe61044b36600461486b565b610e0e565b60fd545b60405190815260200161040a565b6104c4610470366004614897565b80516020818301810180516101f9825292820193820193909320919092526040805180820190915281548152600182015492810192909252600201546001600160a01b03811690600160a01b900460ff1683565b6040805184518152602094850151948101949094526001600160a01b039092169183019190915260ff16606082015260800161040a565b6103fe6105093660046148cb565b610e24565b61045461051c36600461490c565b60009081526097602052604090206001015490565b61042661053f366004614925565b610e81565b6040516012815260200161040a565b610426610561366004614925565b610eac565b610426610574366004614955565b610f2a565b6103fe61058736600461486b565b610fe2565b6104546000805160206154e183398151915281565b61042661101e565b6104266105b736600461486b565b6110b2565b6101fb546105d0906001600160a01b031681565b6040516001600160a01b03909116815260200161040a565b6104266105f636600461490c565b611151565b6104266106093660046149d4565b61115e565b61042661061c366004614a1a565b6112eb565b6101fd54610638906301000000900462ffffff1681565b60405162ffffff909116815260200161040a565b61042661065a366004614a86565b611486565b6101ff546106709063ffffffff1681565b60405163ffffffff909116815260200161040a565b6105d061dea181565b61042661069c366004614af8565b611503565b6104306106af36600461490c565b6115b2565b6104546101fc5481565b61015f5460ff166103fe565b6104266106d8366004614b13565b61165f565b6104266106eb366004614b13565b611778565b6101fd546106389062ffffff1681565b61045461070e366004614b38565b6001600160a01b0316600090815260fb602052604090205490565b610426611802565b61042661073f36600461486b565b611836565b610426610752366004614b55565b61186a565b6104266107653660046149d4565b6119bd565b6103fe610778366004614bee565b81516020818401810180516101f8825292820194820194909420919093529091526000908152604090205460ff1681565b610426611a7f565b6101fa546105d0906001600160a01b031681565b6033546001600160a01b03166105d0565b6105d06107e4366004614c32565b611b11565b6103fe6107f7366004614925565b611b29565b61042661080a366004614c54565b611b54565b610430611bf0565b6104546101fe5481565b6104547f663250ff04bd9eb418dc43eb445811ab983cdd7e031128c17171e0ad792f6c3481565b610454600081565b6103fe61085e36600461486b565b611bff565b6103fe61087136600461486b565b611c8e565b6101f554610454565b61042661088d366004614b38565b611c9b565b6108a56108a036600461490c565b611d30565b60405161040a9493929190614ce5565b6104546108c336600461490c565b611e02565b6104266108d6366004614d1d565b611e19565b6101ff5461063890600160201b900462ffffff1681565b6101f654610454565b6104547f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b610426610930366004614925565b611f7a565b610426611fa0565b61045461094b366004614d91565b6001600160a01b03918216600090815260fc6020908152604080832093909416825291909152205490565b610426611fd7565b61042661098c366004614b38565b61201b565b6104546000805160206154c183398151915281565b6104266109b4366004614dbf565b612167565b6104266109c7366004614b38565b6122d8565b6109df6109da36600461490c565b612370565b60405161040a9796959493929190614e30565b60006001600160e01b03198216635a05180f60e01b1480610a175750610a17826124dc565b92915050565b610a7c7f663250ff04bd9eb418dc43eb445811ab983cdd7e031128c17171e0ad792f6c34604051806040016040528060168152602001754f6e6c7920696e766573746d656e74206f7261636c6560501b815250610a773390565b612511565b6101f985604051610a8d9190614e8a565b90815260405190819003602001902054610adf5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103a34b1b5b2b960911b60448201526064015b60405180910390fd5b60008611610b205760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610ad6565b6101f884604051610b319190614e8a565b90815260408051602092819003830190206000848152925290205460ff1615610b8f5760405162461bcd60e51b815260206004820152601060248201526f496e646578206e6f7420756e6971756560801b6044820152606401610ad6565b60016101f885604051610ba29190614e8a565b90815260408051602092819003830181206000868152908452828120805460ff19169515159590951790945560e0810182528981524283820190815291810186815260608201868152608083018b815260a084018b90526001600160a01b038a1660c08501526101f68054600181018255975283517f6ea6ba7afdda9dd98317feb84bb80d157ea581b23ca788496ba1c38c64dd8212600790980297880190815594517f6ea6ba7afdda9dd98317feb84bb80d157ea581b23ca788496ba1c38c64dd821388015591517f6ea6ba7afdda9dd98317feb84bb80d157ea581b23ca788496ba1c38c64dd8214870155517f6ea6ba7afdda9dd98317feb84bb80d157ea581b23ca788496ba1c38c64dd821586015551805191949293610cea937f6ea6ba7afdda9dd98317feb84bb80d157ea581b23ca788496ba1c38c64dd821601929101906144ae565b5060a08201518051610d069160058401916020909101906144ae565b5060c09190910151600690910180546001600160a01b0319166001600160a01b039092169190911790556040517f9869338698eafe0a2d46b345876e56b743897fa05d14f2935e2ab1bafdcf19f490610d6c908890429089908990899089908990614ea6565b60405180910390a1505050505050565b606060fe8054610d8b90614f00565b80601f0160208091040260200160405190810160405280929190818152602001828054610db790614f00565b8015610e045780601f10610dd957610100808354040283529160200191610e04565b820191906000526020600020905b815481529060010190602001808311610de757829003601f168201915b5050505050905090565b6000610e1b338484612540565b50600192915050565b6000610e6b6000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b610e76848484612664565b5060015b9392505050565b600082815260976020526040902060010154610e9d813361283d565b610ea783836128a1565b505050565b6001600160a01b0381163314610f1c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610ad6565b610f2682826128c3565b5050565b6033546001600160a01b03163314610f545760405162461bcd60e51b8152600401610ad690614f3b565b60008311610f955760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610ad6565b610f9f84846110b2565b7f7314f62a75b4a36c977f8bc5a72c57767f655dcc6abe57336590c7bd6c32230f84848484604051610fd49493929190614f70565b60405180910390a150505050565b33600081815260fc602090815260408083206001600160a01b03871684529091528120549091610e1b918590611019908690614fbf565b612540565b6110366000805160206154c183398151915233611b29565b6110a85760405162461bcd60e51b815260206004820152603960248201527f45524332305072657365744d696e7465725061757365723a206d75737420686160448201527f76652070617573657220726f6c6520746f20756e7061757365000000000000006064820152608401610ad6565b6110b06128e5565b565b6110dc7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633611b29565b6111475760405162461bcd60e51b815260206004820152603660248201527f45524332305072657365744d696e7465725061757365723a206d7573742068616044820152751d99481b5a5b9d195c881c9bdb19481d1bc81b5a5b9d60521b6064820152608401610ad6565b610f26828261297a565b61115b3382612a65565b50565b61116733612bbf565b8061117181612c6c565b8261117b3361070e565b10156111ba5760405162461bcd60e51b815260206004820152600e60248201526d42616c616e636520746f206c6f7760901b6044820152606401610ad6565b6101fc548310156111fe5760405162461bcd60e51b815260206004820152600e60248201526d546f6f2066657720746f6b656e7360901b6044820152606401610ad6565b61120a61dea184611c8e565b506101f560405180608001604052808581526020014281526020018481526020016112323390565b6001600160a01b03169052815460018181018455600093845260209384902083516004909302019182558383015190820155604082015180519293919261127f92600285019201906144ae565b5060609190910151600390910180546001600160a01b0319166001600160a01b039092169190911790557f18436060614a85ed614c8e2269b6bf8b9902a7c813866993d737f6de41c011cc834284336040516112de9493929190614ce5565b60405180910390a1505050565b6113306000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b60006101f9826040516113439190614e8a565b908152604051908190036020018120600201546370a0823160e01b82523060048301526001600160a01b03169150849082906370a0823190602401602060405180830381865afa15801561139b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bf9190614fd7565b10156113d8576113d261dea18685610e24565b5061147e565b60006113e385612cf2565b90506113f161dea185612a65565b6101fb5461140c906001600160a01b03848116911683612d6d565b61142b8661141a8388614ff0565b6001600160a01b0385169190612d6d565b6101ff546040517f940510af16428f7977a47a935331c1f31d000793029a542285e34beb3c70020d91611474918a9188918a9189918d91600160201b900462ffffff1690615007565b60405180910390a1505b505050505050565b600054610100900460ff166114a15760005460ff16156114a5565b303b155b6114c15760405162461bcd60e51b8152600401610ad690615054565b600054610100900460ff161580156114e3576000805461ffff19166101011790555b6114ed8383612dbf565b8015610ea7576000805461ff0019169055505050565b6115486000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b428163ffffffff1610156115955760405162461bcd60e51b8152602060048201526014602482015273496e76616c696420637574206f66662074696d6560601b6044820152606401610ad6565b6101ff805463ffffffff191663ffffffff92909216919091179055565b6101f781815481106115c357600080fd5b9060005260206000200160009150905080546115de90614f00565b80601f016020809104026020016040519081016040528092919081815260200182805461160a90614f00565b80156116575780601f1061162c57610100808354040283529160200191611657565b820191906000526020600020905b81548152906001019060200180831161163a57829003601f168201915b505050505081565b6033546001600160a01b031633146116895760405162461bcd60e51b8152600401610ad690614f3b565b60008162ffffff16116116d35760405162461bcd60e51b8152602060048201526012602482015271496e76616c69642070657263656e7461676560701b6044820152606401610ad6565b610bb88162ffffff161061171f5760405162461bcd60e51b81526020600482015260136024820152720a0cae4c6cadce8c2ceca40e8dede40d0d2ced606b1b6044820152606401610ad6565b6101fd805465ffffff0000001916630100000062ffffff8416908102919091179091556040519081527f5695d0e2f91cd1a654dda929b540bccb2be88ff75f7c51642a408c55099a8eca9060200160405180910390a150565b6033546001600160a01b031633146117a25760405162461bcd60e51b8152600401610ad690614f3b565b60008162ffffff16116117e75760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420706172616d60981b6044820152606401610ad6565b6101fd805462ffffff191662ffffff92909216919091179055565b6033546001600160a01b0316331461182c5760405162461bcd60e51b8152600401610ad690614f3b565b6110b06000612e32565b6033546001600160a01b031633146118605760405162461bcd60e51b8152600401610ad690614f3b565b610f268282612a65565b600054610100900460ff166118855760005460ff1615611889565b303b155b6118a55760405162461bcd60e51b8152600401610ad690615054565b600054610100900460ff161580156118c7576000805461ffff19166101011790555b6118d18686612dbf565b6118d9612e84565b6118e1612ebb565b6001600160a01b03841661192e5760405162461bcd60e51b81526020600482015260146024820152736e6f2077686974656c697374206164647265737360601b6044820152606401610ad6565b6101fa80546001600160a01b038087166001600160a01b0319928316179092556101fb805492861692909116919091179055670de0b6b3a76400006101fc8190556101fd8054633200001965ffffffffffff199091161790556101ff805466ffffffffffffff191663ffffffff85161790556101fe55801561147e576000805461ff0019169055505050505050565b611a026000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b80611a0c81612c6c565b611a4533846101f985604051611a229190614e8a565b908152604051908190036020019020600201546001600160a01b03169190612d6d565b60405183815233907fdfdd120ded9b7afc0c23dd5310e93aaa3e1c3b9f75af9b805fab3030842439f29060200160405180910390a2505050565b611a976000805160206154c183398151915233611b29565b611b095760405162461bcd60e51b815260206004820152603760248201527f45524332305072657365744d696e7465725061757365723a206d75737420686160448201527f76652070617573657220726f6c6520746f2070617573650000000000000000006064820152608401610ad6565b6110b0612ef2565b600082815260c960205260408120610e7a9083612f6f565b60009182526097602090815260408084206001600160a01b0393909316845291905290205460ff1690565b611b996000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b611ba3858461297a565b7f424743e071ac45d10070adfc5ce3e197af300e63595096a96340175278f08d6386858585858a6101ff60049054906101000a900462ffffff16604051610d6c97969594939291906150a2565b606060ff8054610d8b90614f00565b33600090815260fc602090815260408083206001600160a01b038616845290915281205482811015611c815760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610ad6565b610e763385858403612540565b6000610e1b338484612664565b6033546001600160a01b03163314611cc55760405162461bcd60e51b8152600401610ad690614f3b565b6001600160a01b038116611d0d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610ad6565b6101fb80546001600160a01b0319166001600160a01b0392909216919091179055565b6101f58181548110611d4157600080fd5b9060005260206000209060040201600091509050806000015490806001015490806002018054611d7090614f00565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9c90614f00565b8015611de95780601f10611dbe57610100808354040283529160200191611de9565b820191906000526020600020905b815481529060010190602001808311611dcc57829003601f168201915b505050600390930154919250506001600160a01b031684565b600081815260c960205260408120610a1790612f7b565b611e5e6000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b80611e965760405162461bcd60e51b81526020600482015260086024820152674e6f20726174657360c01b6044820152606401610ad6565b611ed2828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612f8592505050565b611eda6131b4565b8015611ee95750611ee9613663565b15611f33576101ff54611f3390611f0d90600160201b900462ffffff166001615103565b6101ff805462ffffff909216600160201b0266ffffff0000000019909216919091179055565b6101ff54604051600160201b90910462ffffff1681527f83d39a50ceda5d45bbc677ab5569eb632e16c4c4276871bcc4e099a6ae4bdef89060200160405180910390a15050565b600082815260976020526040902060010154611f96813361283d565b610ea783836128c3565b6033546001600160a01b03163314611fca5760405162461bcd60e51b8152600401610ad690614f3b565b6110b06101f76000614532565b6033546001600160a01b031633146120015760405162461bcd60e51b8152600401610ad690614f3b565b61200e6101f56000614550565b6110b06101f66000614571565b6033546001600160a01b031633146120455760405162461bcd60e51b8152600401610ad690614f3b565b6001600160a01b03811661208d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610ad6565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190614fd7565b905061212061210f6033546001600160a01b031690565b6001600160a01b0384169083612d6d565b816001600160a01b03167f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e4308260405161215b91815260200190565b60405180910390a25050565b6121ac6000805160206154e1833981519152604051806040016040528060138152602001724f6e6c792070726963696e67206f7261636c6560681b815250610a773390565b600082116121f05760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b210373ab6b2b930ba37b960791b6044820152606401610ad6565b6040805160a081018252606081018481526101fe54608083015281526001600160a01b038516602082015260ff83168183015290516101f990612234908790614e8a565b908152604080519182900360209081019092208351805182558301516001808301919091558484015160029092018054959093015160ff16600160a01b026001600160a81b03199095166001600160a01b03909216919091179390931790556101f78054928301815560005285516122d1927fab423d91e51275f405563b297e90b3a62f6d51fbcf68f05522049701393dd8c301918701906144ae565b5050505050565b6033546001600160a01b031633146123025760405162461bcd60e51b8152600401610ad690614f3b565b6001600160a01b0381166123675760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ad6565b61115b81612e32565b6101f6818154811061238157600080fd5b90600052602060002090600702016000915090508060000154908060010154908060020154908060030154908060040180546123bc90614f00565b80601f01602080910402602001604051908101604052809291908181526020018280546123e890614f00565b80156124355780601f1061240a57610100808354040283529160200191612435565b820191906000526020600020905b81548152906001019060200180831161241857829003601f168201915b50505050509080600501805461244a90614f00565b80601f016020809104026020016040519081016040528092919081815260200182805461247690614f00565b80156124c35780601f10612498576101008083540402835291602001916124c3565b820191906000526020600020905b8154815290600101906020018083116124a657829003601f168201915b505050600690930154919250506001600160a01b031687565b60006001600160e01b03198216637965db0b60e01b1480610a1757506301ffc9a760e01b6001600160e01b0319831614610a17565b61251b8382611b29565b829061253a5760405162461bcd60e51b8152600401610ad69190614858565b50505050565b6001600160a01b0383166125a25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610ad6565b6001600160a01b0382166126035760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610ad6565b6001600160a01b03838116600081815260fc602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166126c85760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610ad6565b6001600160a01b03821661272a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ad6565b6127358383836139f5565b6001600160a01b038316600090815260fb6020526040902054818110156127ad5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610ad6565b6001600160a01b03808516600090815260fb60205260408082208585039055918516815290812080548492906127e4908490614fbf565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161283091815260200190565b60405180910390a361253a565b6128478282611b29565b610f265761285f816001600160a01b03166014613a09565b61286a836020613a09565b60405160200161287b92919061512a565b60408051601f198184030181529082905262461bcd60e51b8252610ad691600401614858565b6128ab8282613ba4565b600082815260c960205260409020610ea79082613c2a565b6128cd8282613c3f565b600082815260c960205260409020610ea79082613ca6565b61015f5460ff1661292f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ad6565b61015f805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166129d05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610ad6565b6129dc600083836139f5565b8060fd60008282546129ee9190614fbf565b90915550506001600160a01b038216600090815260fb602052604081208054839290612a1b908490614fbf565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216612ac55760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610ad6565b612ad1826000836139f5565b6001600160a01b038216600090815260fb602052604090205481811015612b455760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610ad6565b6001600160a01b038316600090815260fb60205260408120838303905560fd8054849290612b74908490614ff0565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6101fa54604051633af32abf60e01b81526001600160a01b03838116600483015290911690633af32abf90602401602060405180830381865afa158015612c0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2e919061519f565b61115b5760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610ad6565b60006001600160a01b03166101f982604051612c889190614e8a565b908152604051908190036020019020600201546001600160a01b0316141561115b5760405162461bcd60e51b815260206004820152601760248201527f4f6e6c7920726564656d7074696f6e207469636b6572730000000000000000006044820152606401610ad6565b600081612710612d0282826151c1565b612d0c91906151e0565b14612d455760405162461bcd60e51b81526020600482015260096024820152681d1bdbc81cdb585b1b60ba1b6044820152606401610ad6565b6101fd5461271090612d63906301000000900462ffffff16846151c1565b610a1791906151e0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610ea7908490613cbb565b600054610100900460ff16612de65760405162461bcd60e51b8152600401610ad690615202565b612dee613d8d565b612df6613d8d565b612dfe613d8d565b612e06613d8d565b612e108282613db4565b612e18613d8d565b612e20613e02565b612e28613d8d565b610f268282613e36565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612eab5760405162461bcd60e51b8152600401610ad690615202565b612eb3613d8d565b6110b0613eaa565b600054610100900460ff16612ee25760405162461bcd60e51b8152600401610ad690615202565b612eea613d8d565b6110b0613e02565b61015f5460ff1615612f395760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ad6565b61015f805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861295d3390565b6000610e7a8383613eda565b6000610a17825490565b6101f754815114612fcd5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081c985d195cc81b1a5cdd60721b6044820152606401610ad6565b60005b8151811015610f26576000828281518110612fed57612fed61524d565b6020026020010151116130315760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964207261746560a01b6044820152606401610ad6565b6101f96101f782815481106130485761304861524d565b9060005260206000200160405161305f9190615263565b908152604051908190036020019020546130b45760405162461bcd60e51b815260206004820152601660248201527510dd5c9c995b98de481b9bdd081cdd5c1c1bdc9d195960521b6044820152606401610ad6565b60405180604001604052808383815181106130d1576130d161524d565b602002602001015181526020016101fe548152506101f96101f783815481106130fc576130fc61524d565b906000526020600020016040516131139190615263565b908152604051602091819003820190208251815591015160019091015581517f311d87a8b482f427fc17bec433c33d0687a51886a2fb08783495b33458841229908390839081106131665761316661524d565b60200260200101516101f783815481106131825761318261524d565b9060005260206000200160405161319a9291906152d5565b60405180910390a1806131ac81615362565b915050612fd0565b6000806131d26131c46101f65490565b6101fd5462ffffff16613f04565b90506000816131e16101f65490565b6131eb9190614ff0565b90506132366040518060e0016040528060008152602001600081526020016000815260200160008152602001606081526020016060815260200160006001600160a01b031681525090565b60006132426101f65490565b90505b8281111561359a576101f661325b600183614ff0565b8154811061326b5761326b61524d565b90600052602060002090600702016040518060e0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820180546132bc90614f00565b80601f01602080910402602001604051908101604052809291908181526020018280546132e890614f00565b80156133355780601f1061330a57610100808354040283529160200191613335565b820191906000526020600020905b81548152906001019060200180831161331857829003601f168201915b5050505050815260200160058201805461334e90614f00565b80601f016020809104026020016040519081016040528092919081815260200182805461337a90614f00565b80156133c75780601f1061339c576101008083540402835291602001916133c7565b820191906000526020600020905b8154815290600101906020018083116133aa57829003601f168201915b5050509183525050600691909101546001600160a01b039081166020909201919091526101fa5460c0830151604051633af32abf60e01b815290831660048201529294501690633af32abf90602401602060405180830381865afa158015613433573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613457919061519f565b6134cf576101f680548061346d5761346d61537d565b600082815260208120600760001990930192830201818155600181018290556002810182905560038101829055906134a86004830182614592565b6134b6600583016000614592565b5060060180546001600160a01b03191690559055613588565b6101ff54602083015163ffffffff9091161115613588576101f68054806134f8576134f861537d565b600082815260208120600760001990930192830201818155600181018290556002810182905560038101829055906135336004830182614592565b613541600583016000614592565b5060060180546001600160a01b03191690559055613588613563600183614ff0565b60c0840151845160808601516135799082613f1a565b86608001518760a00151611b54565b8061359281615393565b915050613245565b50600060018311156135b6576135b1600184614ff0565b6135b9565b60005b90506135c56101f65490565b1580159061360457506101ff546101f6805463ffffffff90921691839081106135f0576135f061524d565b906000526020600020906007020160010154105b15613658576101ff54604051600160201b90910462ffffff1681527f934837eeeed5a287f5fe16bb427a5d016fa89863a28cdc571dc1cf83f78a330c906020015b60405180910390a1600094505050505090565b600194505050505090565b6000806136736131c46101f55490565b90506000816136826101f55490565b61368c9190614ff0565b90506136c2604051806080016040528060008152602001600081526020016060815260200160006001600160a01b031681525090565b60006136ce6101f55490565b90505b82811115613946576101f56136e7600183614ff0565b815481106136f7576136f761524d565b9060005260206000209060040201604051806080016040529081600082015481526020016001820154815260200160028201805461373490614f00565b80601f016020809104026020016040519081016040528092919081815260200182805461376090614f00565b80156137ad5780601f10613782576101008083540402835291602001916137ad565b820191906000526020600020905b81548152906001019060200180831161379057829003601f168201915b5050509183525050600391909101546001600160a01b039081166020909201919091526101fa546060830151604051633af32abf60e01b815290831660048201529294501690633af32abf90602401602060405180830381865afa158015613819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061383d919061519f565b613899576101f58054806138535761385361537d565b60008281526020812060046000199093019283020181815560018101829055906138806002830182614592565b5060030180546001600160a01b03191690559055613934565b6101ff54602083015163ffffffff9091161115613934576101f58054806138c2576138c261537d565b60008281526020812060046000199093019283020181815560018101829055906138ef6002830182614592565b5060030180546001600160a01b03191690559055613934613911600183614ff0565b836060015161392885604001518660000151614012565b855160408701516112eb565b8061393e81615393565b9150506136d1565b50600060018311156139625761395d600184614ff0565b613965565b60005b90506139716101f55490565b158015906139b057506101ff546101f5805463ffffffff909216918390811061399c5761399c61524d565b906000526020600020906004020160010154105b15613658576101ff54604051600160201b90910462ffffff1681527f8f7cfb6b68938d4ebbb02e7d528338bcbccd9eb481fab6bcc9b2bfa17bd925ea90602001613645565b6139fe82612bbf565b610ea7838383614178565b60606000613a188360026151c1565b613a23906002614fbf565b6001600160401b03811115613a3a57613a3a6146b8565b6040519080825280601f01601f191660200182016040528015613a64576020820181803683370190505b509050600360fc1b81600081518110613a7f57613a7f61524d565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613aae57613aae61524d565b60200101906001600160f81b031916908160001a9053506000613ad28460026151c1565b613add906001614fbf565b90505b6001811115613b55576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613b1157613b1161524d565b1a60f81b828281518110613b2757613b2761524d565b60200101906001600160f81b031916908160001a90535060049490941c93613b4e81615393565b9050613ae0565b508315610e7a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ad6565b613bae8282611b29565b610f265760008281526097602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613be63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610e7a836001600160a01b038416614183565b613c498282611b29565b15610f265760008281526097602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610e7a836001600160a01b0384166141d2565b6000613d10826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166142c59092919063ffffffff16565b805190915015610ea75780806020019051810190613d2e919061519f565b610ea75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ad6565b600054610100900460ff166110b05760405162461bcd60e51b8152600401610ad690615202565b600054610100900460ff16613ddb5760405162461bcd60e51b8152600401610ad690615202565b8151613dee9060fe9060208501906144ae565b508051610ea79060ff9060208401906144ae565b600054610100900460ff16613e295760405162461bcd60e51b8152600401610ad690615202565b61015f805460ff19169055565b600054610100900460ff16613e5d5760405162461bcd60e51b8152600401610ad690615202565b613e686000336142dc565b613e927f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336142dc565b610f266000805160206154c1833981519152336142dc565b600054610100900460ff16613ed15760405162461bcd60e51b8152600401610ad690615202565b6110b033612e32565b6000826000018281548110613ef157613ef161524d565b9060005260206000200154905092915050565b6000818310613f135781610e7a565b5090919050565b6000806101f984604051613f2e9190614e8a565b908152604080516020928190038301812060a082018352805460608301908152600182015460808401528252600201546001600160a01b03811693820193909352600160a01b90920460ff1690820152905060006101f9613f8d611bf0565b604051613f9a9190614e8a565b908152604080516020928190038301812060a0820183528054606083018181526001830154608085015283526002909101546001600160a01b03811694830194909452600160a01b90930460ff1691810191909152835151909250613fff90866151c1565b61400991906151e0565b95945050505050565b6000806101f9846040516140269190614e8a565b908152604080516020928190038301812060a082018352805460608301908152600182015460808401528252600201546001600160a01b03811693820193909352600160a01b90920460ff1690820152905060006101f9614085611bf0565b6040516140929190614e8a565b908152604080516020928190038301812060a0820183528054606083018181526001830154608085015283526002909101546001600160a01b03811694830194909452600160a01b90930460ff16918101919091528351519092506000916140fa90876151c1565b61410491906151e0565b9050816040015160ff16836040015160ff16111561414f578160400151836040015161413091906153aa565b61413b90600a6154b1565b61414590826151c1565b9350505050610a17565b8260400151826040015161416391906153aa565b61416e90600a6154b1565b61414590826151e0565b610ea78383836142e6565b60008181526001830160205260408120546141ca57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a17565b506000610a17565b600081815260018301602052604081205480156142bb5760006141f6600183614ff0565b855490915060009061420a90600190614ff0565b905081811461426f57600086600001828154811061422a5761422a61524d565b906000526020600020015490508087600001848154811061424d5761424d61524d565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142805761428061537d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a17565b6000915050610a17565b60606142d4848460008561434d565b949350505050565b610f2682826128a1565b61015f5460ff1615610ea75760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610ad6565b6060824710156143ae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ad6565b843b6143fc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ad6565b600080866001600160a01b031685876040516144189190614e8a565b60006040518083038185875af1925050503d8060008114614455576040519150601f19603f3d011682016040523d82523d6000602084013e61445a565b606091505b509150915061446a828286614475565b979650505050505050565b60608315614484575081610e7a565b8251156144945782518084602001fd5b8160405162461bcd60e51b8152600401610ad69190614858565b8280546144ba90614f00565b90600052602060002090601f0160209004810192826144dc5760008555614522565b82601f106144f557805160ff1916838001178555614522565b82800160010185558215614522579182015b82811115614522578251825591602001919060010190614507565b5061452e9291506145c8565b5090565b508054600082559060005260206000209081019061115b91906145dd565b508054600082556004029060005260206000209081019061115b91906145fa565b508054600082556007029060005260206000209081019061115b9190614636565b50805461459e90614f00565b6000825580601f106145ae575050565b601f01602090049060005260206000209081019061115b91905b5b8082111561452e57600081556001016145c9565b8082111561452e5760006145f18282614592565b506001016145dd565b8082111561452e5760008082556001820181905561461b6002830182614592565b506003810180546001600160a01b03191690556004016145fa565b8082111561452e5760008082556001820181905560028201819055600382018190556146656004830182614592565b614673600583016000614592565b506006810180546001600160a01b0319169055600701614636565b6000602082840312156146a057600080fd5b81356001600160e01b031981168114610e7a57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f8301126146df57600080fd5b81356001600160401b03808211156146f9576146f96146b8565b604051601f8301601f19908116603f01168101908282118183101715614721576147216146b8565b8160405283815286602085880101111561473a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6001600160a01b038116811461115b57600080fd5b60008060008060008060c0878903121561478857600080fd5b8635955060208701356001600160401b03808211156147a657600080fd5b6147b28a838b016146ce565b965060408901359150808211156147c857600080fd5b506147d589828a016146ce565b94505060608701356147e68161475a565b9598949750929560808101359460a0909101359350915050565b60005b8381101561481b578181015183820152602001614803565b8381111561253a5750506000910152565b60008151808452614844816020860160208601614800565b601f01601f19169290920160200192915050565b602081526000610e7a602083018461482c565b6000806040838503121561487e57600080fd5b82356148898161475a565b946020939093013593505050565b6000602082840312156148a957600080fd5b81356001600160401b038111156148bf57600080fd5b6142d4848285016146ce565b6000806000606084860312156148e057600080fd5b83356148eb8161475a565b925060208401356148fb8161475a565b929592945050506040919091013590565b60006020828403121561491e57600080fd5b5035919050565b6000806040838503121561493857600080fd5b82359150602083013561494a8161475a565b809150509250929050565b6000806000806080858703121561496b57600080fd5b84356149768161475a565b93506020850135925060408501356001600160401b038082111561499957600080fd5b6149a5888389016146ce565b935060608701359150808211156149bb57600080fd5b506149c8878288016146ce565b91505092959194509250565b600080604083850312156149e757600080fd5b8235915060208301356001600160401b03811115614a0457600080fd5b614a10858286016146ce565b9150509250929050565b600080600080600060a08688031215614a3257600080fd5b853594506020860135614a448161475a565b9350604086013592506060860135915060808601356001600160401b03811115614a6d57600080fd5b614a79888289016146ce565b9150509295509295909350565b60008060408385031215614a9957600080fd5b82356001600160401b0380821115614ab057600080fd5b614abc868387016146ce565b93506020850135915080821115614ad257600080fd5b50614a10858286016146ce565b803563ffffffff81168114614af357600080fd5b919050565b600060208284031215614b0a57600080fd5b610e7a82614adf565b600060208284031215614b2557600080fd5b813562ffffff81168114610e7a57600080fd5b600060208284031215614b4a57600080fd5b8135610e7a8161475a565b600080600080600060a08688031215614b6d57600080fd5b85356001600160401b0380821115614b8457600080fd5b614b9089838a016146ce565b96506020880135915080821115614ba657600080fd5b50614bb3888289016146ce565b9450506040860135614bc48161475a565b92506060860135614bd48161475a565b9150614be260808701614adf565b90509295509295909350565b60008060408385031215614c0157600080fd5b82356001600160401b03811115614c1757600080fd5b614c23858286016146ce565b95602094909401359450505050565b60008060408385031215614c4557600080fd5b50508035926020909101359150565b60008060008060008060c08789031215614c6d57600080fd5b863595506020870135614c7f8161475a565b9450604087013593506060870135925060808701356001600160401b0380821115614ca957600080fd5b614cb58a838b016146ce565b935060a0890135915080821115614ccb57600080fd5b50614cd889828a016146ce565b9150509295509295509295565b848152836020820152608060408201526000614d04608083018561482c565b905060018060a01b038316606083015295945050505050565b60008060208385031215614d3057600080fd5b82356001600160401b0380821115614d4757600080fd5b818501915085601f830112614d5b57600080fd5b813581811115614d6a57600080fd5b8660208260051b8501011115614d7f57600080fd5b60209290920196919550909350505050565b60008060408385031215614da457600080fd5b8235614daf8161475a565b9150602083013561494a8161475a565b60008060008060808587031215614dd557600080fd5b84356001600160401b03811115614deb57600080fd5b614df7878288016146ce565b9450506020850135614e088161475a565b925060408501359150606085013560ff81168114614e2557600080fd5b939692955090935050565b87815286602082015285604082015284606082015260e060808201526000614e5b60e083018661482c565b82810360a0840152614e6d818661482c565b91505060018060a01b03831660c083015298975050505050505050565b60008251614e9c818460208701614800565b9190910192915050565b87815286602082015260e060408201526000614ec560e083018861482c565b8281036060840152614ed7818861482c565b6001600160a01b03969096166080840152505060a081019290925260c090910152949350505050565b600181811c90821680614f1457607f821691505b60208210811415614f3557634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60018060a01b0385168152836020820152608060408201526000614f97608083018561482c565b828103606084015261446a818561482c565b634e487b7160e01b600052601160045260246000fd5b60008219821115614fd257614fd2614fa9565b500190565b600060208284031215614fe957600080fd5b5051919050565b60008282101561500257615002614fa9565b500390565b86815285602082015284604082015260c06060820152600061502c60c083018661482c565b6001600160a01b039490941660808301525062ffffff9190911660a090910152949350505050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b87815286602082015285604082015260e0606082015260006150c760e083018761482c565b82810360808401526150d9818761482c565b6001600160a01b039590951660a0840152505062ffffff9190911660c09091015295945050505050565b600062ffffff80831681851680830382111561512157615121614fa9565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615162816017850160208801614800565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351615193816028840160208801614800565b01602801949350505050565b6000602082840312156151b157600080fd5b81518015158114610e7a57600080fd5b60008160001904831182151516156151db576151db614fa9565b500290565b6000826151fd57634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600080835461527181614f00565b60018281168015615289576001811461529a576152c9565b60ff198416875282870194506152c9565b8760005260208060002060005b858110156152c05781548a8201529084019082016152a7565b50505082870194505b50929695505050505050565b82815260006020604081840152600084546152ef81614f00565b8060408701526060600180841660008114615311576001811461532557615353565b60ff19851689840152608089019550615353565b896000528660002060005b8581101561534b5781548b8201860152908301908801615330565b8a0184019650505b50939998505050505050505050565b600060001982141561537657615376614fa9565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6000816153a2576153a2614fa9565b506000190190565b600060ff821660ff8416808210156153c4576153c4614fa9565b90039392505050565b600181815b808511156154085781600019048211156153ee576153ee614fa9565b808516156153fb57918102915b93841c93908002906153d2565b509250929050565b60008261541f57506001610a17565b8161542c57506000610a17565b8160018114615442576002811461544c57615468565b6001915050610a17565b60ff84111561545d5761545d614fa9565b50506001821b610a17565b5060208310610133831016604e8410600b841016171561548b575081810a610a17565b61549583836153cd565b80600019048211156154a9576154a9614fa9565b029392505050565b6000610e7a60ff84168361541056fe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a223cfe2c0a4dbfcf8621cfba4fcd5a1de04c83287ea0b145335497fea1e77c46a2646970667358221220dbd4e0d77a7971b63e4360f908e246ae44743bbe347e9f9b7d61d15d46fcda3e64736f6c634300080b0033

Deployed ByteCode Sourcemap

79404:21791:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63978:225;;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;63978:225:0;;;;;;;;85733:734;;;;;;:::i;:::-;;:::i;:::-;;17889:100;;;:::i;:::-;;;;;;;:::i;20056:169::-;;;;;;:::i;:::-;;:::i;19009:108::-;19097:12;;19009:108;;;3596:25:1;;;3584:2;3569:18;19009:108:0;3450:177:1;80479:40:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80479:40:0;;;-1:-1:-1;;;80479:40:0;;;;;;;;;;4222:13:1;;4204:32;;4292:4;4280:17;;;4274:24;4252:20;;;4245:54;;;;-1:-1:-1;;;;;4335:32:1;;;4315:18;;;4308:60;;;;4416:4;4404:17;4399:2;4384:18;;4377:45;4191:3;4176:19;80479:40:0;3959:469:1;91769:217:0;;;;;;:::i;:::-;;:::i;46756:123::-;;;;;;:::i;:::-;46822:7;46849:12;;;:6;:12;;;;;:22;;;;46756:123;47141:147;;;;;;:::i;:::-;;:::i;18851:93::-;;;18934:2;5723:36:1;;5711:2;5696:18;18851:93:0;5581:184:1;48189:218:0;;;;;;:::i;:::-;;:::i;90221:301::-;;;;;;:::i;:::-;;:::i;21608:215::-;;;;;;:::i;:::-;;:::i;79632:78::-;;-1:-1:-1;;;;;;;;;;;79632:78:0;;69119:178;;;:::i;68310:205::-;;;;;;:::i;:::-;;:::i;80563:25::-;;;;;-1:-1:-1;;;;;80563:25:0;;;;;;-1:-1:-1;;;;;6686:32:1;;;6668:51;;6656:2;6641:18;80563:25:0;6522:203:1;28765:91:0;;;;;;:::i;:::-;;:::i;84305:516::-;;;;;;:::i;:::-;;:::i;93640:832::-;;;;;;:::i;:::-;;:::i;80666:31::-;;;;;;;;;;;;;;;8152:8:1;8140:21;;;8122:40;;8110:2;8095:18;80666:31:0;7978:190:1;66821:152:0;;;;;;:::i;:::-;;:::i;80735:24::-;;;;;;;;;;;;8895:10:1;8883:23;;;8865:42;;8853:2;8838:18;80735:24:0;8721:192:1;79546:81:0;;79585:42;79546:81;;92754:157;;;;;;:::i;:::-;;:::i;80367:32::-;;;;;;:::i;:::-;;:::i;80593:33::-;;;;;;30975:86;31046:7;;;;30975:86;;88433:316;;;;;;:::i;:::-;;:::i;88100:171::-;;;;;;:::i;:::-;;:::i;80631:30::-;;;;;;;;;19180:127;;;;;;:::i;:::-;-1:-1:-1;;;;;19281:18:0;19254:7;19281:18;;;:9;:18;;;;;;;19180:127;71554:103;;;:::i;91385:120::-;;;;;;:::i;:::-;;:::i;82717:644::-;;;;;;:::i;:::-;;:::i;87598:284::-;;;;;;:::i;:::-;;:::i;80406:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80406:68:0;;;;;;;;;;;68729:172;;;:::i;80526:32::-;;;;;-1:-1:-1;;;;;80526:32:0;;;70903:87;70976:6;;-1:-1:-1;;;;;70976:6:0;70903:87;;64802:145;;;;;;:::i;:::-;;:::i;45619:139::-;;;;;;:::i;:::-;;:::i;95002:484::-;;;;;;:::i;:::-;;:::i;18108:104::-;;;:::i;80702:26::-;;;;;;79715:84;;79764:35;79715:84;;44699:49;;44744:4;44699:49;;22326:413;;;;;;:::i;:::-;;:::i;19520:175::-;;;;;;:::i;:::-;;:::i;84897:97::-;84970:11;:18;84897:97;;89713:167;;;;;;:::i;:::-;;:::i;80295:31::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;65121:134::-;;;;;;:::i;:::-;;:::i;86625:315::-;;;;;;:::i;:::-;;:::i;80764:26::-;;;;;-1:-1:-1;;;80764:26:0;;;;;;85070:97;85143:11;:18;85070:97;;66979:62;;67017:24;66979:62;;47533:149;;;;;;:::i;:::-;;:::i;83603:91::-;;;:::i;19758:151::-;;;;;;:::i;:::-;-1:-1:-1;;;;;19874:18:0;;;19847:7;19874:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;19758:151;83438:98;;;:::i;87076:283::-;;;;;;:::i;:::-;;:::i;67048:62::-;;-1:-1:-1;;;;;;;;;;;67048:62:0;;89256:334;;;;;;:::i;:::-;;:::i;71812:201::-;;;;;;:::i;:::-;;:::i;80331:31::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;:::i;63978:225::-;64063:4;-1:-1:-1;;;;;;64087:68:0;;-1:-1:-1;;;64087:68:0;;:108;;;64159:36;64183:11;64159:23;:36::i;:::-;64080:115;63978:225;-1:-1:-1;;63978:225:0:o;85733:734::-;100414:76;79764:35;100414:76;;;;;;;;;;;;;-1:-1:-1;;;100414:76:0;;;100477:12;15262:10;;15182:98;100477:12;100414;:76::i;:::-;85967:7:::1;85975:16;85967:25;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:41;85959:73:::1;;;::::0;-1:-1:-1;;;85959:73:0;;15951:2:1;85959:73:0::1;::::0;::::1;15933:21:1::0;15990:2;15970:18;;;15963:30;-1:-1:-1;;;16009:18:1;;;16002:44;16063:18;;85959:73:0::1;;;;;;;;;86056:1;86047:6;:10;86039:37;;;::::0;-1:-1:-1;;;86039:37:0;;16294:2:1;86039:37:0::1;::::0;::::1;16276:21:1::0;16333:2;16313:18;;;16306:30;-1:-1:-1;;;16352:18:1;;;16345:44;16406:18;;86039:37:0::1;16092:338:1::0;86039:37:0::1;86092:17;86110:15;86092:34;;;;;;:::i;:::-;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;:41:::1;::::0;;;;;;;;::::1;;86091:42;86083:71;;;::::0;-1:-1:-1;;;86083:71:0;;16637:2:1;86083:71:0::1;::::0;::::1;16619:21:1::0;16676:2;16656:18;;;16649:30;-1:-1:-1;;;16695:18:1;;;16688:46;16751:18;;86083:71:0::1;16435:340:1::0;86083:71:0::1;86207:4;86163:17;86181:15;86163:34;;;;;;:::i;:::-;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;:41:::1;::::0;;;;;;;;;:48;;-1:-1:-1;;86163:48:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;86243:96:::1;::::0;::::1;::::0;;;;;86262:15:::1;86243:96:::0;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86243:96:0;::::1;::::0;;;;86218:11:::1;:128:::0;;-1:-1:-1;86218:128:0;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;86163:34;;86218:128;;::::1;::::0;;;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;86218:128:0::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;86218:128:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;;86218:128:0::1;-1:-1:-1::0;;;;;86218:128:0;;::::1;::::0;;;::::1;::::0;;86358:103:::1;::::0;::::1;::::0;::::1;::::0;86376:6;;86384:15:::1;::::0;86401:16;;86419:15;;86436:8;;86446:7;;86455:5;;86358:103:::1;:::i;:::-;;;;;;;;85733:734:::0;;;;;;:::o;17889:100::-;17943:13;17976:5;17969:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17889:100;:::o;20056:169::-;20139:4;20156:39;15262:10;20179:7;20188:6;20156:8;:39::i;:::-;-1:-1:-1;20213:4:0;20056:169;;;;:::o;91769:217::-;91913:4;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;91926:36:::1;91936:6;91944:9;91955:6;91926:9;:36::i;:::-;-1:-1:-1::0;91976:4:0::1;100362:1;91769:217:::0;;;;;:::o;47141:147::-;46822:7;46849:12;;;:6;:12;;;;;:22;;;45190:30;45201:4;15262:10;45190;:30::i;:::-;47255:25:::1;47266:4;47272:7;47255:10;:25::i;:::-;47141:147:::0;;;:::o;48189:218::-;-1:-1:-1;;;;;48285:23:0;;15262:10;48285:23;48277:83;;;;-1:-1:-1;;;48277:83:0;;18141:2:1;48277:83:0;;;18123:21:1;18180:2;18160:18;;;18153:30;18219:34;18199:18;;;18192:62;-1:-1:-1;;;18270:18:1;;;18263:45;18325:19;;48277:83:0;17939:411:1;48277:83:0;48373:26;48385:4;48391:7;48373:11;:26::i;:::-;48189:218;;:::o;90221:301::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;90399:1:::1;90390:6;:10;90382:37;;;::::0;-1:-1:-1;;;90382:37:0;;16294:2:1;90382:37:0::1;::::0;::::1;16276:21:1::0;16333:2;16313:18;;;16306:30;-1:-1:-1;;;16352:18:1;;;16345:44;16406:18;;90382:37:0::1;16092:338:1::0;90382:37:0::1;90426:22;90431:8;90441:6;90426:4;:22::i;:::-;90460:56;90483:8;90493:6;90501;90509;90460:56;;;;;;;;;:::i;:::-;;;;;;;;90221:301:::0;;;;:::o;21608:215::-;15262:10;21696:4;21745:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;21745:34:0;;;;;;;;;;21696:4;;21713:80;;21736:7;;21745:47;;21782:10;;21745:47;:::i;:::-;21713:8;:80::i;69119:178::-;69172:34;-1:-1:-1;;;;;;;;;;;15262:10:0;45619:139;:::i;69172:34::-;69164:104;;;;-1:-1:-1;;;69164:104:0;;19741:2:1;69164:104:0;;;19723:21:1;19780:2;19760:18;;;19753:30;19819:34;19799:18;;;19792:62;19890:27;19870:18;;;19863:55;19935:19;;69164:104:0;19539:421:1;69164:104:0;69279:10;:8;:10::i;:::-;69119:178::o;68310:205::-;68386:34;67017:24;15262:10;45619:139;:::i;68386:34::-;68378:101;;;;-1:-1:-1;;;68378:101:0;;20167:2:1;68378:101:0;;;20149:21:1;20206:2;20186:18;;;20179:30;20245:34;20225:18;;;20218:62;-1:-1:-1;;;20296:18:1;;;20289:52;20358:19;;68378:101:0;19965:418:1;68378:101:0;68490:17;68496:2;68500:6;68490:5;:17::i;28765:91::-;28821:27;15262:10;28841:6;28821:5;:27::i;:::-;28765:91;:::o;84305:516::-;100200:29;15262:10;100200:15;:29::i;:::-;84438:6:::1;100570:33;100596:6;100570:25;:33::i;:::-;84491:14:::0;84464:23:::2;15262:10:::0;84474:12:::2;15182:98:::0;84464:23:::2;:41;;84456:68;;;::::0;-1:-1:-1;;;84456:68:0;;20590:2:1;84456:68:0::2;::::0;::::2;20572:21:1::0;20629:2;20609:18;;;20602:30;-1:-1:-1;;;20648:18:1;;;20641:44;20702:18;;84456:68:0::2;20388:338:1::0;84456:68:0::2;84557:18;;84539:14;:36;;84531:63;;;::::0;-1:-1:-1;;;84531:63:0;;20933:2:1;84531:63:0::2;::::0;::::2;20915:21:1::0;20972:2;20952:18;;;20945:30;-1:-1:-1;;;20991:18:1;;;20984:44;21045:18;;84531:63:0::2;20731:338:1::0;84531:63:0::2;84603:38;79585:42;84626:14;84603:8;:38::i;:::-;;84648:11;84665:65;;;;;;;;84676:14;84665:65;;;;84692:15;84665:65;;;;84709:6;84665:65;;;;84717:12;15262:10:::0;;15182:98;84717:12:::2;-1:-1:-1::0;;;;;84665:65:0::2;::::0;;84648:83;;::::2;::::0;;::::2;::::0;;-1:-1:-1;84648:83:0;;;::::2;::::0;;;;;;::::2;::::0;;::::2;;::::0;;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;-1:-1:-1::0;84648:83:0::2;::::0;;;::::2;::::0;::::2;::::0;;::::2;::::0;;-1:-1:-1;;;;;;84648:83:0::2;-1:-1:-1::0;;;;;84648:83:0;;::::2;::::0;;;::::2;::::0;;84743:72:::2;84761:14:::0;84777:15:::2;84794:6:::0;15262:10;84743:72:::2;;;;;;;;;:::i;:::-;;;;;;;;100236:1:::1;84305:516:::0;;:::o;93640:832::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;93838:22:::1;93863:7;93871:6;93863:15;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:31:::1;;::::0;-1:-1:-1;;;93905:57:0;;93956:4:::1;93905:57;::::0;::::1;6668:51:1::0;-1:-1:-1;;;;;93863:31:0::1;::::0;-1:-1:-1;93965:24:0;;93863:31;;93905:42:::1;::::0;6641:18:1;;93905:57:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;93901:566;;;94000:49;79585:42;94027:8;94037:11;94000:12;:49::i;:::-;;93901:566;;;94072:15;94090:42;94107:24;94090:16;:42::i;:::-;94072:60;;94141:32;79585:42;94161:11;94141:5;:32::i;:::-;94228:10;::::0;94182:66:::1;::::0;-1:-1:-1;;;;;94182:45:0;;::::1;::::0;94228:10:::1;94240:7:::0;94182:45:::1;:66::i;:::-;94257:93;94303:8:::0;94314:34:::1;94341:7:::0;94314:24;:34:::1;:::i;:::-;-1:-1:-1::0;;;;;94257:45:0;::::1;::::0;:93;:45:::1;:93::i;:::-;94446:12;::::0;94364:95:::1;::::0;::::1;::::0;::::1;::::0;94380:7;;94389:11;;94402:24;;94428:6;;94436:8;;-1:-1:-1;;;94446:12:0;::::1;;;::::0;94364:95:::1;:::i;:::-;;;;;;;;94063:404;93901:566;93831:641;93640:832:::0;;;;;:::o;66821:152::-;13439:13;;;;;;;:48;;13475:12;;;;13474:13;13439:48;;;14242:4;5002:20;5050:8;13455:16;13431:107;;;;-1:-1:-1;;;13431:107:0;;;;;;;:::i;:::-;13551:19;13574:13;;;;;;13573:14;13598:101;;;;13633:13;:20;;-1:-1:-1;;13668:19:0;;;;;13598:101;66921:44:::1;66952:4;66958:6;66921:30;:44::i;:::-;13729:14:::0;13725:68;;;13776:5;13760:21;;-1:-1:-1;;13760:21:0;;;13146:654;66821:152;;:::o;92754:157::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;92841:15:::1;92833:4;:23;;;;92825:56;;;::::0;-1:-1:-1;;;92825:56:0;;22634:2:1;92825:56:0::1;::::0;::::1;22616:21:1::0;22673:2;22653:18;;;22646:30;-1:-1:-1;;;22692:18:1;;;22685:50;22752:18;;92825:56:0::1;22432:344:1::0;92825:56:0::1;92888:10;:17:::0;;-1:-1:-1;;92888:17:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;92754:157::o;80367:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88433:316::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;88549:1:::1;88526:20;:24;;;88518:55;;;::::0;-1:-1:-1;;;88518:55:0;;22983:2:1;88518:55:0::1;::::0;::::1;22965:21:1::0;23022:2;23002:18;;;22995:30;-1:-1:-1;;;23041:18:1;;;23034:48;23099:18;;88518:55:0::1;22781:342:1::0;88518:55:0::1;88611:4;88588:20;:27;;;88580:59;;;::::0;-1:-1:-1;;;88580:59:0;;23330:2:1;88580:59:0::1;::::0;::::1;23312:21:1::0;23369:2;23349:18;;;23342:30;-1:-1:-1;;;23388:18:1;;;23381:49;23447:18;;88580:59:0::1;23128:343:1::0;88580:59:0::1;88646:17;:40:::0;;-1:-1:-1;;88646:40:0::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;88698:45:::1;::::0;8122:40:1;;;88698:45:0::1;::::0;8110:2:1;8095:18;88698:45:0::1;;;;;;;88433:316:::0;:::o;88100:171::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;88204:1:::1;88185:16;:20;;;88177:46;;;::::0;-1:-1:-1;;;88177:46:0;;23678:2:1;88177:46:0::1;::::0;::::1;23660:21:1::0;23717:2;23697:18;;;23690:30;-1:-1:-1;;;23736:18:1;;;23729:43;23789:18;;88177:46:0::1;23476:337:1::0;88177:46:0::1;88230:16;:35:::0;;-1:-1:-1;;88230:35:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;88100:171::o;71554:103::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;71619:30:::1;71646:1;71619:18;:30::i;91385:120::-:0;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;91477:22:::1;91483:7;91492:6;91477:5;:22::i;82717:644::-:0;13439:13;;;;;;;:48;;13475:12;;;;13474:13;13439:48;;;14242:4;5002:20;5050:8;13455:16;13431:107;;;;-1:-1:-1;;;13431:107:0;;;;;;;:::i;:::-;13551:19;13574:13;;;;;;13573:14;13598:101;;;;13633:13;:20;;-1:-1:-1;;13668:19:0;;;;;13598:101;82924:44:::1;82955:4;82961:6;82924:30;:44::i;:::-;82975:16;:14;:16::i;:::-;82998:17;:15;:17::i;:::-;-1:-1:-1::0;;;;;83032:36:0;::::1;83024:69;;;::::0;-1:-1:-1;;;83024:69:0;;24020:2:1;83024:69:0::1;::::0;::::1;24002:21:1::0;24059:2;24039:18;;;24032:30;-1:-1:-1;;;24078:18:1;;;24071:50;24138:18;;83024:69:0::1;23818:344:1::0;83024:69:0::1;83102:17;:42:::0;;-1:-1:-1;;;;;83102:42:0;;::::1;-1:-1:-1::0;;;;;;83102:42:0;;::::1;;::::0;;;83151:10:::1;:28:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;83209:7:::1;83188:18;:28:::0;;;83223:16:::1;:21:::0;;83251:22;-1:-1:-1;;83251:22:0;;;;;;83280:10:::1;:24:::0;;-1:-1:-1;;83311:16:0;83280:24:::1;::::0;::::1;83311:16:::0;;;83334:11:::1;:21:::0;13725:68;;;;13776:5;13760:21;;-1:-1:-1;;13760:21:0;;;13146:654;82717:644;;;;;:::o;87598:284::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;87725:6:::1;100570:33;100596:6;100570:25;:33::i;:::-;87743:84:::2;15262:10:::0;87820:6:::2;87760:7;87768:6;87760:15;;;;;;:::i;:::-;::::0;;;::::2;::::0;;;;;::::2;::::0;;;:31:::2;;::::0;-1:-1:-1;;;;;87760:31:0::2;::::0;87743:84;:62:::2;:84::i;:::-;87839:37;::::0;3596:25:1;;;15262:10:0;;87839:37:::2;::::0;3584:2:1;3569:18;87839:37:0::2;;;;;;;100362:1:::1;87598:284:::0;;:::o;68729:172::-;68780:34;-1:-1:-1;;;;;;;;;;;15262:10:0;45619:139;:::i;68780:34::-;68772:102;;;;-1:-1:-1;;;68772:102:0;;24369:2:1;68772:102:0;;;24351:21:1;24408:2;24388:18;;;24381:30;24447:34;24427:18;;;24420:62;24518:25;24498:18;;;24491:53;24561:19;;68772:102:0;24167:419:1;68772:102:0;68885:8;:6;:8::i;64802:145::-;64884:7;64911:18;;;:12;:18;;;;;:28;;64933:5;64911:21;:28::i;45619:139::-;45697:4;45721:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45721:29:0;;;;;;;;;;;;;;;45619:139::o;95002:484::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;95252:32:::1;95258:8;95268:15;95252:5;:32::i;:::-;95296:184;95320:7;95336:24;95369:15;95393:18;95420:15;95444:8;95461:12;;;;;;;;;;;95296:184;;;;;;;;;;;;:::i;18108:104::-:0;18164:13;18197:7;18190:14;;;;;:::i;22326:413::-;15262:10;22419:4;22463:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;22463:34:0;;;;;;;;;;22516:35;;;;22508:85;;;;-1:-1:-1;;;22508:85:0;;25581:2:1;22508:85:0;;;25563:21:1;25620:2;25600:18;;;25593:30;25659:34;25639:18;;;25632:62;-1:-1:-1;;;25710:18:1;;;25703:35;25755:19;;22508:85:0;25379:401:1;22508:85:0;22629:67;15262:10;22652:7;22680:15;22661:16;:34;22629:8;:67::i;19520:175::-;19606:4;19623:42;15262:10;19647:9;19658:6;19623:9;:42::i;89713:167::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;89794:27:0;::::1;89786:55;;;::::0;-1:-1:-1;;;89786:55:0;;25987:2:1;89786:55:0::1;::::0;::::1;25969:21:1::0;26026:2;26006:18;;;25999:30;-1:-1:-1;;;26045:18:1;;;26038:45;26100:18;;89786:55:0::1;25785:339:1::0;89786:55:0::1;89848:10;:26:::0;;-1:-1:-1;;;;;;89848:26:0::1;-1:-1:-1::0;;;;;89848:26:0;;;::::1;::::0;;;::::1;::::0;;89713:167::o;80295:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;80295:31:0;;;;;;;-1:-1:-1;;;;;;;80295:31:0;;:::o;65121:134::-;65193:7;65220:18;;;:12;:18;;;;;:27;;:25;:27::i;86625:315::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;86711:17;86703:38:::1;;;::::0;-1:-1:-1;;;86703:38:0;;26331:2:1;86703:38:0::1;::::0;::::1;26313:21:1::0;26370:1;26350:18;;;26343:29;-1:-1:-1;;;26388:18:1;;;26381:38;26436:18;;86703:38:0::1;26129:331:1::0;86703:38:0::1;86748:26;86767:6;;86748:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;86748:18:0::1;::::0;-1:-1:-1;;;86748:26:0:i:1;:::-;86787:27;:25;:27::i;:::-;:58;;;;;86818:27;:25;:27::i;:::-;86783:117;;;86875:12;::::0;86856:36:::1;::::0;86875:16:::1;::::0;-1:-1:-1;;;86875:12:0;::::1;;;86890:1;86875:16;:::i;:::-;93129:12:::0;:28;;;;;;-1:-1:-1;;;93129:28:0;-1:-1:-1;;93129:28:0;;;;;;;;;93063:100;86856:36:::1;86921:12;::::0;86913:21:::1;::::0;-1:-1:-1;;;86921:12:0;;::::1;;;8122:40:1::0;;86913:21:0::1;::::0;8110:2:1;8095:18;86913:21:0::1;;;;;;;86625:315:::0;;:::o;47533:149::-;46822:7;46849:12;;;:6;:12;;;;;:22;;;45190:30;45201:4;15262:10;45190;:30::i;:::-;47648:26:::1;47660:4;47666:7;47648:11;:26::i;83603:91::-:0;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;83665:23:::1;83672:16;;83665:23;:::i;83438:98::-:0;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;83487:18:::1;83494:11;;83487:18;:::i;:::-;83512;83519:11;;83512:18;:::i;87076:283::-:0;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;87155:28:0;::::1;87147:56;;;::::0;-1:-1:-1;;;87147:56:0;;25987:2:1;87147:56:0::1;::::0;::::1;25969:21:1::0;26026:2;26006:18;;;25999:30;-1:-1:-1;;;26045:18:1;;;26038:45;26100:18;;87147:56:0::1;25785:339:1::0;87147:56:0::1;87228:30;::::0;-1:-1:-1;;;87228:30:0;;87252:4:::1;87228:30;::::0;::::1;6668:51:1::0;87210:15:0::1;::::0;-1:-1:-1;;;;;87228:15:0;::::1;::::0;::::1;::::0;6641:18:1;;87228:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87210:48;;87267:36;87286:7;70976:6:::0;;-1:-1:-1;;;;;70976:6:0;;70903:87;87286:7:::1;-1:-1:-1::0;;;;;87267:18:0;::::1;::::0;87295:7;87267:18:::1;:36::i;:::-;87337:5;-1:-1:-1::0;;;;;87315:38:0::1;;87345:7;87315:38;;;;3596:25:1::0;;3584:2;3569:18;;3450:177;87315:38:0::1;;;;;;;;87140:219;87076:283:::0;:::o;89256:334::-;100285:70;-1:-1:-1;;;;;;;;;;;100285:70:0;;;;;;;;;;;;;-1:-1:-1;;;100285:70:0;;;100342:12;15262:10;;15182:98;100285:70;89436:1:::1;89424:9;:13;89416:43;;;::::0;-1:-1:-1;;;89416:43:0;;27094:2:1;89416:43:0::1;::::0;::::1;27076:21:1::0;27133:2;27113:18;;;27106:30;-1:-1:-1;;;27152:18:1;;;27145:47;27209:18;;89416:43:0::1;26892:341:1::0;89416:43:0::1;89484:64;::::0;;89491:29;;;;;89484:64:::1;::::0;::::1;89491:29:::0;;;89508:11:::1;::::0;89491:29;;;;89484:64;;-1:-1:-1;;;;;89484:64:0;::::1;89491:29;89484:64:::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;89466:15;;:7:::1;::::0;:15:::1;::::0;89474:6;;89466:15:::1;:::i;:::-;::::0;;;::::1;::::0;;;;;;::::1;::::0;;;;;;:82;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;;-1:-1:-1::0;;;89466:82:0::1;-1:-1:-1::0;;;;;;89466:82:0;;;-1:-1:-1;;;;;89466:82:0;;::::1;::::0;;;;;;;::::1;::::0;;89555:16:::1;:29:::0;;;;::::1;::::0;;89466:82:::1;89555:29:::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;89256:334:::0;;;;:::o;71812:201::-;70976:6;;-1:-1:-1;;;;;70976:6:0;15262:10;71123:23;71115:68;;;;-1:-1:-1;;;71115:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;71901:22:0;::::1;71893:73;;;::::0;-1:-1:-1;;;71893:73:0;;27440:2:1;71893:73:0::1;::::0;::::1;27422:21:1::0;27479:2;27459:18;;;27452:30;27518:34;27498:18;;;27491:62;-1:-1:-1;;;27569:18:1;;;27562:36;27615:19;;71893:73:0::1;27238:402:1::0;71893:73:0::1;71977:28;71996:8;71977:18;:28::i;80331:31::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;80331:31:0;;;;;;;-1:-1:-1;;;;;;;80331:31:0;;:::o;45312:215::-;45397:4;-1:-1:-1;;;;;;45421:58:0;;-1:-1:-1;;;45421:58:0;;:98;;-1:-1:-1;;;;;;;;;;42276:51:0;;;45483:36;42167:168;100658:166;100784:23;100792:4;100798:8;100784:7;:23::i;:::-;100809:8;100776:42;;;;;-1:-1:-1;;;100776:42:0;;;;;;;;:::i;:::-;;100658:166;;;:::o;26010:380::-;-1:-1:-1;;;;;26146:19:0;;26138:68;;;;-1:-1:-1;;;26138:68:0;;27847:2:1;26138:68:0;;;27829:21:1;27886:2;27866:18;;;27859:30;27925:34;27905:18;;;27898:62;-1:-1:-1;;;27976:18:1;;;27969:34;28020:19;;26138:68:0;27645:400:1;26138:68:0;-1:-1:-1;;;;;26225:21:0;;26217:68;;;;-1:-1:-1;;;26217:68:0;;28252:2:1;26217:68:0;;;28234:21:1;28291:2;28271:18;;;28264:30;28330:34;28310:18;;;28303:62;-1:-1:-1;;;28381:18:1;;;28374:32;28423:19;;26217:68:0;28050:398:1;26217:68:0;-1:-1:-1;;;;;26298:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;26350:32;;3596:25:1;;;26350:32:0;;3569:18:1;26350:32:0;;;;;;;26010:380;;;:::o;23229:733::-;-1:-1:-1;;;;;23369:20:0;;23361:70;;;;-1:-1:-1;;;23361:70:0;;28655:2:1;23361:70:0;;;28637:21:1;28694:2;28674:18;;;28667:30;28733:34;28713:18;;;28706:62;-1:-1:-1;;;28784:18:1;;;28777:35;28829:19;;23361:70:0;28453:401:1;23361:70:0;-1:-1:-1;;;;;23450:23:0;;23442:71;;;;-1:-1:-1;;;23442:71:0;;29061:2:1;23442:71:0;;;29043:21:1;29100:2;29080:18;;;29073:30;29139:34;29119:18;;;29112:62;-1:-1:-1;;;29190:18:1;;;29183:33;29233:19;;23442:71:0;28859:399:1;23442:71:0;23526:47;23547:6;23555:9;23566:6;23526:20;:47::i;:::-;-1:-1:-1;;;;;23610:17:0;;23586:21;23610:17;;;:9;:17;;;;;;23646:23;;;;23638:74;;;;-1:-1:-1;;;23638:74:0;;29465:2:1;23638:74:0;;;29447:21:1;29504:2;29484:18;;;29477:30;29543:34;29523:18;;;29516:62;-1:-1:-1;;;29594:18:1;;;29587:36;29640:19;;23638:74:0;29263:402:1;23638:74:0;-1:-1:-1;;;;;23748:17:0;;;;;;;:9;:17;;;;;;23768:22;;;23748:42;;23812:20;;;;;;;;:30;;23784:6;;23748:17;23812:30;;23784:6;;23812:30;:::i;:::-;;;;;;;;23877:9;-1:-1:-1;;;;;23860:35:0;23869:6;-1:-1:-1;;;;;23860:35:0;;23888:6;23860:35;;;;3596:25:1;;3584:2;3569:18;;3450:177;23860:35:0;;;;;;;;23908:46;47141:147;46048:519;46129:22;46137:4;46143:7;46129;:22::i;:::-;46124:436;;46317:52;46356:7;-1:-1:-1;;;;;46317:52:0;46366:2;46317:30;:52::i;:::-;46442:49;46481:4;46488:2;46442:30;:49::i;:::-;46222:292;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;46222:292:0;;;;;;;;;;-1:-1:-1;;;46168:380:0;;;;;;;:::i;65348:169::-;65436:31;65453:4;65459:7;65436:16;:31::i;:::-;65478:18;;;;:12;:18;;;;;:31;;65501:7;65478:22;:31::i;65611:174::-;65700:32;65718:4;65724:7;65700:17;:32::i;:::-;65743:18;;;;:12;:18;;;;;:34;;65769:7;65743:25;:34::i;32034:120::-;31046:7;;;;31570:41;;;;-1:-1:-1;;;31570:41:0;;30663:2:1;31570:41:0;;;30645:21:1;30702:2;30682:18;;;30675:30;-1:-1:-1;;;30721:18:1;;;30714:50;30781:18;;31570:41:0;30461:344:1;31570:41:0;32093:7:::1;:15:::0;;-1:-1:-1;;32093:15:0::1;::::0;;32124:22:::1;15262:10:::0;32133:12:::1;32124:22;::::0;-1:-1:-1;;;;;6686:32:1;;;6668:51;;6656:2;6641:18;32124:22:0::1;;;;;;;32034:120::o:0;24249:399::-;-1:-1:-1;;;;;24333:21:0;;24325:65;;;;-1:-1:-1;;;24325:65:0;;31012:2:1;24325:65:0;;;30994:21:1;31051:2;31031:18;;;31024:30;31090:33;31070:18;;;31063:61;31141:18;;24325:65:0;30810:355:1;24325:65:0;24403:49;24432:1;24436:7;24445:6;24403:20;:49::i;:::-;24481:6;24465:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;24498:18:0;;;;;;:9;:18;;;;;:28;;24520:6;;24498:18;:28;;24520:6;;24498:28;:::i;:::-;;;;-1:-1:-1;;24542:37:0;;3596:25:1;;;-1:-1:-1;;;;;24542:37:0;;;24559:1;;24542:37;;3584:2:1;3569:18;24542:37:0;;;;;;;48189:218;;:::o;24981:591::-;-1:-1:-1;;;;;25065:21:0;;25057:67;;;;-1:-1:-1;;;25057:67:0;;31372:2:1;25057:67:0;;;31354:21:1;31411:2;31391:18;;;31384:30;31450:34;31430:18;;;31423:62;-1:-1:-1;;;31501:18:1;;;31494:31;31542:19;;25057:67:0;31170:397:1;25057:67:0;25137:49;25158:7;25175:1;25179:6;25137:20;:49::i;:::-;-1:-1:-1;;;;;25224:18:0;;25199:22;25224:18;;;:9;:18;;;;;;25261:24;;;;25253:71;;;;-1:-1:-1;;;25253:71:0;;31774:2:1;25253:71:0;;;31756:21:1;31813:2;31793:18;;;31786:30;31852:34;31832:18;;;31825:62;-1:-1:-1;;;31903:18:1;;;31896:32;31945:19;;25253:71:0;31572:398:1;25253:71:0;-1:-1:-1;;;;;25360:18:0;;;;;;:9;:18;;;;;25381:23;;;25360:44;;25426:12;:22;;25398:6;;25360:18;25426:22;;25398:6;;25426:22;:::i;:::-;;;;-1:-1:-1;;25466:37:0;;3596:25:1;;;25492:1:0;;-1:-1:-1;;;;;25466:37:0;;;;;3584:2:1;3569:18;25466:37:0;;;;;;;47141:147;;;:::o;100856:157::-;100945:17;;100927:60;;-1:-1:-1;;;100927:60:0;;-1:-1:-1;;;;;6686:32:1;;;100927:60:0;;;6668:51:1;100945:17:0;;;;100927:50;;6641:18:1;;100927:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100919:88;;;;-1:-1:-1;;;100919:88:0;;32459:2:1;100919:88:0;;;32441:21:1;32498:2;32478:18;;;32471:30;-1:-1:-1;;;32517:18:1;;;32510:45;32572:18;;100919:88:0;32257:339:1;101019:173:0;101156:1;-1:-1:-1;;;;;101104:54:0;101112:7;101120:6;101112:15;;;;;;:::i;:::-;;;;;;;;;;;;;;:31;;;-1:-1:-1;;;;;101112:31:0;101104:54;;101096:90;;;;-1:-1:-1;;;101096:90:0;;32803:2:1;101096:90:0;;;32785:21:1;32842:2;32822:18;;;32815:30;32881:25;32861:18;;;32854:53;32924:18;;101096:90:0;32601:347:1;83822:232:0;83896:7;83958:16;83949:5;83921:24;83958:16;83949:5;83921:24;:::i;:::-;83920:34;;;;:::i;:::-;:54;83912:76;;;;-1:-1:-1;;;83912:76:0;;33550:2:1;83912:76:0;;;33532:21:1;33589:1;33569:18;;;33562:29;-1:-1:-1;;;33607:18:1;;;33600:39;33656:18;;83912:76:0;33348:332:1;83912:76:0;84022:17;;84043:5;;84003:36;;84022:17;;;;;84003:16;:36;:::i;:::-;84002:46;;;;:::i;73151:222::-;73306:58;;;-1:-1:-1;;;;;33877:32:1;;73306:58:0;;;33859:51:1;33926:18;;;;33919:34;;;73306:58:0;;;;;;;;;;33832:18:1;;;;73306:58:0;;;;;;;;-1:-1:-1;;;;;73306:58:0;-1:-1:-1;;;73306:58:0;;;73279:86;;73299:5;;73279:19;:86::i;67302:521::-;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;67421:26:::1;:24;:26::i;:::-;67458:25;:23;:25::i;:::-;67494:32;:30;:32::i;:::-;67537:42;:40;:42::i;:::-;67590:36;67613:4;67619:6;67590:22;:36::i;:::-;67637:32;:30;:32::i;:::-;67680:27;:25;:27::i;:::-;67718:32;:30;:32::i;:::-;67761:54;67802:4;67808:6;67761:40;:54::i;72173:191::-:0;72266:6;;;-1:-1:-1;;;;;72283:17:0;;;-1:-1:-1;;;;;;72283:17:0;;;;;;;72316:40;;72266:6;;;72283:17;72266:6;;72316:40;;72247:16;;72316:40;72236:128;72173:191;:::o;70567:134::-;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;70630:26:::1;:24;:26::i;:::-;70667;:24;:26::i;30634:136::-:0;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;30698:26:::1;:24;:26::i;:::-;30735:27;:25;:27::i;31775:118::-:0;31046:7;;;;31300:9;31292:38;;;;-1:-1:-1;;;31292:38:0;;34578:2:1;31292:38:0;;;34560:21:1;34617:2;34597:18;;;34590:30;-1:-1:-1;;;34636:18:1;;;34629:46;34692:18;;31292:38:0;34376:340:1;31292:38:0;31835:7:::1;:14:::0;;-1:-1:-1;;31835:14:0::1;31845:4;31835:14;::::0;;31865:20:::1;31872:12;15262:10:::0;;15182:98;59548:158;59622:7;59673:22;59677:3;59689:5;59673:3;:22::i;59077:117::-;59140:7;59167:19;59175:3;54561:18;;54478:109;92129:482;92223:16;:23;92206:13;;:40;92198:71;;;;-1:-1:-1;;;92198:71:0;;34923:2:1;92198:71:0;;;34905:21:1;34962:2;34942:18;;;34935:30;-1:-1:-1;;;34981:18:1;;;34974:48;35039:18;;92198:71:0;34721:342:1;92198:71:0;92281:9;92276:330;92300:6;:13;92296:1;:17;92276:330;;;92349:1;92337:6;92344:1;92337:9;;;;;;;;:::i;:::-;;;;;;;:13;92329:38;;;;-1:-1:-1;;;92329:38:0;;35402:2:1;92329:38:0;;;35384:21:1;35441:2;35421:18;;;35414:30;-1:-1:-1;;;35460:18:1;;;35453:42;35512:18;;92329:38:0;35200:336:1;92329:38:0;92384:7;92392:16;92409:1;92392:19;;;;;;;;:::i;:::-;;;;;;;;92384:28;;;;;;:::i;:::-;;;;;;;;;;;;;;:44;92376:84;;;;-1:-1:-1;;;92376:84:0;;36561:2:1;92376:84:0;;;36543:21:1;36600:2;36580:18;;;36573:30;-1:-1:-1;;;36619:18:1;;;36612:52;36681:18;;92376:84:0;36359:346:1;92376:84:0;92506:29;;;;;;;;92512:6;92519:1;92512:9;;;;;;;;:::i;:::-;;;;;;;92506:29;;;;92523:11;;92506:29;;;92469:7;92477:16;92494:1;92477:19;;;;;;;;:::i;:::-;;;;;;;;92469:28;;;;;;:::i;:::-;;;;;;;;;;;;;;;:66;;;;;;;;;;;;92567:9;;92549:49;;92567:9;;92574:1;;92567:9;;;;;;:::i;:::-;;;;;;;92578:16;92595:1;92578:19;;;;;;;;:::i;:::-;;;;;;;;92549:49;;;;;;;:::i;:::-;;;;;;;;92315:3;;;;:::i;:::-;;;;92276:330;;98837:1134;98891:4;98904:27;98934:58;98954:19;85143:11;:18;;85070:97;98954:19;98975:16;;;;98934:19;:58::i;:::-;98904:88;;98999:19;99043;99021;85143:11;:18;;85070:97;99021:19;:41;;;;:::i;:::-;98999:63;;99069:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99069:28:0;99111:9;99123:19;85143:11;:18;;85070:97;99123:19;99111:31;;99106:595;99148:11;99144:1;:15;99106:595;;;99188:11;99200:5;99204:1;99200;:5;:::i;:::-;99188:18;;;;;;;;:::i;:::-;;;;;;;;;;;99175:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;99175:31:0;;;-1:-1:-1;;99175:31:0;;;;;;-1:-1:-1;;;;;99175:31:0;;;;;;;;;;;99238:17;;99271:19;;;;99220:71;;-1:-1:-1;;;99220:71:0;;6686:32:1;;;99220:71:0;;;6668:51:1;99271:19:0;;-1:-1:-1;99238:17:0;;99220:50;;6641:18:1;;99220:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99215:479;;99304:11;:17;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;99304:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;-1:-1:-1;99304:17:0;;;;-1:-1:-1;;;;;;99304:17:0;;;;;99215:479;;;99364:10;;99341:20;;;;99364:10;;;;-1:-1:-1;99337:357:0;;;99387:11;:17;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;99387:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;-1:-1:-1;99387:17:0;;;;-1:-1:-1;;;;;;99387:17:0;;;;;99415:269;99442:5;99387:17;99442:1;:5;:::i;:::-;99460:19;;;;99492:17;;99543:29;;;;99522:70;;99492:17;99522:20;:70::i;:::-;99605:10;:29;;;99647:10;:26;;;99415:14;:269::i;:::-;99161:3;;;;:::i;:::-;;;;99106:595;;;;99709:25;99752:1;99737:11;:16;;:38;;99760:15;99774:1;99760:11;:15;:::i;:::-;99737:38;;;99756:1;99737:38;99709:66;;99786:19;85143:11;:18;;85070:97;99786:19;:24;;;;:81;;-1:-1:-1;99857:10:0;;99814:11;:30;;99857:10;;;;;99826:17;;99814:30;;;;;;:::i;:::-;;;;;;;;;;;:40;;;:53;99786:81;99782:166;;;99906:12;;99883:36;;-1:-1:-1;;;99906:12:0;;;;;8122:40:1;;99883:36:0;;8110:2:1;8095:18;99883:36:0;;;;;;;;99935:5;99928:12;;;;;;98837:1134;:::o;99782:166::-;99961:4;99954:11;;;;;;98837:1134;:::o;97661:1080::-;97715:4;97728:27;97758:58;97778:19;84970:11;:18;;84897:97;97758:58;97728:88;;97823:19;97867;97845;84970:11;:18;;84897:97;97845:19;:41;;;;:::i;:::-;97823:63;;97893:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97893:28:0;97933:9;97945:19;84970:11;:18;;84897:97;97945:19;97933:31;;97928:545;97970:11;97966:1;:15;97928:545;;;98010:11;98022:5;98026:1;98022;:5;:::i;:::-;98010:18;;;;;;;;:::i;:::-;;;;;;;;;;;97997:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;97997:31:0;;;-1:-1:-1;;97997:31:0;;;;;;-1:-1:-1;;;;;97997:31:0;;;;;;;;;;;98068:17;;98101:19;;;;98050:71;;-1:-1:-1;;;98050:71:0;;6686:32:1;;;98050:71:0;;;6668:51:1;98101:19:0;;-1:-1:-1;98068:17:0;;98050:50;;6641:18:1;;98050:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98045:421;;98134:11;:17;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;98134:17:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;98134:17:0;;;;-1:-1:-1;;;;;;98134:17:0;;;;;98045:421;;;98194:10;;98171:20;;;;98194:10;;;;-1:-1:-1;98167:299:0;;;98217:11;:17;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;98217:17:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;98217:17:0;;;;-1:-1:-1;;;;;;98217:17:0;;;;;98245:211;98272:5;98217:17;98272:1;:5;:::i;:::-;98290:10;:19;;;98322:63;98348:10;:17;;;98367:10;:17;;;98322:25;:63::i;:::-;98398:17;;98428;;;;98245:14;:211::i;:::-;97983:3;;;;:::i;:::-;;;;97928:545;;;;98479:25;98522:1;98507:11;:16;;:38;;98530:15;98544:1;98530:11;:15;:::i;:::-;98507:38;;;98526:1;98507:38;98479:66;;98556:19;84970:11;:18;;84897:97;98556:19;:24;;;;:81;;-1:-1:-1;98627:10:0;;98584:11;:30;;98627:10;;;;;98596:17;;98584:30;;;;;;:::i;:::-;;;;;;;;;;;:40;;;:53;98556:81;98552:166;;;98676:12;;98653:36;;-1:-1:-1;;;98676:12:0;;;;;8122:40:1;;98653:36:0;;8110:2:1;8095:18;98653:36:0;7978:190:1;97170:208:0;97298:20;97314:3;97298:15;:20::i;:::-;97325:47;97352:5;97359:3;97364:7;97325:26;:47::i;39639:451::-;39714:13;39740:19;39772:10;39776:6;39772:1;:10;:::i;:::-;:14;;39785:1;39772:14;:::i;:::-;-1:-1:-1;;;;;39762:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39762:25:0;;39740:47;;-1:-1:-1;;;39798:6:0;39805:1;39798:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;39798:15:0;;;;;;;;;-1:-1:-1;;;39824:6:0;39831:1;39824:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;39824:15:0;;;;;;;;-1:-1:-1;39855:9:0;39867:10;39871:6;39867:1;:10;:::i;:::-;:14;;39880:1;39867:14;:::i;:::-;39855:26;;39850:135;39887:1;39883;:5;39850:135;;;-1:-1:-1;;;39935:5:0;39943:3;39935:11;39922:25;;;;;;;:::i;:::-;;;;39910:6;39917:1;39910:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;39910:37:0;;;;;;;;-1:-1:-1;39972:1:0;39962:11;;;;;39890:3;;;:::i;:::-;;;39850:135;;;-1:-1:-1;40003:10:0;;39995:55;;;;-1:-1:-1;;;39995:55:0;;38328:2:1;39995:55:0;;;38310:21:1;;;38347:18;;;38340:30;38406:34;38386:18;;;38379:62;38458:18;;39995:55:0;38126:356:1;49690:238:0;49774:22;49782:4;49788:7;49774;:22::i;:::-;49769:152;;49813:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;49813:29:0;;;;;;;;;:36;;-1:-1:-1;;49813:36:0;49845:4;49813:36;;;49896:12;15262:10;;15182:98;49896:12;-1:-1:-1;;;;;49869:40:0;49887:7;-1:-1:-1;;;;;49869:40:0;49881:4;49869:40;;;;;;;;;;49690:238;;:::o;58252:152::-;58322:4;58346:50;58351:3;-1:-1:-1;;;;;58371:23:0;;58346:4;:50::i;50060:239::-;50144:22;50152:4;50158:7;50144;:22::i;:::-;50140:152;;;50215:5;50183:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;50183:29:0;;;;;;;;;;:37;;-1:-1:-1;;50183:37:0;;;50240:40;15262:10;;50183:12;;50240:40;;50215:5;50240:40;50060:239;;:::o;58580:158::-;58653:4;58677:53;58685:3;-1:-1:-1;;;;;58705:23:0;;58677:7;:53::i;75779:727::-;76214:23;76240:69;76268:4;76240:69;;;;;;;;;;;;;;;;;76248:5;-1:-1:-1;;;;;76240:27:0;;;:69;;;;;:::i;:::-;76324:17;;76214:95;;-1:-1:-1;76324:21:0;76320:179;;76421:10;76410:30;;;;;;;;;;;;:::i;:::-;76402:85;;;;-1:-1:-1;;;76402:85:0;;38689:2:1;76402:85:0;;;38671:21:1;38728:2;38708:18;;;38701:30;38767:34;38747:18;;;38740:62;-1:-1:-1;;;38818:18:1;;;38811:40;38868:19;;76402:85:0;38487:406:1;15106:70:0;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;17657:162::-;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;17770:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;17794:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;30778:97::-:0;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;30852:7:::1;:15:::0;;-1:-1:-1;;30852:15:0::1;::::0;;30778:97::o;67831:279::-;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;67960:44:::1;44744:4;15262:10:::0;67960::::1;:44::i;:::-;68017:37;67017:24;15262:10:::0;67960::::1;:44::i;68017:37::-;68065;-1:-1:-1::0;;;;;;;;;;;15262:10:0;67960::::1;:44::i;70709:113::-:0;14042:13;;;;;;;14034:69;;;;-1:-1:-1;;;14034:69:0;;;;;;;:::i;:::-;70782:32:::1;15262:10:::0;70782:18:::1;:32::i;54941:120::-:0;55008:7;55035:3;:11;;55047:5;55035:18;;;;;;;;:::i;:::-;;;;;;;;;55028:25;;54941:120;;;;:::o;77045:106::-;77103:7;77134:1;77130;:5;:13;;77142:1;77130:13;;;-1:-1:-1;77138:1:0;;77045:106;-1:-1:-1;77045:106:0:o;95960:343::-;96085:7;96104:20;96127:7;96135:16;96127:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;96104:48;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;96104:48:0;;;;;;;;;-1:-1:-1;;;96104:48:0;;;;;;;;;96127:25;-1:-1:-1;;96190:7:0;96198:8;:6;:8::i;:::-;96190:17;;;;;;:::i;:::-;;;;;;;;;;;;;;;;96159:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;96159:48:0;;;;;;;;;-1:-1:-1;;;96159:48:0;;;;;;;;;;;;96241:12;;:22;96190:17;;-1:-1:-1;96222:41:0;;:16;:41;:::i;:::-;96221:76;;;;:::i;:::-;96214:83;95960:343;-1:-1:-1;;;;;95960:343:0:o;96584:580::-;96684:7;96700:30;96733:7;96741:6;96733:15;;;;;;:::i;:::-;;;;;;;;;;;;;;;;96700:48;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;96700:48:0;;;;;;;;;-1:-1:-1;;;96700:48:0;;;;;;;;;96733:15;-1:-1:-1;;96785:7:0;96793:8;:6;:8::i;:::-;96785:17;;;;;;:::i;:::-;;;;;;;;;;;;;;;;96755:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;96755:47:0;;;;;;;;;-1:-1:-1;;;96755:47:0;;;;;;;;;;;;96875:22;;:32;96785:17;;-1:-1:-1;;;96828:43:0;;:11;:43;:::i;:::-;96827:80;;;;:::i;:::-;96809:99;;96947:13;:22;;;96919:50;;:16;:25;;;:50;;;96915:244;;;97030:13;:22;;;97002:16;:25;;;:50;;;;:::i;:::-;96997:56;;:2;:56;:::i;:::-;96987:67;;:6;:67;:::i;:::-;96980:74;;;;;;;96915:244;97124:16;:25;;;97099:13;:22;;;:50;;;;:::i;:::-;97094:56;;:2;:56;:::i;:::-;97084:67;;:6;:67;:::i;69305:239::-;69492:44;69519:4;69525:2;69529:6;69492:26;:44::i;52167:414::-;52230:4;54360:19;;;:12;;;:19;;;;;;52247:327;;-1:-1:-1;52290:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;52473:18;;52451:19;;;:12;;;:19;;;;;;:40;;;;52506:11;;52247:327;-1:-1:-1;52557:5:0;52550:12;;52757:1420;52823:4;52962:19;;;:12;;;:19;;;;;;52998:15;;52994:1176;;53373:21;53397:14;53410:1;53397:10;:14;:::i;:::-;53446:18;;53373:38;;-1:-1:-1;53426:17:0;;53446:22;;53467:1;;53446:22;:::i;:::-;53426:42;;53502:13;53489:9;:26;53485:405;;53536:17;53556:3;:11;;53568:9;53556:22;;;;;;;;:::i;:::-;;;;;;;;;53536:42;;53710:9;53681:3;:11;;53693:13;53681:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;53795:23;;;:12;;;:23;;;;;:36;;;53485:405;53971:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54066:3;:12;;:19;54079:5;54066:19;;;;;;;;;;;54059:26;;;54109:4;54102:11;;;;;;;52994:1176;54153:5;54146:12;;;;;7485:229;7622:12;7654:52;7676:6;7684:4;7690:1;7693:12;7654:21;:52::i;:::-;7647:59;7485:229;-1:-1:-1;;;;7485:229:0:o;49066:112::-;49145:25;49156:4;49162:7;49145:10;:25::i;33216:272::-;31046:7;;;;33424:9;33416:64;;;;-1:-1:-1;;;33416:64:0;;40683:2:1;33416:64:0;;;40665:21:1;40722:2;40702:18;;;40695:30;40761:34;40741:18;;;40734:62;-1:-1:-1;;;40812:18:1;;;40805:40;40862:19;;33416:64:0;40481:406:1;8605:510:0;8775:12;8833:5;8808:21;:30;;8800:81;;;;-1:-1:-1;;;8800:81:0;;41094:2:1;8800:81:0;;;41076:21:1;41133:2;41113:18;;;41106:30;41172:34;41152:18;;;41145:62;-1:-1:-1;;;41223:18:1;;;41216:36;41269:19;;8800:81:0;40892:402:1;8800:81:0;5002:20;;8892:60;;;;-1:-1:-1;;;8892:60:0;;41501:2:1;8892:60:0;;;41483:21:1;41540:2;41520:18;;;41513:30;41579:31;41559:18;;;41552:59;41628:18;;8892:60:0;41299:353:1;8892:60:0;8966:12;8980:23;9007:6;-1:-1:-1;;;;;9007:11:0;9026:5;9033:4;9007:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8965:73;;;;9056:51;9073:7;9082:10;9094:12;9056:16;:51::i;:::-;9049:58;8605:510;-1:-1:-1;;;;;;;8605:510:0:o;10314:712::-;10464:12;10493:7;10489:530;;;-1:-1:-1;10524:10:0;10517:17;;10489:530;10638:17;;:21;10634:374;;10836:10;10830:17;10897:15;10884:10;10880:2;10876:19;10869:44;10634:374;10979:12;10972:20;;-1:-1:-1;;;10972:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;14:286:1;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:127;558:10;553:3;549:20;546:1;539:31;589:4;586:1;579:15;613:4;610:1;603:15;629:719;672:5;725:3;718:4;710:6;706:17;702:27;692:55;;743:1;740;733:12;692:55;779:6;766:20;-1:-1:-1;;;;;842:2:1;838;835:10;832:36;;;848:18;;:::i;:::-;923:2;917:9;891:2;977:13;;-1:-1:-1;;973:22:1;;;997:2;969:31;965:40;953:53;;;1021:18;;;1041:22;;;1018:46;1015:72;;;1067:18;;:::i;:::-;1107:10;1103:2;1096:22;1142:2;1134:6;1127:18;1188:3;1181:4;1176:2;1168:6;1164:15;1160:26;1157:35;1154:55;;;1205:1;1202;1195:12;1154:55;1269:2;1262:4;1254:6;1250:17;1243:4;1235:6;1231:17;1218:54;1316:1;1309:4;1304:2;1296:6;1292:15;1288:26;1281:37;1336:6;1327:15;;;;;;629:719;;;;:::o;1353:131::-;-1:-1:-1;;;;;1428:31:1;;1418:42;;1408:70;;1474:1;1471;1464:12;1489:885;1613:6;1621;1629;1637;1645;1653;1706:3;1694:9;1685:7;1681:23;1677:33;1674:53;;;1723:1;1720;1713:12;1674:53;1759:9;1746:23;1736:33;;1820:2;1809:9;1805:18;1792:32;-1:-1:-1;;;;;1884:2:1;1876:6;1873:14;1870:34;;;1900:1;1897;1890:12;1870:34;1923:50;1965:7;1956:6;1945:9;1941:22;1923:50;:::i;:::-;1913:60;;2026:2;2015:9;2011:18;1998:32;1982:48;;2055:2;2045:8;2042:16;2039:36;;;2071:1;2068;2061:12;2039:36;;2094:52;2138:7;2127:8;2116:9;2112:24;2094:52;:::i;:::-;2084:62;;;2196:2;2185:9;2181:18;2168:32;2209:31;2234:5;2209:31;:::i;:::-;1489:885;;;;-1:-1:-1;1489:885:1;;2311:3;2296:19;;2283:33;;2363:3;2348:19;;;2335:33;;-1:-1:-1;1489:885:1;-1:-1:-1;;1489:885:1:o;2379:258::-;2451:1;2461:113;2475:6;2472:1;2469:13;2461:113;;;2551:11;;;2545:18;2532:11;;;2525:39;2497:2;2490:10;2461:113;;;2592:6;2589:1;2586:13;2583:48;;;-1:-1:-1;;2627:1:1;2609:16;;2602:27;2379:258::o;2642:::-;2684:3;2722:5;2716:12;2749:6;2744:3;2737:19;2765:63;2821:6;2814:4;2809:3;2805:14;2798:4;2791:5;2787:16;2765:63;:::i;:::-;2882:2;2861:15;-1:-1:-1;;2857:29:1;2848:39;;;;2889:4;2844:50;;2642:258;-1:-1:-1;;2642:258:1:o;2905:220::-;3054:2;3043:9;3036:21;3017:4;3074:45;3115:2;3104:9;3100:18;3092:6;3074:45;:::i;3130:315::-;3198:6;3206;3259:2;3247:9;3238:7;3234:23;3230:32;3227:52;;;3275:1;3272;3265:12;3227:52;3314:9;3301:23;3333:31;3358:5;3333:31;:::i;:::-;3383:5;3435:2;3420:18;;;;3407:32;;-1:-1:-1;;;3130:315:1:o;3632:322::-;3701:6;3754:2;3742:9;3733:7;3729:23;3725:32;3722:52;;;3770:1;3767;3760:12;3722:52;3810:9;3797:23;-1:-1:-1;;;;;3835:6:1;3832:30;3829:50;;;3875:1;3872;3865:12;3829:50;3898;3940:7;3931:6;3920:9;3916:22;3898:50;:::i;4433:456::-;4510:6;4518;4526;4579:2;4567:9;4558:7;4554:23;4550:32;4547:52;;;4595:1;4592;4585:12;4547:52;4634:9;4621:23;4653:31;4678:5;4653:31;:::i;:::-;4703:5;-1:-1:-1;4760:2:1;4745:18;;4732:32;4773:33;4732:32;4773:33;:::i;:::-;4433:456;;4825:7;;-1:-1:-1;;;4879:2:1;4864:18;;;;4851:32;;4433:456::o;4894:180::-;4953:6;5006:2;4994:9;4985:7;4981:23;4977:32;4974:52;;;5022:1;5019;5012:12;4974:52;-1:-1:-1;5045:23:1;;4894:180;-1:-1:-1;4894:180:1:o;5261:315::-;5329:6;5337;5390:2;5378:9;5369:7;5365:23;5361:32;5358:52;;;5406:1;5403;5396:12;5358:52;5442:9;5429:23;5419:33;;5502:2;5491:9;5487:18;5474:32;5515:31;5540:5;5515:31;:::i;:::-;5565:5;5555:15;;;5261:315;;;;;:::o;5770:747::-;5876:6;5884;5892;5900;5953:3;5941:9;5932:7;5928:23;5924:33;5921:53;;;5970:1;5967;5960:12;5921:53;6009:9;5996:23;6028:31;6053:5;6028:31;:::i;:::-;6078:5;-1:-1:-1;6130:2:1;6115:18;;6102:32;;-1:-1:-1;6185:2:1;6170:18;;6157:32;-1:-1:-1;;;;;6238:14:1;;;6235:34;;;6265:1;6262;6255:12;6235:34;6288:50;6330:7;6321:6;6310:9;6306:22;6288:50;:::i;:::-;6278:60;;6391:2;6380:9;6376:18;6363:32;6347:48;;6420:2;6410:8;6407:16;6404:36;;;6436:1;6433;6426:12;6404:36;;6459:52;6503:7;6492:8;6481:9;6477:24;6459:52;:::i;:::-;6449:62;;;5770:747;;;;;;;:::o;6915:390::-;6993:6;7001;7054:2;7042:9;7033:7;7029:23;7025:32;7022:52;;;7070:1;7067;7060:12;7022:52;7106:9;7093:23;7083:33;;7167:2;7156:9;7152:18;7139:32;-1:-1:-1;;;;;7186:6:1;7183:30;7180:50;;;7226:1;7223;7216:12;7180:50;7249;7291:7;7282:6;7271:9;7267:22;7249:50;:::i;:::-;7239:60;;;6915:390;;;;;:::o;7310:663::-;7415:6;7423;7431;7439;7447;7500:3;7488:9;7479:7;7475:23;7471:33;7468:53;;;7517:1;7514;7507:12;7468:53;7553:9;7540:23;7530:33;;7613:2;7602:9;7598:18;7585:32;7626:31;7651:5;7626:31;:::i;:::-;7676:5;-1:-1:-1;7728:2:1;7713:18;;7700:32;;-1:-1:-1;7779:2:1;7764:18;;7751:32;;-1:-1:-1;7834:3:1;7819:19;;7806:33;-1:-1:-1;;;;;7851:30:1;;7848:50;;;7894:1;7891;7884:12;7848:50;7917;7959:7;7950:6;7939:9;7935:22;7917:50;:::i;:::-;7907:60;;;7310:663;;;;;;;;:::o;8173:543::-;8261:6;8269;8322:2;8310:9;8301:7;8297:23;8293:32;8290:52;;;8338:1;8335;8328:12;8290:52;8378:9;8365:23;-1:-1:-1;;;;;8448:2:1;8440:6;8437:14;8434:34;;;8464:1;8461;8454:12;8434:34;8487:50;8529:7;8520:6;8509:9;8505:22;8487:50;:::i;:::-;8477:60;;8590:2;8579:9;8575:18;8562:32;8546:48;;8619:2;8609:8;8606:16;8603:36;;;8635:1;8632;8625:12;8603:36;;8658:52;8702:7;8691:8;8680:9;8676:24;8658:52;:::i;8918:163::-;8985:20;;9045:10;9034:22;;9024:33;;9014:61;;9071:1;9068;9061:12;9014:61;8918:163;;;:::o;9086:184::-;9144:6;9197:2;9185:9;9176:7;9172:23;9168:32;9165:52;;;9213:1;9210;9203:12;9165:52;9236:28;9254:9;9236:28;:::i;9275:274::-;9333:6;9386:2;9374:9;9365:7;9361:23;9357:32;9354:52;;;9402:1;9399;9392:12;9354:52;9441:9;9428:23;9491:8;9484:5;9480:20;9473:5;9470:31;9460:59;;9515:1;9512;9505:12;9554:247;9613:6;9666:2;9654:9;9645:7;9641:23;9637:32;9634:52;;;9682:1;9679;9672:12;9634:52;9721:9;9708:23;9740:31;9765:5;9740:31;:::i;9806:893::-;9920:6;9928;9936;9944;9952;10005:3;9993:9;9984:7;9980:23;9976:33;9973:53;;;10022:1;10019;10012:12;9973:53;10062:9;10049:23;-1:-1:-1;;;;;10132:2:1;10124:6;10121:14;10118:34;;;10148:1;10145;10138:12;10118:34;10171:50;10213:7;10204:6;10193:9;10189:22;10171:50;:::i;:::-;10161:60;;10274:2;10263:9;10259:18;10246:32;10230:48;;10303:2;10293:8;10290:16;10287:36;;;10319:1;10316;10309:12;10287:36;;10342:52;10386:7;10375:8;10364:9;10360:24;10342:52;:::i;:::-;10332:62;;;10444:2;10433:9;10429:18;10416:32;10457:31;10482:5;10457:31;:::i;:::-;10507:5;-1:-1:-1;10564:2:1;10549:18;;10536:32;10577:33;10536:32;10577:33;:::i;:::-;10629:7;-1:-1:-1;10655:38:1;10688:3;10673:19;;10655:38;:::i;:::-;10645:48;;9806:893;;;;;;;;:::o;10704:390::-;10782:6;10790;10843:2;10831:9;10822:7;10818:23;10814:32;10811:52;;;10859:1;10856;10849:12;10811:52;10899:9;10886:23;-1:-1:-1;;;;;10924:6:1;10921:30;10918:50;;;10964:1;10961;10954:12;10918:50;10987;11029:7;11020:6;11009:9;11005:22;10987:50;:::i;:::-;10977:60;11084:2;11069:18;;;;11056:32;;-1:-1:-1;;;;10704:390:1:o;11099:248::-;11167:6;11175;11228:2;11216:9;11207:7;11203:23;11199:32;11196:52;;;11244:1;11241;11234:12;11196:52;-1:-1:-1;;11267:23:1;;;11337:2;11322:18;;;11309:32;;-1:-1:-1;11099:248:1:o;11352:885::-;11476:6;11484;11492;11500;11508;11516;11569:3;11557:9;11548:7;11544:23;11540:33;11537:53;;;11586:1;11583;11576:12;11537:53;11622:9;11609:23;11599:33;;11682:2;11671:9;11667:18;11654:32;11695:31;11720:5;11695:31;:::i;:::-;11745:5;-1:-1:-1;11797:2:1;11782:18;;11769:32;;-1:-1:-1;11848:2:1;11833:18;;11820:32;;-1:-1:-1;11903:3:1;11888:19;;11875:33;-1:-1:-1;;;;;11957:14:1;;;11954:34;;;11984:1;11981;11974:12;11954:34;12007:50;12049:7;12040:6;12029:9;12025:22;12007:50;:::i;:::-;11997:60;;12110:3;12099:9;12095:19;12082:33;12066:49;;12140:2;12130:8;12127:16;12124:36;;;12156:1;12153;12146:12;12124:36;;12179:52;12223:7;12212:8;12201:9;12197:24;12179:52;:::i;:::-;12169:62;;;11352:885;;;;;;;;:::o;12242:461::-;12475:6;12464:9;12457:25;12518:6;12513:2;12502:9;12498:18;12491:34;12561:3;12556:2;12545:9;12541:18;12534:31;12438:4;12582:46;12623:3;12612:9;12608:19;12600:6;12582:46;:::i;:::-;12574:54;;12693:1;12689;12684:3;12680:11;12676:19;12668:6;12664:32;12659:2;12648:9;12644:18;12637:60;12242:461;;;;;;;:::o;12708:615::-;12794:6;12802;12855:2;12843:9;12834:7;12830:23;12826:32;12823:52;;;12871:1;12868;12861:12;12823:52;12911:9;12898:23;-1:-1:-1;;;;;12981:2:1;12973:6;12970:14;12967:34;;;12997:1;12994;12987:12;12967:34;13035:6;13024:9;13020:22;13010:32;;13080:7;13073:4;13069:2;13065:13;13061:27;13051:55;;13102:1;13099;13092:12;13051:55;13142:2;13129:16;13168:2;13160:6;13157:14;13154:34;;;13184:1;13181;13174:12;13154:34;13237:7;13232:2;13222:6;13219:1;13215:14;13211:2;13207:23;13203:32;13200:45;13197:65;;;13258:1;13255;13248:12;13197:65;13289:2;13281:11;;;;;13311:6;;-1:-1:-1;12708:615:1;;-1:-1:-1;;;;12708:615:1:o;13328:388::-;13396:6;13404;13457:2;13445:9;13436:7;13432:23;13428:32;13425:52;;;13473:1;13470;13463:12;13425:52;13512:9;13499:23;13531:31;13556:5;13531:31;:::i;:::-;13581:5;-1:-1:-1;13638:2:1;13623:18;;13610:32;13651:33;13610:32;13651:33;:::i;13998:691::-;14092:6;14100;14108;14116;14169:3;14157:9;14148:7;14144:23;14140:33;14137:53;;;14186:1;14183;14176:12;14137:53;14226:9;14213:23;-1:-1:-1;;;;;14251:6:1;14248:30;14245:50;;;14291:1;14288;14281:12;14245:50;14314;14356:7;14347:6;14336:9;14332:22;14314:50;:::i;:::-;14304:60;;;14414:2;14403:9;14399:18;14386:32;14427:31;14452:5;14427:31;:::i;:::-;14477:5;-1:-1:-1;14529:2:1;14514:18;;14501:32;;-1:-1:-1;14585:2:1;14570:18;;14557:32;14633:4;14620:18;;14608:31;;14598:59;;14653:1;14650;14643:12;14598:59;13998:691;;;;-1:-1:-1;13998:691:1;;-1:-1:-1;;13998:691:1:o;14694:769::-;15031:6;15020:9;15013:25;15074:6;15069:2;15058:9;15054:18;15047:34;15117:6;15112:2;15101:9;15097:18;15090:34;15160:6;15155:2;15144:9;15140:18;15133:34;15204:3;15198;15187:9;15183:19;15176:32;14994:4;15231:46;15272:3;15261:9;15257:19;15249:6;15231:46;:::i;:::-;15326:9;15318:6;15314:22;15308:3;15297:9;15293:19;15286:51;15354:33;15380:6;15372;15354:33;:::i;:::-;15346:41;;;15453:1;15449;15444:3;15440:11;15436:19;15428:6;15424:32;15418:3;15407:9;15403:19;15396:61;14694:769;;;;;;;;;;:::o;15468:276::-;15599:3;15637:6;15631:13;15653:53;15699:6;15694:3;15687:4;15679:6;15675:17;15653:53;:::i;:::-;15722:16;;;;;15468:276;-1:-1:-1;;15468:276:1:o;16780:769::-;17117:6;17106:9;17099:25;17160:6;17155:2;17144:9;17140:18;17133:34;17203:3;17198:2;17187:9;17183:18;17176:31;17080:4;17230:46;17271:3;17260:9;17256:19;17248:6;17230:46;:::i;:::-;17324:9;17316:6;17312:22;17307:2;17296:9;17292:18;17285:50;17352:33;17378:6;17370;17352:33;:::i;:::-;-1:-1:-1;;;;;17422:32:1;;;;17416:3;17401:19;;17394:61;-1:-1:-1;;17442:3:1;17471:19;;17464:35;;;;17530:3;17515:19;;;17508:35;17344:41;16780:769;-1:-1:-1;;;;16780:769:1:o;17554:380::-;17633:1;17629:12;;;;17676;;;17697:61;;17751:4;17743:6;17739:17;17729:27;;17697:61;17804:2;17796:6;17793:14;17773:18;17770:38;17767:161;;;17850:10;17845:3;17841:20;17838:1;17831:31;17885:4;17882:1;17875:15;17913:4;17910:1;17903:15;17767:161;;17554:380;;;:::o;18355:356::-;18557:2;18539:21;;;18576:18;;;18569:30;18635:34;18630:2;18615:18;;18608:62;18702:2;18687:18;;18355:356::o;18716:553::-;18998:1;18994;18989:3;18985:11;18981:19;18973:6;18969:32;18958:9;18951:51;19038:6;19033:2;19022:9;19018:18;19011:34;19081:3;19076:2;19065:9;19061:18;19054:31;18932:4;19108:46;19149:3;19138:9;19134:19;19126:6;19108:46;:::i;:::-;19202:9;19194:6;19190:22;19185:2;19174:9;19170:18;19163:50;19230:33;19256:6;19248;19230:33;:::i;19274:127::-;19335:10;19330:3;19326:20;19323:1;19316:31;19366:4;19363:1;19356:15;19390:4;19387:1;19380:15;19406:128;19446:3;19477:1;19473:6;19470:1;19467:13;19464:39;;;19483:18;;:::i;:::-;-1:-1:-1;19519:9:1;;19406:128::o;21074:184::-;21144:6;21197:2;21185:9;21176:7;21172:23;21168:32;21165:52;;;21213:1;21210;21203:12;21165:52;-1:-1:-1;21236:16:1;;21074:184;-1:-1:-1;21074:184:1:o;21263:125::-;21303:4;21331:1;21328;21325:8;21322:34;;;21336:18;;:::i;:::-;-1:-1:-1;21373:9:1;;21263:125::o;21393:619::-;21681:6;21670:9;21663:25;21724:6;21719:2;21708:9;21704:18;21697:34;21767:6;21762:2;21751:9;21747:18;21740:34;21810:3;21805:2;21794:9;21790:18;21783:31;21644:4;21831:46;21872:3;21861:9;21857:19;21849:6;21831:46;:::i;:::-;-1:-1:-1;;;;;21914:32:1;;;;21908:3;21893:19;;21886:61;-1:-1:-1;21996:8:1;21984:21;;;;21934:3;21963:19;;;21956:50;21914:32;21823:54;-1:-1:-1;;;;21393:619:1:o;22017:410::-;22219:2;22201:21;;;22258:2;22238:18;;;22231:30;22297:34;22292:2;22277:18;;22270:62;-1:-1:-1;;;22363:2:1;22348:18;;22341:44;22417:3;22402:19;;22017:410::o;24591:783::-;24927:6;24916:9;24909:25;24970:6;24965:2;24954:9;24950:18;24943:34;25013:6;25008:2;24997:9;24993:18;24986:34;25056:3;25051:2;25040:9;25036:18;25029:31;24890:4;25083:46;25124:3;25113:9;25109:19;25101:6;25083:46;:::i;:::-;25178:9;25170:6;25166:22;25160:3;25149:9;25145:19;25138:51;25206:33;25232:6;25224;25206:33;:::i;:::-;-1:-1:-1;;;;;25276:32:1;;;;25296:3;25255:19;;25248:61;-1:-1:-1;;25358:8:1;25346:21;;;;25340:3;25325:19;;;25318:50;25198:41;24591:783;-1:-1:-1;;;;;24591:783:1:o;26465:226::-;26504:3;26532:8;26567:2;26564:1;26560:10;26597:2;26594:1;26590:10;26628:3;26624:2;26620:12;26615:3;26612:21;26609:47;;;26636:18;;:::i;:::-;26672:13;;26465:226;-1:-1:-1;;;;26465:226:1:o;29670:786::-;30081:25;30076:3;30069:38;30051:3;30136:6;30130:13;30152:62;30207:6;30202:2;30197:3;30193:12;30186:4;30178:6;30174:17;30152:62;:::i;:::-;-1:-1:-1;;;30273:2:1;30233:16;;;30265:11;;;30258:40;30323:13;;30345:63;30323:13;30394:2;30386:11;;30379:4;30367:17;;30345:63;:::i;:::-;30428:17;30447:2;30424:26;;29670:786;-1:-1:-1;;;;29670:786:1:o;31975:277::-;32042:6;32095:2;32083:9;32074:7;32070:23;32066:32;32063:52;;;32111:1;32108;32101:12;32063:52;32143:9;32137:16;32196:5;32189:13;32182:21;32175:5;32172:32;32162:60;;32218:1;32215;32208:12;32953:168;32993:7;33059:1;33055;33051:6;33047:14;33044:1;33041:21;33036:1;33029:9;33022:17;33018:45;33015:71;;;33066:18;;:::i;:::-;-1:-1:-1;33106:9:1;;32953:168::o;33126:217::-;33166:1;33192;33182:132;;33236:10;33231:3;33227:20;33224:1;33217:31;33271:4;33268:1;33261:15;33299:4;33296:1;33289:15;33182:132;-1:-1:-1;33328:9:1;;33126:217::o;33964:407::-;34166:2;34148:21;;;34205:2;34185:18;;;34178:30;34244:34;34239:2;34224:18;;34217:62;-1:-1:-1;;;34310:2:1;34295:18;;34288:41;34361:3;34346:19;;33964:407::o;35068:127::-;35129:10;35124:3;35120:20;35117:1;35110:31;35160:4;35157:1;35150:15;35184:4;35181:1;35174:15;35541:813;35669:3;35698:1;35731:6;35725:13;35761:36;35787:9;35761:36;:::i;:::-;35816:1;35833:18;;;35860:104;;;;35978:1;35973:356;;;;35826:503;;35860:104;-1:-1:-1;;35893:24:1;;35881:37;;35938:16;;;;-1:-1:-1;35860:104:1;;35973:356;36004:6;36001:1;35994:17;36034:4;36079:2;36076:1;36066:16;36104:1;36118:165;36132:6;36129:1;36126:13;36118:165;;;36210:14;;36197:11;;;36190:35;36253:16;;;;36147:10;;36118:165;;;36122:3;;;36312:6;36307:3;36303:16;36296:23;;35826:503;-1:-1:-1;36345:3:1;;35541:813;-1:-1:-1;;;;;;35541:813:1:o;36710:998::-;36884:6;36873:9;36866:25;36847:4;36910:2;36948;36943;36932:9;36928:18;36921:30;36971:1;37004:6;36998:13;37034:36;37060:9;37034:36;:::i;:::-;37106:6;37101:2;37090:9;37086:18;37079:34;37132:2;37153:1;37185:2;37174:9;37170:18;37202:1;37197:122;;;;37333:1;37328:354;;;;37163:519;;37197:122;-1:-1:-1;;37245:24:1;;37225:18;;;37218:52;37305:3;37290:19;;;-1:-1:-1;37197:122:1;;37328:354;37359:6;37356:1;37349:17;37407:2;37404:1;37394:16;37432:1;37446:180;37460:6;37457:1;37454:13;37446:180;;;37553:14;;37529:17;;;37525:26;;37518:50;37596:16;;;;37475:10;;37446:180;;;37650:17;;37646:26;;;-1:-1:-1;;37163:519:1;-1:-1:-1;37699:3:1;;36710:998;-1:-1:-1;;;;;;;;;36710:998:1:o;37713:135::-;37752:3;-1:-1:-1;;37773:17:1;;37770:43;;;37793:18;;:::i;:::-;-1:-1:-1;37840:1:1;37829:13;;37713:135::o;37853:127::-;37914:10;37909:3;37905:20;37902:1;37895:31;37945:4;37942:1;37935:15;37969:4;37966:1;37959:15;37985:136;38024:3;38052:5;38042:39;;38061:18;;:::i;:::-;-1:-1:-1;;;38097:18:1;;37985:136::o;38898:195::-;38936:4;38973;38970:1;38966:12;39005:4;39002:1;38998:12;39030:3;39025;39022:12;39019:38;;;39037:18;;:::i;:::-;39074:13;;;38898:195;-1:-1:-1;;;38898:195:1:o;39098:422::-;39187:1;39230:5;39187:1;39244:270;39265:7;39255:8;39252:21;39244:270;;;39324:4;39320:1;39316:6;39312:17;39306:4;39303:27;39300:53;;;39333:18;;:::i;:::-;39383:7;39373:8;39369:22;39366:55;;;39403:16;;;;39366:55;39482:22;;;;39442:15;;;;39244:270;;;39248:3;39098:422;;;;;:::o;39525:806::-;39574:5;39604:8;39594:80;;-1:-1:-1;39645:1:1;39659:5;;39594:80;39693:4;39683:76;;-1:-1:-1;39730:1:1;39744:5;;39683:76;39775:4;39793:1;39788:59;;;;39861:1;39856:130;;;;39768:218;;39788:59;39818:1;39809:10;;39832:5;;;39856:130;39893:3;39883:8;39880:17;39877:43;;;39900:18;;:::i;:::-;-1:-1:-1;;39956:1:1;39942:16;;39971:5;;39768:218;;40070:2;40060:8;40057:16;40051:3;40045:4;40042:13;40038:36;40032:2;40022:8;40019:16;40014:2;40008:4;40005:12;40001:35;39998:77;39995:159;;;-1:-1:-1;40107:19:1;;;40139:5;;39995:159;40186:34;40211:8;40205:4;40186:34;:::i;:::-;40256:6;40252:1;40248:6;40244:19;40235:7;40232:32;40229:58;;;40267:18;;:::i;:::-;40305:20;;39525:806;-1:-1:-1;;;39525:806:1:o;40336:140::-;40394:5;40423:47;40464:4;40454:8;40450:19;40444:4;40423:47;:::i

Swarm Source

ipfs://dbd4e0d77a7971b63e4360f908e246ae44743bbe347e9f9b7d61d15d46fcda3e
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading