ETH Price: $2,953.52 (-0.38%)
 

More Info

Private Name Tags

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Swap With Permit287204442026-01-24 16:30:4820 mins ago1769272248IN
SyncSwap: Router V3
0 ETH0.000001720.004999
Swap With Permit287188732026-01-24 15:58:4852 mins ago1769270328IN
SyncSwap: Router V3
0 ETH0.000001730.004999
Swap287184062026-01-24 15:48:141 hr ago1769269694IN
SyncSwap: Router V3
0 ETH0.000000250.00013812
Burn Liquidity W...287180722026-01-24 15:40:321 hr ago1769269232IN
SyncSwap: Router V3
0 ETH0.000001520.004999
Swap With Permit287178532026-01-24 15:35:201 hr ago1769268920IN
SyncSwap: Router V3
0 ETH0.000000220.0001201
Swap With Permit287145812026-01-24 14:18:412 hrs ago1769264321IN
SyncSwap: Router V3
0 ETH0.000000090.0001201
Burn Liquidity S...287127742026-01-24 13:40:473 hrs ago1769262047IN
SyncSwap: Router V3
0 ETH0.000000030.0001201
Burn Liquidity W...287126722026-01-24 13:39:013 hrs ago1769261941IN
SyncSwap: Router V3
0 ETH0.000000060.0001201
Swap287125802026-01-24 13:37:193 hrs ago1769261839IN
SyncSwap: Router V3
0 ETH0.000001310.00505
Swap287125472026-01-24 13:36:333 hrs ago1769261793IN
SyncSwap: Router V3
0 ETH0.000001310.00505
Swap287125202026-01-24 13:35:573 hrs ago1769261757IN
SyncSwap: Router V3
0 ETH0.000001330.00505
Swap With Permit287109912026-01-24 13:03:143 hrs ago1769259794IN
SyncSwap: Router V3
0 ETH0.000000080.0001201
Swap287101512026-01-24 12:42:134 hrs ago1769258533IN
SyncSwap: Router V3
0 ETH0.000000040.0001201
Burn Liquidity W...287080462026-01-24 11:55:574 hrs ago1769255757IN
SyncSwap: Router V3
0 ETH0.000000060.0001201
Swap287073752026-01-24 11:40:135 hrs ago1769254813IN
SyncSwap: Router V3
0 ETH0.000001310.00505
Swap287072642026-01-24 11:37:465 hrs ago1769254666IN
SyncSwap: Router V3
0 ETH0.000001330.00505
Swap287072312026-01-24 11:37:125 hrs ago1769254632IN
SyncSwap: Router V3
0 ETH0.00000130.00505
Swap With Permit287066982026-01-24 11:25:545 hrs ago1769253954IN
SyncSwap: Router V3
0 ETH0.000001630.00505
Swap287066842026-01-24 11:25:395 hrs ago1769253939IN
SyncSwap: Router V3
0 ETH0.000000860.00505
Swap287066712026-01-24 11:25:245 hrs ago1769253924IN
SyncSwap: Router V3
0 ETH0.000002070.00505
Swap287066582026-01-24 11:25:115 hrs ago1769253911IN
SyncSwap: Router V3
0 ETH0.000001320.00505
Swap287066392026-01-24 11:24:445 hrs ago1769253884IN
SyncSwap: Router V3
0 ETH0.000001390.00505
Swap287066142026-01-24 11:24:175 hrs ago1769253857IN
SyncSwap: Router V3
0 ETH0.000000870.00505
Burn Liquidity287032992026-01-24 10:16:446 hrs ago1769249804IN
SyncSwap: Router V3
0 ETH0.000000070.000169
Swap With Permit287031132026-01-24 10:13:346 hrs ago1769249614IN
SyncSwap: Router V3
0 ETH0.00000010.0001201
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
286824672026-01-24 2:46:4314 hrs ago1769222803
SyncSwap: Router V3
0.007 ETH
286824362026-01-24 2:45:4314 hrs ago1769222743
SyncSwap: Router V3
0.01 ETH
286824182026-01-24 2:45:1314 hrs ago1769222713
SyncSwap: Router V3
0.02 ETH
286823912026-01-24 2:44:2714 hrs ago1769222667
SyncSwap: Router V3
0.01 ETH
286631652026-01-23 18:52:5521 hrs ago1769194375
SyncSwap: Router V3
0.0005 ETH
286630482026-01-23 18:51:1521 hrs ago1769194275
SyncSwap: Router V3
0.0007 ETH
286624422026-01-23 18:37:1422 hrs ago1769193434
SyncSwap: Router V3
0.0005 ETH
286565972026-01-23 16:37:1224 hrs ago1769186232
SyncSwap: Router V3
0.00003111 ETH
286565972026-01-23 16:37:1224 hrs ago1769186232
SyncSwap: Router V3
0.00003111 ETH
286473172026-01-23 13:38:5927 hrs ago1769175539
SyncSwap: Router V3
0.0013 ETH
286472942026-01-23 13:38:3127 hrs ago1769175511
SyncSwap: Router V3
0.00006209 ETH
286445042026-01-23 12:39:2428 hrs ago1769171964
SyncSwap: Router V3
0.00005306 ETH
286445042026-01-23 12:39:2428 hrs ago1769171964
SyncSwap: Router V3
0.00005306 ETH
286326002026-01-23 8:13:1032 hrs ago1769155990
SyncSwap: Router V3
0.00091394 ETH
286326002026-01-23 8:13:1032 hrs ago1769155990
SyncSwap: Router V3
0.00091394 ETH
285950862026-01-22 15:52:582 days ago1769097178
SyncSwap: Router V3
0.017 ETH
285895232026-01-22 14:23:182 days ago1769091798
SyncSwap: Router V3
867 wei
285895232026-01-22 14:23:182 days ago1769091798
SyncSwap: Router V3
867 wei
285895232026-01-22 14:23:182 days ago1769091798
SyncSwap: Router V3
0.0008051 ETH
285894342026-01-22 14:21:232 days ago1769091683
SyncSwap: Router V3
0.002 ETH
285859872026-01-22 13:09:552 days ago1769087395
SyncSwap: Router V3
0.0049 ETH
285812872026-01-22 11:26:012 days ago1769081161
SyncSwap: Router V3
0.00000231 ETH
285748462026-01-22 8:58:362 days ago1769072316
SyncSwap: Router V3
0.00013 ETH
285741342026-01-22 8:39:222 days ago1769071162
SyncSwap: Router V3
0.00012 ETH
285740332026-01-22 8:36:312 days ago1769070991
SyncSwap: Router V3
0.00013 ETH
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SyncSwapRouterV3

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 2000000 runs

Other Settings:
default evmVersion, GNU AGPLv3 license
/**
 *Submitted for verification at scrollscan.com on 2025-04-10
*/

// SPDX-License-Identifier: AGPL-3.0-or-later
//      ___                         ___           ___           ___           ___           ___                   
//     /  /\          __           /  /\         /  /\         /  /\         /  /\         /  /\          ___     
//    /  /::\        |  |\        /  /::|       /  /::\       /  /::\       /  /:/_       /  /::\        /  /\    
//   /__/:/\:\       |  |:|      /  /:|:|      /  /:/\:\     /__/:/\:\     /  /:/ /\     /  /:/\:\      /  /::\   
//  _\_ \:\ \:\      |  |:|     /  /:/|:|__   /  /:/  \:\   _\_ \:\ \:\   /  /:/ /:/_   /  /::\ \:\    /  /:/\:\  
// /__/\ \:\ \:\     |__|:|__  /__/:/ |:| /\ /__/:/ \  \:\ /__/\ \:\ \:\ /__/:/ /:/ /\ /__/:/\:\_\:\  /  /::\ \:\ 
// \  \:\ \:\_\/     /  /::::\ \__\/  |:|/:/ \  \:\  \__\/ \  \:\ \:\_\/ \  \:\/:/ /:/ \__\/  \:\/:/ /__/:/\:\_\:\
//  \  \:\_\:\      /  /:/~~~~     |  |:/:/   \  \:\        \  \:\_\:\    \  \::/ /:/       \__\::/  \__\/  \:\/:/
//   \  \:\/:/     /__/:/          |__|::/     \  \:\        \  \:\/:/     \  \:\/:/        /  /:/        \  \::/ 
//    \  \::/      \__\/           /__/:/       \  \:\        \  \::/       \  \::/        /__/:/          \__\/  
//     \__\/                       \__\/         \__\/         \__\/         \__\/         \__\/                  
//
// Welcome to the SyncSwap V3 Router!
//

pragma solidity ^0.8.0;

interface IRouter {
    struct SwapStep {
        address pool;
        bytes data;
        address callback;
        bytes callbackData;
        bool useVault;

        address tokenOut;
        bool zeroForOne;
        address recipient;
        uint160 sqrtPriceLimitX96;
    }

    struct SwapPath {
        SwapStep[] steps;
        address tokenIn;
        uint amountIn;
    }

    struct SplitPermitParams {
        address token;
        uint approveAmount;
        uint deadline;
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct ArrayPermitParams {
        uint approveAmount;
        uint deadline;
        bytes signature;
    }
}

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

interface IStaking {
    function stake(uint amount, address to) external;
    function stake(address token, uint amount, address to) external;
}

interface IPoolFactory {
    function master() external view returns (address);

    function getDeployData() external view returns (bytes memory);

    function createPool(bytes calldata data) external returns (address pool);
}

/**
 * @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 Ownable {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(msg.sender);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        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);
    }
}

abstract contract Rescuable is Ownable {
    /// @dev Rescues ERC20 tokens.
    function rescueERC20(address token, address to, uint256 amount) external onlyOwner {
        require(to != address(0) && to != token, "Invalid to");

        uint balance = IERC20(token).balanceOf(address(this));

        if (amount == 0) {
            TransferHelper.safeTransfer(token, to, balance);
        } else {
            require(amount <= balance, "Exceeds balance");
            TransferHelper.safeTransfer(token, to, amount);
        }
    }

    /// @dev Rescues Ether.
    function rescueETH(address payable to, uint256 amount) external onlyOwner {
        if (amount == 0) {
            amount = address(this).balance;
        }
        TransferHelper.safeTransferETH(to, amount);
    }
}

/// @dev The ETH transfer has failed.
error ETHTransferFailed();

/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();

/// @dev The ERC20 `transfer` has failed.
error TransferFailed();

/// @dev The ERC20 `approve` has failed.
error ApproveFailed();

/// @dev Helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true / false.
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("approve(address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert ApproveFailed();
        }
    }

    function safeTransfer(
        address token,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("transfer(address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert TransferFailed();
        }
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint value
    ) internal {
        // bytes4(keccak256(bytes("transferFrom(address,address,uint256)")));
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert TransferFromFailed();
        }
    }

    function safeTransferETH(address to, uint value) internal {
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, ) = to.call{value: value}("");

        if (!success) {
            revert ETHTransferFailed();
        }
    }
}

interface IERC20Base {
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint amount) external returns (bool);
    function transfer(address to, uint amount) external returns (bool);
    function transferFrom(address from, address to, uint amount) external returns (bool);
    
    event Approval(address indexed owner, address indexed spender, uint amount);
    event Transfer(address indexed from, address indexed to, uint amount);
}

interface IERC20 is IERC20Base {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}

interface IERC20Permit is IERC20 {
    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
    function nonces(address owner) external view returns (uint);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

interface IERC20Permit2 is IERC20Permit {
    function permit2(address owner, address spender, uint amount, uint deadline, bytes calldata signature) external;
}

/// @title Interface for permit
/// @notice Interface used by DAI/CHAI for permit
interface IERC20PermitAllowed {
    /// @notice Approve the spender to spend some tokens via the holder signature
    /// @dev This is the permit interface used by DAI and CHAI
    /// @param holder The address of the token holder, the token owner
    /// @param spender The address of the token spender
    /// @param nonce The holder's nonce, increases at each call to permit
    /// @param expiry The timestamp at which the permit is no longer valid
    /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function permit(
        address holder,
        address spender,
        uint256 nonce,
        uint256 expiry,
        bool allowed,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

abstract contract SelfPermit {
    function selfPermit(
        address token,
        uint value,
        uint deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable {
        IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s);
    }

    function selfPermitIfNecessary(
        address token,
        uint value,
        uint deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < value) {
            selfPermit(token, value, deadline, v, r, s);
        }
    }

    function selfPermitAllowed(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable {
        IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s);
    }

    function selfPermitAllowedIfNecessary(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) {
            selfPermitAllowed(token, nonce, expiry, v, r, s);
        }
    }

    function selfPermit2(
        address token,
        uint value,
        uint deadline,
        bytes calldata signature
    ) public payable {
        IERC20Permit2(token).permit2(msg.sender, address(this), value, deadline, signature);
    }

    function selfPermit2IfNecessary(
        address token,
        uint value,
        uint deadline,
        bytes calldata signature
    ) external payable {
        if (IERC20(token).allowance(msg.sender, address(this)) < value) {
            selfPermit2(token, value, deadline, signature);
        }
    }
}

/// @title Permissionless pool actions
/// @notice Contains pool methods that can be called by anyone
interface ICLPoolActions {
    /// @notice Initialize function used in proxy deployment
    /// @dev Can be called once only
    /// Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value
    /// @dev not locked because it initializes unlocked
    /// @param _factory The CL factory contract address
    /// @param _token0 The first token of the pool by address sort order
    /// @param _token1 The second token of the pool by address sort order
    /// @param _tickSpacing The pool tick spacing
    /// @param _sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96
    function initialize(
        address _factory,
        address _token0,
        address _token1,
        int24 _tickSpacing,
        uint160 _sqrtPriceX96
    ) external;

    /// @notice Initialize gauge and nft manager
    /// @dev Callable only once, by the gauge factory
    /// @param _gauge The gauge corresponding to this pool
    /// @param _nft The position manager used for position management
    function setGaugeAndPositionManager(address _gauge, address _nft) external;

    /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position
    /// @dev The caller of this method receives a callback in the form of ICLMintCallback#uniswapV3MintCallback
    /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends
    /// on tickLower, tickUpper, the amount of liquidity, and the current price.
    /// @param recipient The address for which the liquidity will be created
    /// @param tickLower The lower tick of the position in which to add liquidity
    /// @param tickUpper The upper tick of the position in which to add liquidity
    /// @param amount The amount of liquidity to mint
    /// @param data Any data that should be passed through to the callback
    /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback
    /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback
    function mint(address recipient, int24 tickLower, int24 tickUpper, uint128 amount, bytes calldata data)
        external
        returns (uint256 amount0, uint256 amount1);

    /// @notice Collects tokens owed to a position
    /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.
    /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or
    /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the
    /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.
    /// @param recipient The address which should receive the fees collected
    /// @param tickLower The lower tick of the position for which to collect fees
    /// @param tickUpper The upper tick of the position for which to collect fees
    /// @param amount0Requested How much token0 should be withdrawn from the fees owed
    /// @param amount1Requested How much token1 should be withdrawn from the fees owed
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collect(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount0Requested,
        uint128 amount1Requested
    ) external returns (uint128 amount0, uint128 amount1);

    /// @notice Collects tokens owed to a position
    /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.
    /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or
    /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the
    /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.
    /// @param recipient The address which should receive the fees collected
    /// @param tickLower The lower tick of the position for which to collect fees
    /// @param tickUpper The upper tick of the position for which to collect fees
    /// @param amount0Requested How much token0 should be withdrawn from the fees owed
    /// @param amount1Requested How much token1 should be withdrawn from the fees owed
    /// @param owner Owner of the position in the pool (nft manager or gauge)
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collect(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount0Requested,
        uint128 amount1Requested,
        address owner
    ) external returns (uint128 amount0, uint128 amount1);

    /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position
    /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0
    /// @dev Fees must be collected separately via a call to #collect
    /// @param tickLower The lower tick of the position for which to burn liquidity
    /// @param tickUpper The upper tick of the position for which to burn liquidity
    /// @param amount How much liquidity to burn
    /// @return amount0 The amount of token0 sent to the recipient
    /// @return amount1 The amount of token1 sent to the recipient
    function burn(int24 tickLower, int24 tickUpper, uint128 amount)
        external
        returns (uint256 amount0, uint256 amount1);

    /// @notice Burn liquidity from the supplied owner and account tokens owed for the liquidity to the position
    /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0
    /// @dev Fees must be collected separately via a call to #collect
    /// @param tickLower The lower tick of the position for which to burn liquidity
    /// @param tickUpper The upper tick of the position for which to burn liquidity
    /// @param amount How much liquidity to burn
    /// @param owner Owner of the position in the pool (nft manager or gauge)
    /// @return amount0 The amount of token0 sent to the recipient
    /// @return amount1 The amount of token1 sent to the recipient
    function burn(int24 tickLower, int24 tickUpper, uint128 amount, address owner)
        external
        returns (uint256 amount0, uint256 amount1);

    /// @notice Convert existing liquidity into staked liquidity
    /// @notice Only callable by the gauge associated with this pool
    /// @param stakedLiquidityDelta The amount by which to increase or decrease the staked liquidity
    /// @param tickLower The lower tick of the position for which to stake liquidity
    /// @param tickUpper The upper tick of the position for which to stake liquidity
    /// @param positionUpdate If the nft and gauge position should be updated
    function stake(int128 stakedLiquidityDelta, int24 tickLower, int24 tickUpper, bool positionUpdate) external;

    /// @notice Swap token0 for token1, or token1 for token0
    /// @dev The caller of this method receives a callback in the form of ICLSwapCallback#uniswapV3SwapCallback
    /// @param recipient The address to receive the output of the swap
    /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0
    /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)
    /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this
    /// value after the swap. If one for zero, the price cannot be greater than this value after the swap
    /// @param data Any data to be passed through to the callback
    /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive
    /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive
    function swap(
        address recipient,
        bool zeroForOne,
        int256 amountSpecified,
        uint160 sqrtPriceLimitX96,
        bytes calldata data
    ) external returns (int256 amount0, int256 amount1);

    function swap(
        address recipient,
        bool zeroForOne,
        int256 amountSpecified,
        uint160 sqrtPriceLimitX96,
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (int256 amount0, int256 amount1);

    /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback
    /// @dev The caller of this method receives a callback in the form of ICLFlashCallback#uniswapV3FlashCallback
    /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling
    /// with 0 amount{0,1} and sending the donation amount(s) from the callback
    /// @param recipient The address which will receive the token0 and token1 amounts
    /// @param amount0 The amount of token0 to send
    /// @param amount1 The amount of token1 to send
    /// @param data Any data to be passed through to the callback
    function flash(address recipient, uint256 amount0, uint256 amount1, bytes calldata data) external;

    /// @notice Increase the maximum number of price and liquidity observations that this pool will store
    /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to
    /// the input observationCardinalityNext.
    /// @param observationCardinalityNext The desired minimum number of observations for the pool to store
    function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;

    /// @notice Updates rewardGrowthGlobalX128 every time when any tick is crossed,
    /// or when any position is staked/unstaked from the gauge
    function updateRewardsGrowthGlobal() external;

    /// @notice Syncs rewards with gauge
    /// @param rewardRate the rate rewards being distributed during the epoch
    /// @param rewardReserve the available rewards to be distributed during the epoch
    /// @param periodFinish the end of the current period of rewards, updated once per epoch
    function syncReward(uint256 rewardRate, uint256 rewardReserve, uint256 periodFinish) external;
}

/// @notice Helper utility that enables calling multiple local methods in a single call.
/// @author Modified from Uniswap (https://github.com/Uniswap/v3-periphery/blob/main/contracts/base/Multicall.sol)
/// License-Identifier: GPL-2.0-or-later
abstract contract Multicall {
    function multicall(bytes[] calldata data) public payable returns (bytes[] memory results) {
        results = new bytes[](data.length);
        
        for (uint i; i < data.length;) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);

            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string)));
            }

            results[i] = result;

            // cannot realistically overflow on human timescales
            unchecked {
                ++i;
            }
        }
    }
}

interface IPool {
    struct TokenAmount {
        address token;
        uint amount;
    }

    /// @dev Returns the address of pool master.
    function master() external view returns (address);

    /// @dev Returns the vault.
    function vault() external view returns (address);

    /// @dev Returns the pool type.
    function poolType() external view returns (uint16);

    /// @dev Returns the assets of the pool.
    function getAssets() external view returns (address[] memory assets);

    /// @dev Returns the swap fee of the pool.
    function getSwapFee(address sender, address tokenIn, address tokenOut, bytes calldata data) external view returns (uint24 swapFee);

    /// @dev Returns the protocol fee of the pool.
    function getProtocolFee() external view returns (uint24 protocolFee);

    /// @dev Mints liquidity.
    function mint(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (uint liquidity);

    /// @dev Burns liquidity.
    function burn(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount[] memory tokenAmounts);

    /// @dev Burns liquidity with single output token.
    function burnSingle(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount memory tokenAmount);

    /// @dev Swaps between tokens.
    function swap(
        bytes calldata data,
        address sender,
        address callback,
        bytes calldata callbackData
    ) external returns (TokenAmount memory tokenAmount);
}

interface IBasePool is IPool, IERC20Permit2 {
    function token0() external view returns (address);
    function token1() external view returns (address);

    function reserve0() external view returns (uint);
    function reserve1() external view returns (uint);
    function invariantLast() external view returns (uint);

    function getReserves() external view returns (uint, uint);
    function getAmountOut(address tokenIn, uint amountIn, address sender) external view returns (uint amountOut);
    function getAmountIn(address tokenOut, uint amountOut, address sender) external view returns (uint amountIn);

    event Mint(
        address indexed sender,
        uint amount0,
        uint amount1,
        uint liquidity,
        address indexed to
    );

    event Burn(
        address indexed sender,
        uint amount0,
        uint amount1,
        uint liquidity,
        address indexed to
    );

    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );

    event Sync(
        uint reserve0,
        uint reserve1
    );
}

interface IVault {
    function wETH() external view returns (address);

    function reserves(address token) external view returns (uint reserve);

    function balanceOf(address token, address owner) external view returns (uint balance);

    function deposit(address token, address to) external payable returns (uint amount);

    function depositETH(address to) external payable returns (uint amount);

    function transferAndDeposit(address token, address to, uint amount) external payable returns (uint);

    function transfer(address token, address to, uint amount) external;

    function withdraw(address token, address to, uint amount) external;

    function withdrawAlternative(address token, address to, uint amount, uint8 mode) external;

    function withdrawETH(address to, uint amount) external;
}

interface INFTPositionManager {
    struct MintParams {
        address token0;
        address token1;
        int24 tickSpacing;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
        uint160 sqrtPriceX96;
    }

    function mint(MintParams calldata params)
        external
        payable
        returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);

    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    function increaseLiquidity(IncreaseLiquidityParams calldata params)
        external
        payable
        returns (uint128 liquidity, uint256 amount0, uint256 amount1);
}

error NotEnoughLiquidityMinted();
error TooLittleReceived();
error Expired();

/// @notice The router is a universal interface for users to access
/// functions across different protocol parts in one place.
///
/// It handles the allowances and transfers of tokens, and
/// allows chained swaps/operations across multiple pools, with
/// additional features like slippage protection and permit support.
///
contract SyncSwapRouterV3 is IRouter, SelfPermit, Multicall, Rescuable {

    struct TokenInput {
        address token;
        uint amount;
        bool useVault;
    }

    address public constant vault = 0x7160570BB153Edd0Ea1775EC2b2Ac9b65F1aB61B;
    address public constant wETH = 0x5300000000000000000000000000000000000004;
    address private constant NATIVE_TOKEN = address(0);

    mapping(address => mapping(address => bool)) public isPoolEntered;
    mapping(address => address[]) public enteredPools;

    modifier ensure(uint deadline) {
        // solhint-disable-next-line not-rely-on-time
        if (block.timestamp > deadline) {
            revert Expired();
        }
        _;
    }

    receive() external payable {
        //require(msg.sender == wETH, "Not wETH");
    }

    function enteredPoolsLength(address account) external view returns (uint) {
        return enteredPools[account].length;
    }

    function _transferFromSender(address token, address to, uint amount, bool useVault) private {
        if (useVault) {
            if (token == NATIVE_TOKEN || (token == wETH && address(this).balance >= amount)) {
                // Deposit ETH to the vault.
                IVault(vault).deposit{value: amount}(NATIVE_TOKEN, to);
            } else {
                // Transfer tokens to the vault.
                TransferHelper.safeTransferFrom(token, msg.sender, vault, amount);

                // Notify the vault to deposit to receiver.
                IVault(vault).deposit(token, to);
            }
        } else {
            if (token == NATIVE_TOKEN || (token == wETH && address(this).balance >= amount)) {
                // Wrap native ETH to wETH.
                IWETH(wETH).deposit{value: amount}();

                // Send wETH to the receiver.
                IWETH(wETH).transfer(to, amount);
            } else {
                // Transfer tokens to the receiver.
                TransferHelper.safeTransferFrom(token, msg.sender, to, amount);
            }
        }
    }

    function _transferAndAddLiquidity(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData
    ) private returns (uint liquidity) {
        // Send all input tokens to the pool.
        uint n = inputs.length;

        TokenInput memory input;

        for (uint i; i < n; ) {
            input = inputs[i];

            _transferFromSender(input.token, pool, input.amount, input.useVault);

            unchecked {
                ++i;
            }
        }

        liquidity = IPool(pool).mint(data, msg.sender, callback, callbackData);

        if (liquidity < minLiquidity) {
            revert NotEnoughLiquidityMinted();
        }
    }

    function _markPoolEntered(address pool) private {
        if (!isPoolEntered[pool][msg.sender]) {
            isPoolEntered[pool][msg.sender] = true;
            enteredPools[msg.sender].push(pool);
        }
    }

    function addLiquidity(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        address staking
    ) public payable returns (uint liquidity) {
        liquidity = _transferAndAddLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData
        );

        if (staking != address(0)) {
            address to = abi.decode(data, (address));
            IStaking(staking).stake(liquidity, to);
        }
    }

    function addLiquidity2(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        address staking
    ) external payable returns (uint liquidity) {
        liquidity = addLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData,
            staking
        );

        _markPoolEntered(pool);
    }

    function addLiquidityWithPermit(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        SplitPermitParams[] memory permits,
        address staking
    ) public payable returns (uint liquidity) {
        // Approve all tokens via permit.
        uint n = permits.length;

        SplitPermitParams memory params;

        for (uint i; i < n; ) {
            params = permits[i];

            IERC20Permit(params.token).permit(
                msg.sender,
                address(this),
                params.approveAmount,
                params.deadline,
                params.v,
                params.r,
                params.s
            );

            unchecked {
                ++i;
            }
        }

        liquidity = _transferAndAddLiquidity(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData
        );

        if (staking != address(0)) {
            address to = abi.decode(data, (address));
            IStaking(staking).stake(liquidity, to);
        }
    }

    function addLiquidityWithPermit2(
        address pool,
        TokenInput[] calldata inputs,
        bytes calldata data,
        uint minLiquidity,
        address callback,
        bytes calldata callbackData,
        SplitPermitParams[] memory permits,
        address staking
    ) public payable returns (uint liquidity) {
        liquidity = addLiquidityWithPermit(
            pool,
            inputs,
            data,
            minLiquidity,
            callback,
            callbackData,
            permits,
            staking
        );

        _markPoolEntered(pool);
    }

    // Burn Liquidity
    function _transferAndBurnLiquidity(
        address pool,
        uint liquidity,
        bytes memory data,
        uint[] memory minAmounts,
        address callback,
        bytes calldata callbackData
    ) private returns (IPool.TokenAmount[] memory amounts) {
        IBasePool(pool).transferFrom(msg.sender, pool, liquidity);

        amounts = IPool(pool).burn(data, msg.sender, callback, callbackData);

        uint n = amounts.length;

        for (uint i; i < n; ) {
            IPool.TokenAmount memory tokenAmount = amounts[i];

            if (tokenAmount.amount < minAmounts[i]) {
                revert TooLittleReceived();
            }

            unchecked {
                ++i;
            }
        }
    }

    function burnLiquidity(
        address pool,
        uint liquidity,
        bytes calldata data,
        uint[] calldata minAmounts,
        address callback,
        bytes calldata callbackData
    ) external returns (IPool.TokenAmount[] memory amounts) {
        amounts = _transferAndBurnLiquidity(
            pool,
            liquidity,
            data,
            minAmounts,
            callback,
            callbackData
        );
    }

    function burnLiquidityWithPermit(
        address pool,
        uint liquidity,
        bytes calldata data,
        uint[] calldata minAmounts,
        address callback,
        bytes calldata callbackData,
        ArrayPermitParams memory permit
    ) external returns (IPool.TokenAmount[] memory amounts) {
        // Approve liquidity via permit.
        IBasePool(pool).permit2(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.signature
        );

        amounts = _transferAndBurnLiquidity(
            pool,
            liquidity,
            data,
            minAmounts,
            callback,
            callbackData
        );
    }

    // Burn Liquidity Single
    function _transferAndBurnLiquiditySingle(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData
    ) private returns (IPool.TokenAmount memory amountOut) {
        IBasePool(pool).transferFrom(msg.sender, pool, liquidity);

        amountOut = IPool(pool).burnSingle(data, msg.sender, callback, callbackData);

        if (amountOut.amount < minAmount) {
            revert TooLittleReceived();
        }
    }

    function burnLiquiditySingle(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData
    ) external returns (IPool.TokenAmount memory amountOut) {
        amountOut = _transferAndBurnLiquiditySingle(
            pool,
            liquidity,
            data,
            minAmount,
            callback,
            callbackData
        );
    }

    function burnLiquiditySingleWithPermit(
        address pool,
        uint liquidity,
        bytes memory data,
        uint minAmount,
        address callback,
        bytes memory callbackData,
        ArrayPermitParams calldata permit
    ) external returns (IPool.TokenAmount memory amountOut) {
        // Approve liquidity via permit.
        IBasePool(pool).permit2(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.signature
        );

        amountOut = _transferAndBurnLiquiditySingle(
            pool,
            liquidity,
            data,
            minAmount,
            callback,
            callbackData
        );
    }

    function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
        require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported

        (address tokenIn, uint amountToPay) = abi.decode(data, (address, uint));

        //pay(tokenIn, address(this), msg.sender, amountToPay);

        /*
        if ((tokenIn == wETH || tokenIn == NATIVE_TOKEN) && address(this).balance >= amountToPay) {
            // pay with WETH
            IWETH(wETH).deposit{value: amountToPay}(); // wrap only what is needed to pay
            IWETH(wETH).transfer(msg.sender, amountToPay);
        } else {
            // pay with tokens already in the contract (for the exact input multihop case)
            TransferHelper.safeTransfer(tokenIn, msg.sender, amountToPay);
        }
        */

        // pay with tokens already in the contract (for the exact input multihop case)
        TransferHelper.safeTransfer(tokenIn == NATIVE_TOKEN ? wETH : tokenIn, msg.sender, amountToPay);
    }

    struct SwapState {
        IPool.TokenAmount lastAmountOut;
        uint lastStepIndex;
    }

    // Swap
    function _swap(
        SwapPath[] memory paths,
        uint amountOutMin,
        address ethUnwrapRecipient
    ) private returns (IPool.TokenAmount memory amountOut) {
        uint pathsLength = paths.length;

        SwapPath memory path;
        SwapStep memory step;

        SwapState memory state;

        for (uint pathIndex; pathIndex < pathsLength; ) {
            path = paths[pathIndex];

            // Prefund the first step.
            step = path.steps[0];

            // Receive funds from sender.
            if (step.recipient == address(0)) {
                _transferFromSender(
                    path.tokenIn,
                    step.pool, // prefund the first pool
                    path.amountIn,
                    step.useVault
                );
            } else {
                // range pools
                _transferFromSender(
                    path.tokenIn,
                    address(this), // send to router first for range pools
                    path.amountIn,
                    step.useVault
                );

                state.lastAmountOut = IPool.TokenAmount(path.tokenIn, path.amountIn);
            }

            // Cache steps length.
            state.lastStepIndex = path.steps.length - 1;

            uint stepIndex;
            while (true) {

                if (step.recipient == address(0)) {
                    state.lastAmountOut = IBasePool(step.pool).swap(
                        step.data, msg.sender, step.callback, step.callbackData
                    );
                } else {
                    // Using output amount of last step, or the path input amount for the first step.

                    // input token and amount
                    bytes memory rangePoolCallbackData = abi.encode(state.lastAmountOut.token, state.lastAmountOut.amount);

                    (int256 amount0, int256 amount1) = ICLPoolActions(step.pool).swap(
                        step.recipient,
                        step.zeroForOne,
                        int256(state.lastAmountOut.amount),
                        (
                            step.sqrtPriceLimitX96 == 0
                            ? (step.zeroForOne ? 4295128740 : 1461446703485210103287273052203988822378723970341)
                            : step.sqrtPriceLimitX96
                        ),
                        rangePoolCallbackData,
                        msg.sender,
                        step.callback,
                        step.callbackData
                    );

                    state.lastAmountOut = IPool.TokenAmount({
                        token: step.tokenOut,
                        amount: step.zeroForOne ? uint(-amount1) : uint(-amount0)
                    });
                }

                if (stepIndex >= state.lastStepIndex) {
                    amountOut.token = state.lastAmountOut.token;
                    amountOut.amount += state.lastAmountOut.amount;

                    break; // next path
                } else {
                    bool previousStepUseVault = step.useVault;

                    unchecked {
                        ++stepIndex;
                    }

                    // Cache the next step.
                    step = path.steps[stepIndex];

                    if (!previousStepUseVault && step.useVault) {
                        uint amount = IERC20(state.lastAmountOut.token).balanceOf(address(this));

                        // Transfer tokens to the vault.
                        TransferHelper.safeTransfer(state.lastAmountOut.token, vault, amount);

                        // Notify the vault to deposit.
                        IVault(vault).deposit(state.lastAmountOut.token, step.pool);
                    }
                }
            }

            unchecked {
                ++pathIndex;
            }
        }

        if (amountOut.amount < amountOutMin) {
            revert TooLittleReceived();
        }

        if (ethUnwrapRecipient != address(0)) {
            IWETH(wETH).withdraw(IERC20(wETH).balanceOf(address(this)));
            TransferHelper.safeTransferETH(ethUnwrapRecipient, address(this).balance);
        }
    }

    function swap(
        SwapPath[] memory paths,
        uint amountOutMin,
        uint deadline,
        address ethUnwrapRecipient
    ) external payable ensure(deadline) returns (IPool.TokenAmount memory amountOut) {
        amountOut = _swap(
            paths,
            amountOutMin,
            ethUnwrapRecipient
        );
    }

    function swapWithPermit(
        SwapPath[] memory paths,
        uint amountOutMin,
        uint deadline,
        SplitPermitParams calldata permit,
        address ethUnwrapRecipient
    ) external payable ensure(deadline) returns (IPool.TokenAmount memory amountOut) {
        // Approve input tokens via permit.
        IERC20Permit(permit.token).permit(
            msg.sender,
            address(this),
            permit.approveAmount,
            permit.deadline,
            permit.v,
            permit.r,
            permit.s
        );

        amountOut = _swap(
            paths,
            amountOutMin,
            ethUnwrapRecipient
        );
    }

    function createPosition(
        address nftPositionManager,
        address pool,
        INFTPositionManager.MintParams calldata params
    ) public payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1) {
        if (params.token0 != wETH || msg.value == 0) {
            _transferFromSender(params.token0, address(this), params.amount0Desired, false);
            _safeApproveToken(params.token0, nftPositionManager, params.amount0Desired);
        }

        if (params.token1 != wETH || msg.value == 0) {
            _transferFromSender(params.token1, address(this), params.amount1Desired, false);
            _safeApproveToken(params.token1, nftPositionManager, params.amount1Desired);
        }

        (tokenId, liquidity, amount0, amount1) = INFTPositionManager(nftPositionManager).mint{value: msg.value}(params);

        // refund
        _refundTokenTo(params.token0, msg.sender);
        _refundTokenTo(params.token1, msg.sender);

        _markPoolEntered(pool);
    }

    function createPositionWithPermit(
        address nftPositionManager,
        address pool,
        INFTPositionManager.MintParams calldata params,
        SplitPermitParams[] memory permits
    ) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1) {
        // Approve all tokens via permit.
        uint n = permits.length;

        SplitPermitParams memory permitParams;

        for (uint i; i < n; ) {
            permitParams = permits[i];

            IERC20Permit(permitParams.token).permit(
                msg.sender,
                address(this),
                permitParams.approveAmount,
                permitParams.deadline,
                permitParams.v,
                permitParams.r,
                permitParams.s
            );

            unchecked {
                ++i;
            }
        }

        (tokenId, liquidity, amount0, amount1) = createPosition(
            nftPositionManager,
            pool,
            params
        );
    }

    function increaseLiquidity(
        address nftPositionManager,
        address tokenA,
        address tokenB,
        INFTPositionManager.IncreaseLiquidityParams calldata params
    ) public payable returns (uint128 liquidity, uint256 amount0, uint256 amount1) {
        if (tokenA != wETH || msg.value == 0) {
            _transferFromSender(tokenA, address(this), params.amount0Desired, false);
            _safeApproveToken(tokenA, nftPositionManager, params.amount0Desired);
        }

        if (tokenB != wETH || msg.value == 0) {
            _transferFromSender(tokenB, address(this), params.amount1Desired, false);
            _safeApproveToken(tokenB, nftPositionManager, params.amount1Desired);
        }

        (liquidity, amount0, amount1) = INFTPositionManager(nftPositionManager).increaseLiquidity{value: msg.value}(params);

        // refund
        _refundTokenTo(tokenA, msg.sender);
        _refundTokenTo(tokenB, msg.sender);
    }

    function increaseLiquidityWithPermit(
        address nftPositionManager,
        address tokenA,
        address tokenB,
        INFTPositionManager.IncreaseLiquidityParams calldata params,
        SplitPermitParams[] memory permits
    ) external payable returns (uint128 liquidity, uint256 amount0, uint256 amount1) {
        // Approve all tokens via permit.
        uint n = permits.length;

        SplitPermitParams memory permitParams;

        for (uint i; i < n; ) {
            permitParams = permits[i];

            IERC20Permit(permitParams.token).permit(
                msg.sender,
                address(this),
                permitParams.approveAmount,
                permitParams.deadline,
                permitParams.v,
                permitParams.r,
                permitParams.s
            );

            unchecked {
                ++i;
            }
        }

        (liquidity, amount0, amount1) = increaseLiquidity(
            nftPositionManager,
            tokenA,
            tokenB,
            params
        );
    }

    function _refundTokenTo(address token, address to) private {
        if (token == NATIVE_TOKEN || token == wETH) {
            uint balance = IERC20(wETH).balanceOf(address(this));
            if (balance != 0) {
                IWETH(wETH).withdraw(balance);
            }
            if (address(this).balance != 0) {
                TransferHelper.safeTransferETH(to, address(this).balance);
            }
        } else {
            uint balance = IERC20(token).balanceOf(address(this));
            if (balance != 0) {
                TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
            }
        }
    }

    function _safeApproveToken(address token, address spender, uint amount) private {
        if (token != NATIVE_TOKEN) {
            if (IERC20(token).allowance(address(this), spender) < amount) {
                TransferHelper.safeApprove(token, spender, 0); // set to 0 first for better compatibility
                TransferHelper.safeApprove(token, spender, type(uint).max);
            }
        }
    }

    /// @notice Wrapper function to allow pool deployment to be batched.
    function createPool(address _factory, bytes calldata data) external payable returns (address) {
        return IPoolFactory(_factory).createPool(data);
    }

    function _stake(address target, address token, uint amount) private {
        TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);

        if (IERC20(token).allowance(address(this), target) < amount) {
            /// @dev This can approve arbitrary contract, the router is not intended to store any funds.
            TransferHelper.safeApprove(token, target, type(uint).max);
        }
    }

    /// @dev Universal function to stake tokens to a target contract.
    function stake(address target, address token, uint amount, address to) external {
        _stake(target, token, amount);
        IStaking(target).stake(amount, to);
    }

    function stakeWithToken(address target, address token, uint amount, address to) external {
        _stake(target, token, amount);
        IStaking(target).stake(token, amount, to);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"ApproveFailed","type":"error"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"Expired","type":"error"},{"inputs":[],"name":"NotEnoughLiquidityMinted","type":"error"},{"inputs":[],"name":"TooLittleReceived","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"useVault","type":"bool"}],"internalType":"struct SyncSwapRouterV3.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"internalType":"address","name":"staking","type":"address"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"useVault","type":"bool"}],"internalType":"struct SyncSwapRouterV3.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"internalType":"address","name":"staking","type":"address"}],"name":"addLiquidity2","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"useVault","type":"bool"}],"internalType":"struct SyncSwapRouterV3.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"},{"internalType":"address","name":"staking","type":"address"}],"name":"addLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"useVault","type":"bool"}],"internalType":"struct SyncSwapRouterV3.TokenInput[]","name":"inputs","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"},{"internalType":"address","name":"staking","type":"address"}],"name":"addLiquidityWithPermit2","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256[]","name":"minAmounts","type":"uint256[]"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"burnLiquidity","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"amounts","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"burnLiquiditySingle","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IRouter.ArrayPermitParams","name":"permit","type":"tuple"}],"name":"burnLiquiditySingleWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256[]","name":"minAmounts","type":"uint256[]"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"components":[{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IRouter.ArrayPermitParams","name":"permit","type":"tuple"}],"name":"burnLiquidityWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"amounts","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"createPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nftPositionManager","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"internalType":"struct INFTPositionManager.MintParams","name":"params","type":"tuple"}],"name":"createPosition","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nftPositionManager","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"internalType":"struct INFTPositionManager.MintParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"}],"name":"createPositionWithPermit","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"enteredPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"enteredPoolsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftPositionManager","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct INFTPositionManager.IncreaseLiquidityParams","name":"params","type":"tuple"}],"name":"increaseLiquidity","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nftPositionManager","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct INFTPositionManager.IncreaseLiquidityParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams[]","name":"permits","type":"tuple[]"}],"name":"increaseLiquidityWithPermit","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isPoolEntered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"selfPermit2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"selfPermit2IfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowed","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowedIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"stakeWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"internalType":"bool","name":"useVault","type":"bool"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct IRouter.SwapStep[]","name":"steps","type":"tuple[]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"internalType":"struct IRouter.SwapPath[]","name":"paths","type":"tuple[]"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"ethUnwrapRecipient","type":"address"}],"name":"swap","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"callback","type":"address"},{"internalType":"bytes","name":"callbackData","type":"bytes"},{"internalType":"bool","name":"useVault","type":"bool"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct IRouter.SwapStep[]","name":"steps","type":"tuple[]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"internalType":"struct IRouter.SwapPath[]","name":"paths","type":"tuple[]"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"approveAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IRouter.SplitPermitParams","name":"permit","type":"tuple"},{"internalType":"address","name":"ethUnwrapRecipient","type":"address"}],"name":"swapWithPermit","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount","name":"amountOut","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052348015600e575f80fd5b50601633601a565b6069565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6152c0806100765f395ff3fe60806040526004361061022c575f3560e01c80638eb8287111610131578063eb1432f0116100ac578063f44e537a1161007c578063fb68908811610062578063fb6890881461066e578063fbfa77cf14610681578063fc31d54a146106a8575f80fd5b8063f44e537a14610630578063fa461e331461064f575f80fd5b8063eb1432f0146105c4578063f2428621146105d7578063f2fde38b146105fe578063f3995c671461061d575f80fd5b8063ad271fa311610101578063b6541ffe116100e7578063b6541ffe1461055d578063b956b3fb14610570578063c2e3140a146105b1575f80fd5b8063ad271fa31461051f578063b2118a8d1461053e575f80fd5b80638eb82871146104955780639dd41df2146104d9578063a4a78f0c146104ec578063ac9650d8146104ff575f80fd5b8063523acafa116101c15780636cc781cd116101915780637d10c9d6116101775780637d10c9d61461043a5780638aa74f71146104595780638da5cb5b1461046c575f80fd5b80636cc781cd14610413578063715018a614610426575f80fd5b8063523acafa146103af57806353c43f15146103c25780636291027c146103e1578063688ee44c14610400575f80fd5b806339be5126116101fc57806339be5126146102f15780634659a4941461031257806346e8f38f146103255780634f25b85814610366575f80fd5b8063099a04e5146102375780630ae6a646146102585780632b4abadb14610281578063353766c6146102c5575f80fd5b3661023357005b5f80fd5b348015610242575f80fd5b5061025661025136600461386d565b6106bb565b005b61026b610266366004613d00565b6106db565b6040516102789190613d74565b60405180910390f35b34801561028c575f80fd5b506102a061029b36600461386d565b61082e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610278565b3480156102d0575f80fd5b506102e46102df366004613e82565b61086f565b6040516102789190613f74565b6103046102ff3660046140f4565b610987565b604051908152602001610278565b6102566103203660046141f6565b610b86565b61033861033336600461424c565b610c3c565b604080516fffffffffffffffffffffffffffffffff9094168452602084019290925290820152606001610278565b348015610371575f80fd5b5061039f6103803660046142a5565b600160209081525f928352604080842090915290825290205460ff1681565b6040519015158152602001610278565b6103386103bd3660046142dc565b610ddd565b3480156103cd575f80fd5b5061026b6103dc366004614360565b610f29565b3480156103ec575f80fd5b506102566103fb3660046143fa565b610f4a565b61025661040e36600461444a565b610fdf565b61025661042136600461444a565b61108d565b348015610431575f80fd5b5061025661111d565b348015610445575f80fd5b5061026b6104543660046144bf565b611130565b61026b610467366004614582565b6111dd565b348015610477575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166102a0565b6104a86104a33660046145e7565b611240565b604080519485526fffffffffffffffffffffffffffffffff9093166020850152918301526060820152608001610278565b6102a06104e736600461462d565b611425565b6102566104fa3660046141f6565b6114c3565b61051261050d36600461467e565b611593565b6040516102789190614709565b34801561052a575f80fd5b506102e461053936600461478a565b6116fd565b348015610549575f80fd5b50610256610558366004614858565b611782565b6104a861056b366004614896565b611963565b34801561057b575f80fd5b5061030461058a366004614908565b73ffffffffffffffffffffffffffffffffffffffff165f9081526002602052604090205490565b6102566105bf3660046141f6565b611ab0565b6103046105d236600461492a565b611b58565b3480156105e2575f80fd5b506102a073530000000000000000000000000000000000000481565b348015610609575f80fd5b50610256610618366004614908565b611b76565b61025661062b3660046141f6565b611c2d565b34801561063b575f80fd5b5061025661064a3660046143fa565b611caa565b34801561065a575f80fd5b50610256610669366004614a04565b611d18565b61030461067c3660046140f4565b611d82565b34801561068c575f80fd5b506102a0737160570bb153edd0ea1775ec2b2ac9b65f1ab61b81565b6103046106b636600461492a565b611da1565b6106c3611e74565b805f036106cd5750475b6106d78282611f10565b5050565b604080518082019091525f80825260208201528380421115610729576040517f203d82d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107366020850185614908565b73ffffffffffffffffffffffffffffffffffffffff1663d505accf33306020880135604089013561076d60808b0160608c01614a53565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff95861660048201529490931660248501526044840191909152606483015260ff166084820152608087013560a482015260a087013560c482015260e4015f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050610823878785611fab565b979650505050505050565b6002602052815f5260405f208181548110610847575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b8051602082015160408084015190517f2c0198cc00000000000000000000000000000000000000000000000000000000815260609373ffffffffffffffffffffffffffffffffffffffff8f1693632c0198cc936108d6933393309390929091600401614a6c565b5f604051808303815f87803b1580156108ed575f80fd5b505af11580156108ff573d5f803e3d5ffd5b505050506109788b8b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284375f920191909152508c92508b91508a90506126cf565b9b9a5050505050505050505050565b81516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a081018290529091905f5b82811015610aaf578581815181106109d8576109d8614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015610a8e575f80fd5b505af1158015610aa0573d5f803e3d5ffd5b505050508060010190506109be565b50610ac18e8e8e8e8e8e8e8e8e6128c0565b925073ffffffffffffffffffffffffffffffffffffffff841615610b75575f610aec8b8d018d614908565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810186905273ffffffffffffffffffffffffffffffffffffffff808316602483015291925090861690637acb7757906044015f604051808303815f87803b158015610b5d575f80fd5b505af1158015610b6f573d5f803e3d5ffd5b50505050505b50509b9a5050505050505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b5f604051808303815f87803b158015610c1e575f80fd5b505af1158015610c30573d5f803e3d5ffd5b50505050505050505050565b5f808073ffffffffffffffffffffffffffffffffffffffff8616735300000000000000000000000000000000000004141580610c76575034155b15610c9a57610c8b863086602001355f612a18565b610c9a86888660200135612d75565b73ffffffffffffffffffffffffffffffffffffffff8516735300000000000000000000000000000000000004141580610cd1575034155b15610cf557610ce6853086604001355f612a18565b610cf585888660400135612d75565b604080517f219f5d170000000000000000000000000000000000000000000000000000000081528535600482015260208601356024820152908501356044820152606085013560648201526080850135608482015260a085013560a482015273ffffffffffffffffffffffffffffffffffffffff88169063219f5d1790349060c40160606040518083038185885af1158015610d93573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610db89190614b0e565b91945092509050610dc98633612e64565b610dd38533612e64565b9450945094915050565b80516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052909182918291905f5b82811015610f0957868181518110610e3257610e32614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015610ee8575f80fd5b505af1158015610efa573d5f803e3d5ffd5b50505050806001019050610e18565b50610f168a8a8a8a610c3c565b919c909b50909950975050505050505050565b604080518082019091525f8082526020820152610823878787878787613102565b610f55848484613286565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8281166024830152851690637acb7757906044015b5f604051808303815f87803b158015610fc3575f80fd5b505af1158015610fd5573d5f803e3d5ffd5b5050505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152849073ffffffffffffffffffffffffffffffffffffffff87169063dd62ed3e90604401602060405180830381865afa15801561104f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110739190614b40565b101561108657611086858585858561108d565b5050505050565b6040517f2c0198cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861690632c0198cc906110e990339030908990899089908990600401614b9e565b5f604051808303815f87803b158015611100575f80fd5b505af1158015611112573d5f803e3d5ffd5b505050505050505050565b611125611e74565b61112e5f61335a565b565b604080518082019091525f808252602082015273ffffffffffffffffffffffffffffffffffffffff8816632c0198cc3330853560208701356111756040890189614bf5565b6040518763ffffffff1660e01b815260040161119696959493929190614b9e565b5f604051808303815f87803b1580156111ad575f80fd5b505af11580156111bf573d5f803e3d5ffd5b505050506111d1888888888888613102565b98975050505050505050565b604080518082019091525f8082526020820152828042111561122b576040517f203d82d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611236868685611fab565b9695505050505050565b5f8080807353000000000000000000000000000000000000046112666020870187614908565b73ffffffffffffffffffffffffffffffffffffffff16141580611287575034155b156112c3576112a861129c6020870187614908565b308760a001355f612a18565b6112c36112b86020870187614908565b888760a00135612d75565b7353000000000000000000000000000000000000046112e86040870160208801614908565b73ffffffffffffffffffffffffffffffffffffffff16141580611309575034155b1561134b5761132d6113216040870160208801614908565b308760c001355f612a18565b61134b6113406040870160208801614908565b888760c00135612d75565b6040517fb5007d1f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169063b5007d1f90349061139f908990600401614c67565b60806040518083038185885af11580156113bb573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113e09190614d9a565b929650909450925090506114006113fa6020870187614908565b33612e64565b6114136113fa6040870160208801614908565b61141c866133ce565b93509350935093565b6040517f13b8683f0000000000000000000000000000000000000000000000000000000081525f9073ffffffffffffffffffffffffffffffffffffffff8516906313b8683f9061147b9086908690600401614dd3565b6020604051808303815f875af1158015611497573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114bb9190614de6565b949350505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611553573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115779190614b40565b101561158b5761158b868686868686610b86565b505050505050565b60608167ffffffffffffffff8111156115ae576115ae613897565b6040519080825280602002602001820160405280156115e157816020015b60608152602001906001900390816115cc5790505b5090505f5b828110156116f6575f803086868581811061160357611603614ac2565b90506020028101906116159190614bf5565b604051611623929190614e01565b5f60405180830381855af49150503d805f811461165b576040519150601f19603f3d011682016040523d82523d5f602084013e611660565b606091505b5091509150816116ce57604481511015611678575f80fd5b600481019050808060200190518101906116929190614e10565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c59190614e85565b60405180910390fd5b808484815181106116e1576116e1614ac2565b602090810291909101015250506001016115e6565b5092915050565b60606117748a8a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284375f920191909152508b92508a91508990506126cf565b9a9950505050505050505050565b61178a611e74565b73ffffffffffffffffffffffffffffffffffffffff8216158015906117db57508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f496e76616c696420746f0000000000000000000000000000000000000000000060448201526064016116c5565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156118ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118cf9190614b40565b9050815f036118e8576118e3848483613499565b61195d565b80821115611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f457863656564732062616c616e6365000000000000000000000000000000000060448201526064016116c5565b61195d848484613499565b50505050565b80516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905290918291829182915f5b82811015611a90578781815181106119b9576119b9614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015611a6f575f80fd5b505af1158015611a81573d5f803e3d5ffd5b5050505080600101905061199f565b50611a9c8a8a8a611240565b929d919c509a509098509650505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611b20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b449190614b40565b101561158b5761158b868686868686611c2d565b5f611b6b8b8b8b8b8b8b8b8b8b8b611da1565b90506117748b6133ce565b611b7e611e74565b73ffffffffffffffffffffffffffffffffffffffff8116611c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016116c5565b611c2a8161335a565b50565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610c07565b611cb5848484613286565b6040517f294091cd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260248201849052828116604483015285169063294091cd90606401610fac565b5f841380611d2557505f83135b611d2d575f80fd5b5f80611d3b8385018561386d565b909250905061158b73ffffffffffffffffffffffffffffffffffffffff831615611d655782611d7b565b7353000000000000000000000000000000000000045b3383613499565b5f611d968c8c8c8c8c8c8c8c8c8c8c610987565b90506109788c6133ce565b5f611db38b8b8b8b8b8b8b8b8b6128c0565b905073ffffffffffffffffffffffffffffffffffffffff821615611774575f611dde888a018a614908565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff808316602483015291925090841690637acb7757906044015f604051808303815f87803b158015611e4f575f80fd5b505af1158015611e61573d5f803e3d5ffd5b50505050509a9950505050505050505050565b33611e935f5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461112e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016116c5565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f8114611f66576040519150601f19603f3d011682016040523d82523d5f602084013e611f6b565b606091505b5050905080611fa6576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6040805180820182525f80825260208083018290528651845160608082018752808252818401859052818701859052865161012081018852858152808501829052808801869052808201829052608080820187905260a0820187905260c0820187905260e082018790526101008201879052885190810189529788018681529188018690529087529286019390935292935f5b848110156125825788818151811061205857612058614ac2565b60200260200101519350835f01515f8151811061207757612077614ac2565b602002602001015192505f73ffffffffffffffffffffffffffffffffffffffff168360e0015173ffffffffffffffffffffffffffffffffffffffff16036120d8576120d38460200151845f015186604001518660800151612a18565b612125565b6120f084602001513086604001518660800151612a18565b60408051808201825260208087015173ffffffffffffffffffffffffffffffffffffffff168252918601519181019190915282525b83515161213490600190614ec4565b60208301525f5b60e084015173ffffffffffffffffffffffffffffffffffffffff166121ee57835f015173ffffffffffffffffffffffffffffffffffffffff16637132bb7f856020015133876040015188606001516040518563ffffffff1660e01b81526004016121a89493929190614ed7565b60408051808303815f875af11580156121c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e79190614f8c565b835261238a565b825180516020918201516040515f9361222a9392910173ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405160208183030381529060405290505f80865f015173ffffffffffffffffffffffffffffffffffffffff1663078981648860e001518960c00151895f0151602001518b610100015173ffffffffffffffffffffffffffffffffffffffff165f1461229b578b61010001516122c5565b8b60c001516122be5773fffd8963efd1fc6a506488495d951d5263988d256122c5565b6401000276a45b88338e604001518f606001516040518963ffffffff1660e01b81526004016122f4989796959493929190614fa6565b60408051808303815f875af115801561230f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612333919061504a565b9150915060405180604001604052808860a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c00151612379576123748461506c565b612382565b6123828361506c565b905286525050505b826020015181106123d05782515173ffffffffffffffffffffffffffffffffffffffff168752825160209081015190880180516123c89083906150a2565b905250612579565b608084015185518051600190930192839081106123ef576123ef614ac2565b6020026020010151945080158015612408575084608001515b15612573578351516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612479573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061249d9190614b40565b8551519091506124c290737160570bb153edd0ea1775ec2b2ac9b65f1ab61b83613499565b84515186516040517ff9609f0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f08906044016020604051808303815f875af115801561254c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125709190614b40565b50505b5061213b565b5060010161203e565b5086856020015110156125c1576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8616156126c4576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273530000000000000000000000000000000000000490632e1a7d4d9082906370a0823190602401602060405180830381865afa15801561264b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061266f9190614b40565b6040518263ffffffff1660e01b815260040161268d91815260200190565b5f604051808303815f87803b1580156126a4575f80fd5b505af11580156126b6573d5f803e3d5ffd5b505050506126c48647611f10565b505050509392505050565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff881660248201819052604482018890526060916323b872dd906064016020604051808303815f875af1158015612748573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061276c91906150b5565b506040517ff66eab5b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89169063f66eab5b906127c790899033908990899089906004016150d0565b5f604051808303815f875af11580156127e2573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612827919081019061512d565b80519091505f5b818110156128b3575f83828151811061284957612849614ac2565b6020026020010151905087828151811061286557612865614ac2565b6020026020010151816020015110156128aa576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161282e565b5050979650505050505050565b604080516060810182525f8082526020820181905291810182905288905f5b82811015612930578b8b828181106128f9576128f9614ac2565b90506060020180360381019061290f91906151be565b9150612928825f01518e84602001518560400151612a18565b6001016128df565b506040517f03e7286a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d16906303e7286a9061298d908c908c9033908c908c908c90600401615209565b6020604051808303815f875af11580156129a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129cd9190614b40565b925086831015612a09576040517f249942be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509998505050505050505050565b8015612bf35773ffffffffffffffffffffffffffffffffffffffff84161580612a75575073ffffffffffffffffffffffffffffffffffffffff8416735300000000000000000000000000000000000004148015612a755750814710155b15612b2a576040517ff9609f080000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff84166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f0890849060440160206040518083038185885af1158015612aff573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612b249190614b40565b5061195d565b612b4a8433737160570bb153edd0ea1775ec2b2ac9b65f1ab61b856135d2565b6040517ff9609f0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808616600483015284166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f08906044016020604051808303815f875af1158015612bcf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b249190614b40565b73ffffffffffffffffffffffffffffffffffffffff84161580612c4a575073ffffffffffffffffffffffffffffffffffffffff8416735300000000000000000000000000000000000004148015612c4a5750814710155b15612d695773530000000000000000000000000000000000000473ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004015f604051808303818588803b158015612ca9575f80fd5b505af1158015612cbb573d5f803e3d5ffd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8716600482015260248101869052735300000000000000000000000000000000000004935063a9059cbb925060440190506020604051808303815f875af1158015612d45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b2491906150b5565b61195d843385856135d2565b73ffffffffffffffffffffffffffffffffffffffff831615611fa6576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282919085169063dd62ed3e90604401602060405180830381865afa158015612e04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e289190614b40565b1015611fa657612e3983835f613713565b611fa683837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613713565b73ffffffffffffffffffffffffffffffffffffffff82161580612eb0575073ffffffffffffffffffffffffffffffffffffffff8216735300000000000000000000000000000000000004145b15612fd3576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f90735300000000000000000000000000000000000004906370a0823190602401602060405180830381865afa158015612f1d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f419190614b40565b90508015612fc3576040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905273530000000000000000000000000000000000000490632e1a7d4d906024015f604051808303815f87803b158015612fac575f80fd5b505af1158015612fbe573d5f803e3d5ffd5b505050505b4715611fa657611fa68247611f10565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa15801561303d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130619190614b40565b90508015611fa6576040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152611fa6908490849073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156130d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130fd9190614b40565b613499565b6040805180820182525f808252602082015290517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff88166024820181905260448201889052906323b872dd906064016020604051808303815f875af115801561318a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131ae91906150b5565b506040517f27b0bcea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816906327b0bcea90613207908890339088908890600401614ed7565b60408051808303815f875af1158015613222573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132469190614f8c565b90508381602001511015611236576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613292823330846135d2565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff848116602483015282919084169063dd62ed3e90604401602060405180830381865afa158015613305573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133299190614b40565b1015611fa657611fa682847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613713565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81165f90815260016020908152604080832033845290915290205460ff16611c2a5773ffffffffffffffffffffffffffffffffffffffff165f818152600160208181526040808420338552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790556002825283208054928301815583529091200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291515f9283929087169161352f9190615274565b5f604051808303815f865af19150503d805f8114613568576040519150601f19603f3d011682016040523d82523d5f602084013e61356d565b606091505b509150915081158061359b575080511580159061359b57508080602001905181019061359991906150b5565b155b15611086576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f928392908816916136709190615274565b5f604051808303815f865af19150503d805f81146136a9576040519150601f19603f3d011682016040523d82523d5f602084013e6136ae565b606091505b50915091508115806136dc57508051158015906136dc5750808060200190518101906136da91906150b5565b155b1561158b576040517f7939f42400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291515f928392908716916137a99190615274565b5f604051808303815f865af19150503d805f81146137e2576040519150601f19603f3d011682016040523d82523d5f602084013e6137e7565b606091505b5091509150811580613815575080511580159061381557508080602001905181019061381391906150b5565b155b15611086576040517f3e3f8f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611c2a575f80fd5b5f806040838503121561387e575f80fd5b82356138898161384c565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156138e7576138e7613897565b60405290565b604051610120810167ffffffffffffffff811182821017156138e7576138e7613897565b60405160c0810167ffffffffffffffff811182821017156138e7576138e7613897565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561397b5761397b613897565b604052919050565b5f67ffffffffffffffff82111561399c5761399c613897565b5060051b60200190565b80356139b18161384c565b919050565b5f67ffffffffffffffff8211156139cf576139cf613897565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f82601f830112613a0a575f80fd5b8135613a1d613a18826139b6565b613934565b818152846020838601011115613a31575f80fd5b816020850160208301375f918101602001919091529392505050565b8015158114611c2a575f80fd5b80356139b181613a4d565b5f82601f830112613a74575f80fd5b613a81613a188335613983565b82358082526020808301929160051b850101851015613a9e575f80fd5b602084015b6020853560051b860101811015613ce15767ffffffffffffffff81351115613ac9575f80fd5b8035850160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828903011215613afe575f80fd5b613b066138c4565b67ffffffffffffffff60208301351115613b1e575f80fd5b60208083013583010188601f820112613b35575f80fd5b613b42613a188235613983565b81358082526020808301929160051b8401018b1015613b5f575f80fd5b602083015b6020843560051b850101811015613cae5767ffffffffffffffff81351115613b8a575f80fd5b803584016101207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828f03011215613bc0575f80fd5b613bc86138ed565b613bd4602083016139a6565b815267ffffffffffffffff60408301351115613bee575f80fd5b613c018e602060408501358501016139fb565b6020820152613c12606083016139a6565b604082015267ffffffffffffffff60808301351115613c2f575f80fd5b613c428e602060808501358501016139fb565b6060820152613c5360a08301613a5a565b6080820152613c6460c083016139a6565b60a0820152613c7560e08301613a5a565b60c0820152613c8761010083016139a6565b60e0820152613c9961012083016139a6565b61010082015284525060209283019201613b64565b50835250613cc09050604083016139a6565b60208281019190915260609290920135604082015284529283019201613aa3565b50949350505050565b5f60c08284031215613cfa575f80fd5b50919050565b5f805f805f6101408688031215613d15575f80fd5b853567ffffffffffffffff811115613d2b575f80fd5b613d3788828901613a65565b9550506020860135935060408601359250613d558760608801613cea565b9150610120860135613d668161384c565b809150509295509295909350565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081015b92915050565b5f8083601f840112613db3575f80fd5b50813567ffffffffffffffff811115613dca575f80fd5b602083019150836020828501011115613de1575f80fd5b9250929050565b5f8083601f840112613df8575f80fd5b50813567ffffffffffffffff811115613e0f575f80fd5b6020830191508360208260051b8501011115613de1575f80fd5b5f60608284031215613e39575f80fd5b613e416138c4565b82358152602080840135908201529050604082013567ffffffffffffffff811115613e6a575f80fd5b613e76848285016139fb565b60408301525092915050565b5f805f805f805f805f8060e08b8d031215613e9b575f80fd5b613ea48b6139a6565b995060208b0135985060408b013567ffffffffffffffff811115613ec6575f80fd5b613ed28d828e01613da3565b90995097505060608b013567ffffffffffffffff811115613ef1575f80fd5b613efd8d828e01613de8565b9097509550613f10905060808c016139a6565b935060a08b013567ffffffffffffffff811115613f2b575f80fd5b613f378d828e01613da3565b90945092505060c08b013567ffffffffffffffff811115613f56575f80fd5b613f628d828e01613e29565b9150509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b81811015613fd657613fc0838551805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b6020939093019260409290920191600101613f8d565b509095945050505050565b5f8083601f840112613ff1575f80fd5b50813567ffffffffffffffff811115614008575f80fd5b602083019150836020606083028501011115613de1575f80fd5b803560ff811681146139b1575f80fd5b5f82601f830112614041575f80fd5b813561404f613a1882613983565b80828252602082019150602060c08402860101925085831115614070575f80fd5b602085015b838110156140ea5760c0818803121561408c575f80fd5b614094613911565b813561409f8161384c565b815260208281013590820152604080830135908201526140c160608301614022565b60608201526080828101359082015260a08083013590820152835260209092019160c001614075565b5095945050505050565b5f805f805f805f805f805f6101008c8e03121561410f575f80fd5b6141188c6139a6565b9a5060208c013567ffffffffffffffff811115614133575f80fd5b61413f8e828f01613fe1565b909b5099505060408c013567ffffffffffffffff81111561415e575f80fd5b61416a8e828f01613da3565b90995097505060608c0135955061418360808d016139a6565b945060a08c013567ffffffffffffffff81111561419e575f80fd5b6141aa8e828f01613da3565b90955093505060c08c013567ffffffffffffffff8111156141c9575f80fd5b6141d58e828f01614032565b9250506141e460e08d016139a6565b90509295989b509295989b9093969950565b5f805f805f8060c0878903121561420b575f80fd5b86356142168161384c565b9550602087013594506040870135935061423260608801614022565b9598949750929560808101359460a0909101359350915050565b5f805f806101208587031215614260575f80fd5b843561426b8161384c565b9350602085013561427b8161384c565b9250604085013561428b8161384c565b915061429a8660608701613cea565b905092959194509250565b5f80604083850312156142b6575f80fd5b82356142c18161384c565b915060208301356142d18161384c565b809150509250929050565b5f805f805f61014086880312156142f1575f80fd5b85356142fc8161384c565b9450602086013561430c8161384c565b9350604086013561431c8161384c565b925061432b8760608801613cea565b915061012086013567ffffffffffffffff811115614347575f80fd5b61435388828901614032565b9150509295509295909350565b5f805f805f8060c08789031215614375575f80fd5b86356143808161384c565b955060208701359450604087013567ffffffffffffffff8111156143a2575f80fd5b6143ae89828a016139fb565b9450506060870135925060808701356143c68161384c565b915060a087013567ffffffffffffffff8111156143e1575f80fd5b6143ed89828a016139fb565b9150509295509295509295565b5f805f806080858703121561440d575f80fd5b84356144188161384c565b935060208501356144288161384c565b925060408501359150606085013561443f8161384c565b939692955090935050565b5f805f805f6080868803121561445e575f80fd5b85356144698161384c565b94506020860135935060408601359250606086013567ffffffffffffffff811115614492575f80fd5b61449e88828901613da3565b969995985093965092949392505050565b5f60608284031215613cfa575f80fd5b5f805f805f805f60e0888a0312156144d5575f80fd5b87356144e08161384c565b965060208801359550604088013567ffffffffffffffff811115614502575f80fd5b61450e8a828b016139fb565b95505060608801359350614524608089016139a6565b925060a088013567ffffffffffffffff81111561453f575f80fd5b61454b8a828b016139fb565b92505060c088013567ffffffffffffffff811115614567575f80fd5b6145738a828b016144af565b91505092959891949750929550565b5f805f8060808587031215614595575f80fd5b843567ffffffffffffffff8111156145ab575f80fd5b6145b787828801613a65565b9450506020850135925060408501359150606085013561443f8161384c565b5f6101808284031215613cfa575f80fd5b5f805f6101c084860312156145fa575f80fd5b83356146058161384c565b925060208401356146158161384c565b915061462485604086016145d6565b90509250925092565b5f805f6040848603121561463f575f80fd5b833561464a8161384c565b9250602084013567ffffffffffffffff811115614665575f80fd5b61467186828701613da3565b9497909650939450505050565b5f806020838503121561468f575f80fd5b823567ffffffffffffffff8111156146a5575f80fd5b6146b185828601613de8565b90969095509350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561477e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08786030184526147698583516146bd565b9450602093840193919091019060010161472f565b50929695505050505050565b5f805f805f805f805f60c08a8c0312156147a2575f80fd5b89356147ad8161384c565b985060208a0135975060408a013567ffffffffffffffff8111156147cf575f80fd5b6147db8c828d01613da3565b90985096505060608a013567ffffffffffffffff8111156147fa575f80fd5b6148068c828d01613de8565b90965094505060808a013561481a8161384c565b925060a08a013567ffffffffffffffff811115614835575f80fd5b6148418c828d01613da3565b915080935050809150509295985092959850929598565b5f805f6060848603121561486a575f80fd5b83356148758161384c565b925060208401356148858161384c565b929592945050506040919091013590565b5f805f806101e085870312156148aa575f80fd5b84356148b58161384c565b935060208501356148c58161384c565b92506148d486604087016145d6565b91506101c085013567ffffffffffffffff8111156148f0575f80fd5b6148fc87828801614032565b91505092959194509250565b5f60208284031215614918575f80fd5b81356149238161384c565b9392505050565b5f805f805f805f805f8060e08b8d031215614943575f80fd5b8a3561494e8161384c565b995060208b013567ffffffffffffffff811115614969575f80fd5b6149758d828e01613fe1565b909a5098505060408b013567ffffffffffffffff811115614994575f80fd5b6149a08d828e01613da3565b90985096505060608b013594506149b960808c016139a6565b935060a08b013567ffffffffffffffff8111156149d4575f80fd5b6149e08d828e01613da3565b90945092506149f3905060c08c016139a6565b90509295989b9194979a5092959850565b5f805f8060608587031215614a17575f80fd5b8435935060208501359250604085013567ffffffffffffffff811115614a3b575f80fd5b614a4787828801613da3565b95989497509550505050565b5f60208284031215614a63575f80fd5b61492382614022565b73ffffffffffffffffffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff8516602082015283604082015282606082015260a060808201525f61082360a08301846146bd565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516fffffffffffffffffffffffffffffffff811681146139b1575f80fd5b5f805f60608486031215614b20575f80fd5b614b2984614aef565b602085015160409095015190969495509392505050565b5f60208284031215614b50575f80fd5b5051919050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff8616602082015284604082015283606082015260a060808201525f6111d160a083018486614b57565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614c28575f80fd5b83018035915067ffffffffffffffff821115614c42575f80fd5b602001915036819003821315613de1575f80fd5b8035600281900b81146139b1575f80fd5b6101808101614c9382614c79856139a6565b73ffffffffffffffffffffffffffffffffffffffff169052565b614c9f602084016139a6565b73ffffffffffffffffffffffffffffffffffffffff166020830152614cc660408401614c56565b614cd5604084018260020b9052565b50614ce260608401614c56565b614cf1606084018260020b9052565b50614cfe60808401614c56565b614d0d608084018260020b9052565b5060a0838101359083015260c0808401359083015260e080840135908301526101008084013590830152614d4461012084016139a6565b73ffffffffffffffffffffffffffffffffffffffff166101208301526101408381013590830152614d7861016084016139a6565b73ffffffffffffffffffffffffffffffffffffffff81166101608401526116f6565b5f805f8060808587031215614dad575f80fd5b84519350614dbd60208601614aef565b6040860151606090960151949790965092505050565b602081525f6114bb602083018486614b57565b5f60208284031215614df6575f80fd5b81516149238161384c565b818382375f9101908152919050565b5f60208284031215614e20575f80fd5b815167ffffffffffffffff811115614e36575f80fd5b8201601f81018413614e46575f80fd5b8051614e54613a18826139b6565b818152856020838501011115614e68575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b602081525f61492360208301846146bd565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115613d9d57613d9d614e97565b608081525f614ee960808301876146bd565b73ffffffffffffffffffffffffffffffffffffffff8616602084015273ffffffffffffffffffffffffffffffffffffffff85166040840152828103606084015261082381856146bd565b5f60408284031215614f43575f80fd5b6040805190810167ffffffffffffffff81118282101715614f6657614f66613897565b80604052508091508251614f798161384c565b8152602092830151920191909152919050565b5f60408284031215614f9c575f80fd5b6149238383614f33565b73ffffffffffffffffffffffffffffffffffffffff89168152871515602082015286604082015273ffffffffffffffffffffffffffffffffffffffff8616606082015261010060808201525f6150006101008301876146bd565b73ffffffffffffffffffffffffffffffffffffffff861660a084015273ffffffffffffffffffffffffffffffffffffffff851660c084015282810360e084015261097881856146bd565b5f806040838503121561505b575f80fd5b505080516020909101519092909150565b5f7f8000000000000000000000000000000000000000000000000000000000000000820361509c5761509c614e97565b505f0390565b80820180821115613d9d57613d9d614e97565b5f602082840312156150c5575f80fd5b815161492381613a4d565b608081525f6150e260808301886146bd565b73ffffffffffffffffffffffffffffffffffffffff8716602084015273ffffffffffffffffffffffffffffffffffffffff8616604084015282810360608401526111d1818587614b57565b5f6020828403121561513d575f80fd5b815167ffffffffffffffff811115615153575f80fd5b8201601f81018413615163575f80fd5b8051615171613a1882613983565b8082825260208201915060208360061b850101925086831115615192575f80fd5b6020840193505b82841015611236576151ab8785614f33565b8252602082019150604084019350615199565b5f60608284031280156151cf575f80fd5b506151d86138c4565b82356151e38161384c565b81526020838101359082015260408301356151fd81613a4d565b60408201529392505050565b608081525f61521c60808301888a614b57565b73ffffffffffffffffffffffffffffffffffffffff8716602084015273ffffffffffffffffffffffffffffffffffffffff861660408401528281036060840152615267818587614b57565b9998505050505050505050565b5f82518060208501845e5f92019182525091905056fea2646970667358221220f4d732f610e8f230a2bc90c91cfdeabcdd828565752199e1013b215972a6409064736f6c634300081a0033

Deployed Bytecode

0x60806040526004361061022c575f3560e01c80638eb8287111610131578063eb1432f0116100ac578063f44e537a1161007c578063fb68908811610062578063fb6890881461066e578063fbfa77cf14610681578063fc31d54a146106a8575f80fd5b8063f44e537a14610630578063fa461e331461064f575f80fd5b8063eb1432f0146105c4578063f2428621146105d7578063f2fde38b146105fe578063f3995c671461061d575f80fd5b8063ad271fa311610101578063b6541ffe116100e7578063b6541ffe1461055d578063b956b3fb14610570578063c2e3140a146105b1575f80fd5b8063ad271fa31461051f578063b2118a8d1461053e575f80fd5b80638eb82871146104955780639dd41df2146104d9578063a4a78f0c146104ec578063ac9650d8146104ff575f80fd5b8063523acafa116101c15780636cc781cd116101915780637d10c9d6116101775780637d10c9d61461043a5780638aa74f71146104595780638da5cb5b1461046c575f80fd5b80636cc781cd14610413578063715018a614610426575f80fd5b8063523acafa146103af57806353c43f15146103c25780636291027c146103e1578063688ee44c14610400575f80fd5b806339be5126116101fc57806339be5126146102f15780634659a4941461031257806346e8f38f146103255780634f25b85814610366575f80fd5b8063099a04e5146102375780630ae6a646146102585780632b4abadb14610281578063353766c6146102c5575f80fd5b3661023357005b5f80fd5b348015610242575f80fd5b5061025661025136600461386d565b6106bb565b005b61026b610266366004613d00565b6106db565b6040516102789190613d74565b60405180910390f35b34801561028c575f80fd5b506102a061029b36600461386d565b61082e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610278565b3480156102d0575f80fd5b506102e46102df366004613e82565b61086f565b6040516102789190613f74565b6103046102ff3660046140f4565b610987565b604051908152602001610278565b6102566103203660046141f6565b610b86565b61033861033336600461424c565b610c3c565b604080516fffffffffffffffffffffffffffffffff9094168452602084019290925290820152606001610278565b348015610371575f80fd5b5061039f6103803660046142a5565b600160209081525f928352604080842090915290825290205460ff1681565b6040519015158152602001610278565b6103386103bd3660046142dc565b610ddd565b3480156103cd575f80fd5b5061026b6103dc366004614360565b610f29565b3480156103ec575f80fd5b506102566103fb3660046143fa565b610f4a565b61025661040e36600461444a565b610fdf565b61025661042136600461444a565b61108d565b348015610431575f80fd5b5061025661111d565b348015610445575f80fd5b5061026b6104543660046144bf565b611130565b61026b610467366004614582565b6111dd565b348015610477575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166102a0565b6104a86104a33660046145e7565b611240565b604080519485526fffffffffffffffffffffffffffffffff9093166020850152918301526060820152608001610278565b6102a06104e736600461462d565b611425565b6102566104fa3660046141f6565b6114c3565b61051261050d36600461467e565b611593565b6040516102789190614709565b34801561052a575f80fd5b506102e461053936600461478a565b6116fd565b348015610549575f80fd5b50610256610558366004614858565b611782565b6104a861056b366004614896565b611963565b34801561057b575f80fd5b5061030461058a366004614908565b73ffffffffffffffffffffffffffffffffffffffff165f9081526002602052604090205490565b6102566105bf3660046141f6565b611ab0565b6103046105d236600461492a565b611b58565b3480156105e2575f80fd5b506102a073530000000000000000000000000000000000000481565b348015610609575f80fd5b50610256610618366004614908565b611b76565b61025661062b3660046141f6565b611c2d565b34801561063b575f80fd5b5061025661064a3660046143fa565b611caa565b34801561065a575f80fd5b50610256610669366004614a04565b611d18565b61030461067c3660046140f4565b611d82565b34801561068c575f80fd5b506102a0737160570bb153edd0ea1775ec2b2ac9b65f1ab61b81565b6103046106b636600461492a565b611da1565b6106c3611e74565b805f036106cd5750475b6106d78282611f10565b5050565b604080518082019091525f80825260208201528380421115610729576040517f203d82d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107366020850185614908565b73ffffffffffffffffffffffffffffffffffffffff1663d505accf33306020880135604089013561076d60808b0160608c01614a53565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff95861660048201529490931660248501526044840191909152606483015260ff166084820152608087013560a482015260a087013560c482015260e4015f604051808303815f87803b158015610802575f80fd5b505af1158015610814573d5f803e3d5ffd5b50505050610823878785611fab565b979650505050505050565b6002602052815f5260405f208181548110610847575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b8051602082015160408084015190517f2c0198cc00000000000000000000000000000000000000000000000000000000815260609373ffffffffffffffffffffffffffffffffffffffff8f1693632c0198cc936108d6933393309390929091600401614a6c565b5f604051808303815f87803b1580156108ed575f80fd5b505af11580156108ff573d5f803e3d5ffd5b505050506109788b8b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284375f920191909152508c92508b91508a90506126cf565b9b9a5050505050505050505050565b81516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a081018290529091905f5b82811015610aaf578581815181106109d8576109d8614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015610a8e575f80fd5b505af1158015610aa0573d5f803e3d5ffd5b505050508060010190506109be565b50610ac18e8e8e8e8e8e8e8e8e6128c0565b925073ffffffffffffffffffffffffffffffffffffffff841615610b75575f610aec8b8d018d614908565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810186905273ffffffffffffffffffffffffffffffffffffffff808316602483015291925090861690637acb7757906044015f604051808303815f87803b158015610b5d575f80fd5b505af1158015610b6f573d5f803e3d5ffd5b50505050505b50509b9a5050505050505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b5f604051808303815f87803b158015610c1e575f80fd5b505af1158015610c30573d5f803e3d5ffd5b50505050505050505050565b5f808073ffffffffffffffffffffffffffffffffffffffff8616735300000000000000000000000000000000000004141580610c76575034155b15610c9a57610c8b863086602001355f612a18565b610c9a86888660200135612d75565b73ffffffffffffffffffffffffffffffffffffffff8516735300000000000000000000000000000000000004141580610cd1575034155b15610cf557610ce6853086604001355f612a18565b610cf585888660400135612d75565b604080517f219f5d170000000000000000000000000000000000000000000000000000000081528535600482015260208601356024820152908501356044820152606085013560648201526080850135608482015260a085013560a482015273ffffffffffffffffffffffffffffffffffffffff88169063219f5d1790349060c40160606040518083038185885af1158015610d93573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610db89190614b0e565b91945092509050610dc98633612e64565b610dd38533612e64565b9450945094915050565b80516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052909182918291905f5b82811015610f0957868181518110610e3257610e32614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015610ee8575f80fd5b505af1158015610efa573d5f803e3d5ffd5b50505050806001019050610e18565b50610f168a8a8a8a610c3c565b919c909b50909950975050505050505050565b604080518082019091525f8082526020820152610823878787878787613102565b610f55848484613286565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8281166024830152851690637acb7757906044015b5f604051808303815f87803b158015610fc3575f80fd5b505af1158015610fd5573d5f803e3d5ffd5b5050505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152849073ffffffffffffffffffffffffffffffffffffffff87169063dd62ed3e90604401602060405180830381865afa15801561104f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110739190614b40565b101561108657611086858585858561108d565b5050505050565b6040517f2c0198cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861690632c0198cc906110e990339030908990899089908990600401614b9e565b5f604051808303815f87803b158015611100575f80fd5b505af1158015611112573d5f803e3d5ffd5b505050505050505050565b611125611e74565b61112e5f61335a565b565b604080518082019091525f808252602082015273ffffffffffffffffffffffffffffffffffffffff8816632c0198cc3330853560208701356111756040890189614bf5565b6040518763ffffffff1660e01b815260040161119696959493929190614b9e565b5f604051808303815f87803b1580156111ad575f80fd5b505af11580156111bf573d5f803e3d5ffd5b505050506111d1888888888888613102565b98975050505050505050565b604080518082019091525f8082526020820152828042111561122b576040517f203d82d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611236868685611fab565b9695505050505050565b5f8080807353000000000000000000000000000000000000046112666020870187614908565b73ffffffffffffffffffffffffffffffffffffffff16141580611287575034155b156112c3576112a861129c6020870187614908565b308760a001355f612a18565b6112c36112b86020870187614908565b888760a00135612d75565b7353000000000000000000000000000000000000046112e86040870160208801614908565b73ffffffffffffffffffffffffffffffffffffffff16141580611309575034155b1561134b5761132d6113216040870160208801614908565b308760c001355f612a18565b61134b6113406040870160208801614908565b888760c00135612d75565b6040517fb5007d1f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169063b5007d1f90349061139f908990600401614c67565b60806040518083038185885af11580156113bb573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113e09190614d9a565b929650909450925090506114006113fa6020870187614908565b33612e64565b6114136113fa6040870160208801614908565b61141c866133ce565b93509350935093565b6040517f13b8683f0000000000000000000000000000000000000000000000000000000081525f9073ffffffffffffffffffffffffffffffffffffffff8516906313b8683f9061147b9086908690600401614dd3565b6020604051808303815f875af1158015611497573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114bb9190614de6565b949350505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611553573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115779190614b40565b101561158b5761158b868686868686610b86565b505050505050565b60608167ffffffffffffffff8111156115ae576115ae613897565b6040519080825280602002602001820160405280156115e157816020015b60608152602001906001900390816115cc5790505b5090505f5b828110156116f6575f803086868581811061160357611603614ac2565b90506020028101906116159190614bf5565b604051611623929190614e01565b5f60405180830381855af49150503d805f811461165b576040519150601f19603f3d011682016040523d82523d5f602084013e611660565b606091505b5091509150816116ce57604481511015611678575f80fd5b600481019050808060200190518101906116929190614e10565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c59190614e85565b60405180910390fd5b808484815181106116e1576116e1614ac2565b602090810291909101015250506001016115e6565b5092915050565b60606117748a8a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284375f920191909152508b92508a91508990506126cf565b9a9950505050505050505050565b61178a611e74565b73ffffffffffffffffffffffffffffffffffffffff8216158015906117db57508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f496e76616c696420746f0000000000000000000000000000000000000000000060448201526064016116c5565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156118ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118cf9190614b40565b9050815f036118e8576118e3848483613499565b61195d565b80821115611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f457863656564732062616c616e6365000000000000000000000000000000000060448201526064016116c5565b61195d848484613499565b50505050565b80516040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905290918291829182915f5b82811015611a90578781815181106119b9576119b9614ac2565b6020908102919091018101518051918101516040808301516060840151608085015160a086015193517fd505accf0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810195909552606485019290925260ff16608484015260a483015260c482015290935073ffffffffffffffffffffffffffffffffffffffff9091169063d505accf9060e4015f604051808303815f87803b158015611a6f575f80fd5b505af1158015611a81573d5f803e3d5ffd5b5050505080600101905061199f565b50611a9c8a8a8a611240565b929d919c509a509098509650505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611b20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b449190614b40565b101561158b5761158b868686868686611c2d565b5f611b6b8b8b8b8b8b8b8b8b8b8b611da1565b90506117748b6133ce565b611b7e611e74565b73ffffffffffffffffffffffffffffffffffffffff8116611c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016116c5565b611c2a8161335a565b50565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610c07565b611cb5848484613286565b6040517f294091cd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260248201849052828116604483015285169063294091cd90606401610fac565b5f841380611d2557505f83135b611d2d575f80fd5b5f80611d3b8385018561386d565b909250905061158b73ffffffffffffffffffffffffffffffffffffffff831615611d655782611d7b565b7353000000000000000000000000000000000000045b3383613499565b5f611d968c8c8c8c8c8c8c8c8c8c8c610987565b90506109788c6133ce565b5f611db38b8b8b8b8b8b8b8b8b6128c0565b905073ffffffffffffffffffffffffffffffffffffffff821615611774575f611dde888a018a614908565b6040517f7acb77570000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff808316602483015291925090841690637acb7757906044015f604051808303815f87803b158015611e4f575f80fd5b505af1158015611e61573d5f803e3d5ffd5b50505050509a9950505050505050505050565b33611e935f5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461112e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016116c5565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f8114611f66576040519150601f19603f3d011682016040523d82523d5f602084013e611f6b565b606091505b5050905080611fa6576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6040805180820182525f80825260208083018290528651845160608082018752808252818401859052818701859052865161012081018852858152808501829052808801869052808201829052608080820187905260a0820187905260c0820187905260e082018790526101008201879052885190810189529788018681529188018690529087529286019390935292935f5b848110156125825788818151811061205857612058614ac2565b60200260200101519350835f01515f8151811061207757612077614ac2565b602002602001015192505f73ffffffffffffffffffffffffffffffffffffffff168360e0015173ffffffffffffffffffffffffffffffffffffffff16036120d8576120d38460200151845f015186604001518660800151612a18565b612125565b6120f084602001513086604001518660800151612a18565b60408051808201825260208087015173ffffffffffffffffffffffffffffffffffffffff168252918601519181019190915282525b83515161213490600190614ec4565b60208301525f5b60e084015173ffffffffffffffffffffffffffffffffffffffff166121ee57835f015173ffffffffffffffffffffffffffffffffffffffff16637132bb7f856020015133876040015188606001516040518563ffffffff1660e01b81526004016121a89493929190614ed7565b60408051808303815f875af11580156121c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e79190614f8c565b835261238a565b825180516020918201516040515f9361222a9392910173ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405160208183030381529060405290505f80865f015173ffffffffffffffffffffffffffffffffffffffff1663078981648860e001518960c00151895f0151602001518b610100015173ffffffffffffffffffffffffffffffffffffffff165f1461229b578b61010001516122c5565b8b60c001516122be5773fffd8963efd1fc6a506488495d951d5263988d256122c5565b6401000276a45b88338e604001518f606001516040518963ffffffff1660e01b81526004016122f4989796959493929190614fa6565b60408051808303815f875af115801561230f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612333919061504a565b9150915060405180604001604052808860a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c00151612379576123748461506c565b612382565b6123828361506c565b905286525050505b826020015181106123d05782515173ffffffffffffffffffffffffffffffffffffffff168752825160209081015190880180516123c89083906150a2565b905250612579565b608084015185518051600190930192839081106123ef576123ef614ac2565b6020026020010151945080158015612408575084608001515b15612573578351516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612479573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061249d9190614b40565b8551519091506124c290737160570bb153edd0ea1775ec2b2ac9b65f1ab61b83613499565b84515186516040517ff9609f0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f08906044016020604051808303815f875af115801561254c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125709190614b40565b50505b5061213b565b5060010161203e565b5086856020015110156125c1576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8616156126c4576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273530000000000000000000000000000000000000490632e1a7d4d9082906370a0823190602401602060405180830381865afa15801561264b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061266f9190614b40565b6040518263ffffffff1660e01b815260040161268d91815260200190565b5f604051808303815f87803b1580156126a4575f80fd5b505af11580156126b6573d5f803e3d5ffd5b505050506126c48647611f10565b505050509392505050565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff881660248201819052604482018890526060916323b872dd906064016020604051808303815f875af1158015612748573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061276c91906150b5565b506040517ff66eab5b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89169063f66eab5b906127c790899033908990899089906004016150d0565b5f604051808303815f875af11580156127e2573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612827919081019061512d565b80519091505f5b818110156128b3575f83828151811061284957612849614ac2565b6020026020010151905087828151811061286557612865614ac2565b6020026020010151816020015110156128aa576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161282e565b5050979650505050505050565b604080516060810182525f8082526020820181905291810182905288905f5b82811015612930578b8b828181106128f9576128f9614ac2565b90506060020180360381019061290f91906151be565b9150612928825f01518e84602001518560400151612a18565b6001016128df565b506040517f03e7286a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d16906303e7286a9061298d908c908c9033908c908c908c90600401615209565b6020604051808303815f875af11580156129a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129cd9190614b40565b925086831015612a09576040517f249942be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509998505050505050505050565b8015612bf35773ffffffffffffffffffffffffffffffffffffffff84161580612a75575073ffffffffffffffffffffffffffffffffffffffff8416735300000000000000000000000000000000000004148015612a755750814710155b15612b2a576040517ff9609f080000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff84166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f0890849060440160206040518083038185885af1158015612aff573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612b249190614b40565b5061195d565b612b4a8433737160570bb153edd0ea1775ec2b2ac9b65f1ab61b856135d2565b6040517ff9609f0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808616600483015284166024820152737160570bb153edd0ea1775ec2b2ac9b65f1ab61b9063f9609f08906044016020604051808303815f875af1158015612bcf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b249190614b40565b73ffffffffffffffffffffffffffffffffffffffff84161580612c4a575073ffffffffffffffffffffffffffffffffffffffff8416735300000000000000000000000000000000000004148015612c4a5750814710155b15612d695773530000000000000000000000000000000000000473ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004015f604051808303818588803b158015612ca9575f80fd5b505af1158015612cbb573d5f803e3d5ffd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8716600482015260248101869052735300000000000000000000000000000000000004935063a9059cbb925060440190506020604051808303815f875af1158015612d45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b2491906150b5565b61195d843385856135d2565b73ffffffffffffffffffffffffffffffffffffffff831615611fa6576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282919085169063dd62ed3e90604401602060405180830381865afa158015612e04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e289190614b40565b1015611fa657612e3983835f613713565b611fa683837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613713565b73ffffffffffffffffffffffffffffffffffffffff82161580612eb0575073ffffffffffffffffffffffffffffffffffffffff8216735300000000000000000000000000000000000004145b15612fd3576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f90735300000000000000000000000000000000000004906370a0823190602401602060405180830381865afa158015612f1d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f419190614b40565b90508015612fc3576040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905273530000000000000000000000000000000000000490632e1a7d4d906024015f604051808303815f87803b158015612fac575f80fd5b505af1158015612fbe573d5f803e3d5ffd5b505050505b4715611fa657611fa68247611f10565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa15801561303d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130619190614b40565b90508015611fa6576040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152611fa6908490849073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156130d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130fd9190614b40565b613499565b6040805180820182525f808252602082015290517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff88166024820181905260448201889052906323b872dd906064016020604051808303815f875af115801561318a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131ae91906150b5565b506040517f27b0bcea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816906327b0bcea90613207908890339088908890600401614ed7565b60408051808303815f875af1158015613222573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132469190614f8c565b90508381602001511015611236576040517fc9f52c7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613292823330846135d2565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff848116602483015282919084169063dd62ed3e90604401602060405180830381865afa158015613305573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133299190614b40565b1015611fa657611fa682847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613713565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81165f90815260016020908152604080832033845290915290205460ff16611c2a5773ffffffffffffffffffffffffffffffffffffffff165f818152600160208181526040808420338552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790556002825283208054928301815583529091200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291515f9283929087169161352f9190615274565b5f604051808303815f865af19150503d805f8114613568576040519150601f19603f3d011682016040523d82523d5f602084013e61356d565b606091505b509150915081158061359b575080511580159061359b57508080602001905181019061359991906150b5565b155b15611086576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f928392908816916136709190615274565b5f604051808303815f865af19150503d805f81146136a9576040519150601f19603f3d011682016040523d82523d5f602084013e6136ae565b606091505b50915091508115806136dc57508051158015906136dc5750808060200190518101906136da91906150b5565b155b1561158b576040517f7939f42400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291515f928392908716916137a99190615274565b5f604051808303815f865af19150503d805f81146137e2576040519150601f19603f3d011682016040523d82523d5f602084013e6137e7565b606091505b5091509150811580613815575080511580159061381557508080602001905181019061381391906150b5565b155b15611086576040517f3e3f8f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611c2a575f80fd5b5f806040838503121561387e575f80fd5b82356138898161384c565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156138e7576138e7613897565b60405290565b604051610120810167ffffffffffffffff811182821017156138e7576138e7613897565b60405160c0810167ffffffffffffffff811182821017156138e7576138e7613897565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561397b5761397b613897565b604052919050565b5f67ffffffffffffffff82111561399c5761399c613897565b5060051b60200190565b80356139b18161384c565b919050565b5f67ffffffffffffffff8211156139cf576139cf613897565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f82601f830112613a0a575f80fd5b8135613a1d613a18826139b6565b613934565b818152846020838601011115613a31575f80fd5b816020850160208301375f918101602001919091529392505050565b8015158114611c2a575f80fd5b80356139b181613a4d565b5f82601f830112613a74575f80fd5b613a81613a188335613983565b82358082526020808301929160051b850101851015613a9e575f80fd5b602084015b6020853560051b860101811015613ce15767ffffffffffffffff81351115613ac9575f80fd5b8035850160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828903011215613afe575f80fd5b613b066138c4565b67ffffffffffffffff60208301351115613b1e575f80fd5b60208083013583010188601f820112613b35575f80fd5b613b42613a188235613983565b81358082526020808301929160051b8401018b1015613b5f575f80fd5b602083015b6020843560051b850101811015613cae5767ffffffffffffffff81351115613b8a575f80fd5b803584016101207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828f03011215613bc0575f80fd5b613bc86138ed565b613bd4602083016139a6565b815267ffffffffffffffff60408301351115613bee575f80fd5b613c018e602060408501358501016139fb565b6020820152613c12606083016139a6565b604082015267ffffffffffffffff60808301351115613c2f575f80fd5b613c428e602060808501358501016139fb565b6060820152613c5360a08301613a5a565b6080820152613c6460c083016139a6565b60a0820152613c7560e08301613a5a565b60c0820152613c8761010083016139a6565b60e0820152613c9961012083016139a6565b61010082015284525060209283019201613b64565b50835250613cc09050604083016139a6565b60208281019190915260609290920135604082015284529283019201613aa3565b50949350505050565b5f60c08284031215613cfa575f80fd5b50919050565b5f805f805f6101408688031215613d15575f80fd5b853567ffffffffffffffff811115613d2b575f80fd5b613d3788828901613a65565b9550506020860135935060408601359250613d558760608801613cea565b9150610120860135613d668161384c565b809150509295509295909350565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081015b92915050565b5f8083601f840112613db3575f80fd5b50813567ffffffffffffffff811115613dca575f80fd5b602083019150836020828501011115613de1575f80fd5b9250929050565b5f8083601f840112613df8575f80fd5b50813567ffffffffffffffff811115613e0f575f80fd5b6020830191508360208260051b8501011115613de1575f80fd5b5f60608284031215613e39575f80fd5b613e416138c4565b82358152602080840135908201529050604082013567ffffffffffffffff811115613e6a575f80fd5b613e76848285016139fb565b60408301525092915050565b5f805f805f805f805f8060e08b8d031215613e9b575f80fd5b613ea48b6139a6565b995060208b0135985060408b013567ffffffffffffffff811115613ec6575f80fd5b613ed28d828e01613da3565b90995097505060608b013567ffffffffffffffff811115613ef1575f80fd5b613efd8d828e01613de8565b9097509550613f10905060808c016139a6565b935060a08b013567ffffffffffffffff811115613f2b575f80fd5b613f378d828e01613da3565b90945092505060c08b013567ffffffffffffffff811115613f56575f80fd5b613f628d828e01613e29565b9150509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b81811015613fd657613fc0838551805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b6020939093019260409290920191600101613f8d565b509095945050505050565b5f8083601f840112613ff1575f80fd5b50813567ffffffffffffffff811115614008575f80fd5b602083019150836020606083028501011115613de1575f80fd5b803560ff811681146139b1575f80fd5b5f82601f830112614041575f80fd5b813561404f613a1882613983565b80828252602082019150602060c08402860101925085831115614070575f80fd5b602085015b838110156140ea5760c0818803121561408c575f80fd5b614094613911565b813561409f8161384c565b815260208281013590820152604080830135908201526140c160608301614022565b60608201526080828101359082015260a08083013590820152835260209092019160c001614075565b5095945050505050565b5f805f805f805f805f805f6101008c8e03121561410f575f80fd5b6141188c6139a6565b9a5060208c013567ffffffffffffffff811115614133575f80fd5b61413f8e828f01613fe1565b909b5099505060408c013567ffffffffffffffff81111561415e575f80fd5b61416a8e828f01613da3565b90995097505060608c0135955061418360808d016139a6565b945060a08c013567ffffffffffffffff81111561419e575f80fd5b6141aa8e828f01613da3565b90955093505060c08c013567ffffffffffffffff8111156141c9575f80fd5b6141d58e828f01614032565b9250506141e460e08d016139a6565b90509295989b509295989b9093969950565b5f805f805f8060c0878903121561420b575f80fd5b86356142168161384c565b9550602087013594506040870135935061423260608801614022565b9598949750929560808101359460a0909101359350915050565b5f805f806101208587031215614260575f80fd5b843561426b8161384c565b9350602085013561427b8161384c565b9250604085013561428b8161384c565b915061429a8660608701613cea565b905092959194509250565b5f80604083850312156142b6575f80fd5b82356142c18161384c565b915060208301356142d18161384c565b809150509250929050565b5f805f805f61014086880312156142f1575f80fd5b85356142fc8161384c565b9450602086013561430c8161384c565b9350604086013561431c8161384c565b925061432b8760608801613cea565b915061012086013567ffffffffffffffff811115614347575f80fd5b61435388828901614032565b9150509295509295909350565b5f805f805f8060c08789031215614375575f80fd5b86356143808161384c565b955060208701359450604087013567ffffffffffffffff8111156143a2575f80fd5b6143ae89828a016139fb565b9450506060870135925060808701356143c68161384c565b915060a087013567ffffffffffffffff8111156143e1575f80fd5b6143ed89828a016139fb565b9150509295509295509295565b5f805f806080858703121561440d575f80fd5b84356144188161384c565b935060208501356144288161384c565b925060408501359150606085013561443f8161384c565b939692955090935050565b5f805f805f6080868803121561445e575f80fd5b85356144698161384c565b94506020860135935060408601359250606086013567ffffffffffffffff811115614492575f80fd5b61449e88828901613da3565b969995985093965092949392505050565b5f60608284031215613cfa575f80fd5b5f805f805f805f60e0888a0312156144d5575f80fd5b87356144e08161384c565b965060208801359550604088013567ffffffffffffffff811115614502575f80fd5b61450e8a828b016139fb565b95505060608801359350614524608089016139a6565b925060a088013567ffffffffffffffff81111561453f575f80fd5b61454b8a828b016139fb565b92505060c088013567ffffffffffffffff811115614567575f80fd5b6145738a828b016144af565b91505092959891949750929550565b5f805f8060808587031215614595575f80fd5b843567ffffffffffffffff8111156145ab575f80fd5b6145b787828801613a65565b9450506020850135925060408501359150606085013561443f8161384c565b5f6101808284031215613cfa575f80fd5b5f805f6101c084860312156145fa575f80fd5b83356146058161384c565b925060208401356146158161384c565b915061462485604086016145d6565b90509250925092565b5f805f6040848603121561463f575f80fd5b833561464a8161384c565b9250602084013567ffffffffffffffff811115614665575f80fd5b61467186828701613da3565b9497909650939450505050565b5f806020838503121561468f575f80fd5b823567ffffffffffffffff8111156146a5575f80fd5b6146b185828601613de8565b90969095509350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561477e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08786030184526147698583516146bd565b9450602093840193919091019060010161472f565b50929695505050505050565b5f805f805f805f805f60c08a8c0312156147a2575f80fd5b89356147ad8161384c565b985060208a0135975060408a013567ffffffffffffffff8111156147cf575f80fd5b6147db8c828d01613da3565b90985096505060608a013567ffffffffffffffff8111156147fa575f80fd5b6148068c828d01613de8565b90965094505060808a013561481a8161384c565b925060a08a013567ffffffffffffffff811115614835575f80fd5b6148418c828d01613da3565b915080935050809150509295985092959850929598565b5f805f6060848603121561486a575f80fd5b83356148758161384c565b925060208401356148858161384c565b929592945050506040919091013590565b5f805f806101e085870312156148aa575f80fd5b84356148b58161384c565b935060208501356148c58161384c565b92506148d486604087016145d6565b91506101c085013567ffffffffffffffff8111156148f0575f80fd5b6148fc87828801614032565b91505092959194509250565b5f60208284031215614918575f80fd5b81356149238161384c565b9392505050565b5f805f805f805f805f8060e08b8d031215614943575f80fd5b8a3561494e8161384c565b995060208b013567ffffffffffffffff811115614969575f80fd5b6149758d828e01613fe1565b909a5098505060408b013567ffffffffffffffff811115614994575f80fd5b6149a08d828e01613da3565b90985096505060608b013594506149b960808c016139a6565b935060a08b013567ffffffffffffffff8111156149d4575f80fd5b6149e08d828e01613da3565b90945092506149f3905060c08c016139a6565b90509295989b9194979a5092959850565b5f805f8060608587031215614a17575f80fd5b8435935060208501359250604085013567ffffffffffffffff811115614a3b575f80fd5b614a4787828801613da3565b95989497509550505050565b5f60208284031215614a63575f80fd5b61492382614022565b73ffffffffffffffffffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff8516602082015283604082015282606082015260a060808201525f61082360a08301846146bd565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516fffffffffffffffffffffffffffffffff811681146139b1575f80fd5b5f805f60608486031215614b20575f80fd5b614b2984614aef565b602085015160409095015190969495509392505050565b5f60208284031215614b50575f80fd5b5051919050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff8616602082015284604082015283606082015260a060808201525f6111d160a083018486614b57565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614c28575f80fd5b83018035915067ffffffffffffffff821115614c42575f80fd5b602001915036819003821315613de1575f80fd5b8035600281900b81146139b1575f80fd5b6101808101614c9382614c79856139a6565b73ffffffffffffffffffffffffffffffffffffffff169052565b614c9f602084016139a6565b73ffffffffffffffffffffffffffffffffffffffff166020830152614cc660408401614c56565b614cd5604084018260020b9052565b50614ce260608401614c56565b614cf1606084018260020b9052565b50614cfe60808401614c56565b614d0d608084018260020b9052565b5060a0838101359083015260c0808401359083015260e080840135908301526101008084013590830152614d4461012084016139a6565b73ffffffffffffffffffffffffffffffffffffffff166101208301526101408381013590830152614d7861016084016139a6565b73ffffffffffffffffffffffffffffffffffffffff81166101608401526116f6565b5f805f8060808587031215614dad575f80fd5b84519350614dbd60208601614aef565b6040860151606090960151949790965092505050565b602081525f6114bb602083018486614b57565b5f60208284031215614df6575f80fd5b81516149238161384c565b818382375f9101908152919050565b5f60208284031215614e20575f80fd5b815167ffffffffffffffff811115614e36575f80fd5b8201601f81018413614e46575f80fd5b8051614e54613a18826139b6565b818152856020838501011115614e68575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b602081525f61492360208301846146bd565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115613d9d57613d9d614e97565b608081525f614ee960808301876146bd565b73ffffffffffffffffffffffffffffffffffffffff8616602084015273ffffffffffffffffffffffffffffffffffffffff85166040840152828103606084015261082381856146bd565b5f60408284031215614f43575f80fd5b6040805190810167ffffffffffffffff81118282101715614f6657614f66613897565b80604052508091508251614f798161384c565b8152602092830151920191909152919050565b5f60408284031215614f9c575f80fd5b6149238383614f33565b73ffffffffffffffffffffffffffffffffffffffff89168152871515602082015286604082015273ffffffffffffffffffffffffffffffffffffffff8616606082015261010060808201525f6150006101008301876146bd565b73ffffffffffffffffffffffffffffffffffffffff861660a084015273ffffffffffffffffffffffffffffffffffffffff851660c084015282810360e084015261097881856146bd565b5f806040838503121561505b575f80fd5b505080516020909101519092909150565b5f7f8000000000000000000000000000000000000000000000000000000000000000820361509c5761509c614e97565b505f0390565b80820180821115613d9d57613d9d614e97565b5f602082840312156150c5575f80fd5b815161492381613a4d565b608081525f6150e260808301886146bd565b73ffffffffffffffffffffffffffffffffffffffff8716602084015273ffffffffffffffffffffffffffffffffffffffff8616604084015282810360608401526111d1818587614b57565b5f6020828403121561513d575f80fd5b815167ffffffffffffffff811115615153575f80fd5b8201601f81018413615163575f80fd5b8051615171613a1882613983565b8082825260208201915060208360061b850101925086831115615192575f80fd5b6020840193505b82841015611236576151ab8785614f33565b8252602082019150604084019350615199565b5f60608284031280156151cf575f80fd5b506151d86138c4565b82356151e38161384c565b81526020838101359082015260408301356151fd81613a4d565b60408201529392505050565b608081525f61521c60808301888a614b57565b73ffffffffffffffffffffffffffffffffffffffff8716602084015273ffffffffffffffffffffffffffffffffffffffff861660408401528281036060840152615267818587614b57565b9998505050505050505050565b5f82518060208501845e5f92019182525091905056fea2646970667358221220f4d732f610e8f230a2bc90c91cfdeabcdd828565752199e1013b215972a6409064736f6c634300081a0033

Deployed Bytecode Sourcemap

29819:22988:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5863:219;;;;;;;;;;-1:-1:-1;5863:219:0;;;;;:::i;:::-;;:::i;:::-;;45702:693;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30295:49;;;;;;;;;;-1:-1:-1;30295:49:0;;;;;:::i;:::-;;:::i;:::-;;;8747:42:1;8735:55;;;8717:74;;8705:2;8690:18;30295:49:0;8571:226:1;37263:756:0;;;;;;;;;;-1:-1:-1;37263:756:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;34129:1243::-;;;;;;:::i;:::-;;:::i;:::-;;;16316:25:1;;;16304:2;16289:18;34129:1243:0;16170:177:1;11409:289:0;;;;;;:::i;:::-;;:::i;48509:977::-;;;;;;:::i;:::-;;:::i;:::-;;;;18108:34:1;18096:47;;;18078:66;;18175:2;18160:18;;18153:34;;;;18203:18;;;18196:34;18066:2;18051:18;48509:977:0;17876:360:1;30223:65:0;;;;;;;;;;-1:-1:-1;30223:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18815:14:1;;18808:22;18790:41;;18778:2;18763:18;30223:65:0;18650:187:1;49494:1095:0;;;;;;:::i;:::-;;:::i;38594:463::-;;;;;;;;;;-1:-1:-1;38594:463:0;;;;;:::i;:::-;;:::i;52434:173::-;;;;;;;;;;-1:-1:-1;52434:173:0;;;;;:::i;:::-;;:::i;12333:315::-;;;;;;:::i;:::-;;:::i;12076:249::-;;;;;;:::i;:::-;;:::i;4463:103::-;;;;;;;;;;;;;:::i;39065:755::-;;;;;;;;;;-1:-1:-1;39065:755:0;;;;;:::i;:::-;;:::i;45344:350::-;;;;;;:::i;:::-;;:::i;3824:87::-;;;;;;;;;;-1:-1:-1;3870:7:0;3897:6;;;3824:87;;46403:1038;;;;;;:::i;:::-;;:::i;:::-;;;;25535:25:1;;;25608:34;25596:47;;;25591:2;25576:18;;25569:75;25660:18;;;25653:34;25718:2;25703:18;;25696:34;25522:3;25507:19;46403:1038:0;25304:432:1;51765:159:0;;;;;;:::i;:::-;;:::i;11706:362::-;;;;;;:::i;:::-;;:::i;23783:789::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;36789:466::-;;;;;;;;;;-1:-1:-1;36789:466:0;;;;;:::i;:::-;;:::i;5362:464::-;;;;;;;;;;-1:-1:-1;5362:464:0;;;;;:::i;:::-;;:::i;47449:1052::-;;;;;;:::i;:::-;;:::i;30647:128::-;;;;;;;;;;-1:-1:-1;30647:128:0;;;;;:::i;:::-;30739:21;;30715:4;30739:21;;;:12;:21;;;;;:28;;30647:128;11067:334;;;;;;:::i;:::-;;:::i;33591:530::-;;;;;;:::i;:::-;;:::i;30084:73::-;;;;;;;;;;;;30115:42;30084:73;;4721:201;;;;;;;;;;-1:-1:-1;4721:201:0;;;;;:::i;:::-;;:::i;10792:267::-;;;;;;:::i;:::-;;:::i;52615:189::-;;;;;;;;;;-1:-1:-1;52615:189:0;;;;;:::i;:::-;;:::i;39828:1081::-;;;;;;;;;;-1:-1:-1;39828:1081:0;;;;;:::i;:::-;;:::i;35380:615::-;;;;;;:::i;:::-;;:::i;30003:74::-;;;;;;;;;;;;30035:42;30003:74;;32942:641;;;;;;:::i;:::-;;:::i;5863:219::-;3710:13;:11;:13::i;:::-;5952:6:::1;5962:1;5952:11:::0;5948:74:::1;;-1:-1:-1::0;5989:21:0::1;5948:74;6032:42;6063:2;6067:6;6032:30;:42::i;:::-;5863:219:::0;;:::o;45702:693::-;-1:-1:-1;;;;;;;;;;;;;;;;;45924:8:0;30472;30454:15;:26;30450:75;;;30504:9;;;;;;;;;;;;;;30450:75;46048:12:::1;;::::0;::::1;:6:::0;:12:::1;:::i;:::-;46035:33;;;46083:10;46116:4;46136:20;::::0;::::1;;46171:15;::::0;::::1;;46201:8;::::0;;;::::1;::::0;::::1;;:::i;:::-;46035:231;::::0;;::::1;::::0;;;;;;33713:42:1;33701:55;;;46035:231:0::1;::::0;::::1;33683:74:1::0;33793:55;;;;33773:18;;;33766:83;33865:18;;;33858:34;;;;33908:18;;;33901:34;33984:4;33972:17;33951:19;;;33944:46;46224:8:0::1;::::0;::::1;;34006:19:1::0;;;33999:35;46247:8:0::1;::::0;::::1;;34050:19:1::0;;;34043:35;33655:19;;46035:231:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;46291:96;46311:5;46331:12;46358:18;46291:5;:96::i;:::-;46279:108:::0;45702:693;-1:-1:-1;;;;;;;45702:693:0:o;30295:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30295:49:0;;-1:-1:-1;30295:49:0:o;37263:756::-;37723:20;;37758:15;;;;37788:16;;;;;37632:183;;;;;37543:34;;37632:23;;;;;;:183;;37670:10;;37703:4;;37723:20;;37758:15;;37632:183;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37838:173;37878:4;37897:9;37921:4;;37838:173;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37838:173:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37940:10:0;;-1:-1:-1;37940:10:0;;;;37838:173;;;37940:10;;37838:173;37940:10;37838:173;;;;;;;;;-1:-1:-1;37965:8:0;;-1:-1:-1;37988:12:0;;-1:-1:-1;37988:12:0;;-1:-1:-1;37838:25:0;:173::i;:::-;37828:183;37263:756;-1:-1:-1;;;;;;;;;;;37263:756:0:o;34129:1243::-;34527:14;;-1:-1:-1;;;;;;;;34448:14:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34448:14:0;;34527;34603:6;34598:412;34615:1;34611;:5;34598:412;;;34644:7;34652:1;34644:10;;;;;;;;:::i;:::-;;;;;;;;;;;;34684:12;;34784:20;;;;34823:15;;;;;34857:8;;;;34884;;;;34911;;;;34671:263;;;;;34723:10;34671:263;;;33683:74:1;34760:4:0;33773:18:1;;;33766:83;33865:18;;;33858:34;;;;33908:18;;;33901:34;;;;33984:4;33972:17;33951:19;;;33944:46;34006:19;;;33999:35;34050:19;;;34043:35;34644:10:0;;-1:-1:-1;34671:33:0;;;;;;;33655:19:1;;34671:263:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34980:3;;;;;34598:412;;;;35034:171;35073:4;35092:6;;35113:4;;35132:12;35159:8;35182:12;;35034:24;:171::i;:::-;35022:183;-1:-1:-1;35222:21:0;;;;35218:147;;35260:10;35273:27;;;;35284:4;35273:27;:::i;:::-;35315:38;;;;;;;;35327:25:1;;;35315:23:0;35388:55:1;;;35368:18;;;35361:83;35260:40:0;;-1:-1:-1;35315:23:0;;;;;;35300:18:1;;35315:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35245:120;35218:147;34464:908;;34129:1243;;;;;;;;;;;;;:::o;11409:289::-;11600:90;;;;;11634:10;11600:90;;;35788:74:1;11654:4:0;35878:18:1;;;35871:83;35970:18;;;35963:34;;;36013:18;;;36006:34;;;11676:4:0;36056:19:1;;;36049:51;36149:4;36137:17;;36116:19;;;36109:46;36171:19;;;36164:35;;;36215:19;;;36208:35;;;11600:33:0;;;;;;35760:19:1;;11600:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11409:289;;;;;;:::o;48509:977::-;48724:17;;;48792:14;;;30115:42;48792:14;;;:32;;-1:-1:-1;48810:9:0;:14;48792:32;48788:220;;;48841:72;48861:6;48877:4;48884:6;:21;;;48907:5;48841:19;:72::i;:::-;48928:68;48946:6;48954:18;48974:6;:21;;;48928:17;:68::i;:::-;49024:14;;;30115:42;49024:14;;;:32;;-1:-1:-1;49042:9:0;:14;49024:32;49020:220;;;49073:72;49093:6;49109:4;49116:6;:21;;;49139:5;49073:19;:72::i;:::-;49160:68;49178:6;49186:18;49206:6;:21;;;49160:17;:68::i;:::-;49284:83;;;;;;36517:20:1;;49284:83:0;;;36546:24:1;36640:4;36628:17;;36615:31;36662:20;;;36655:37;36750:17;;;36737:31;36784:20;;;36777:37;36884:4;36872:17;;36859:31;36906:20;;;36899:37;37006:4;36994:17;;36981:31;37028:20;;;37021:37;37128:4;37116:17;;37103:31;37150:20;;;37143:37;49284:57:0;;;;;;49349:9;;36457:19:1;;49284:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49252:115;;-1:-1:-1;49252:115:0;-1:-1:-1;49252:115:0;-1:-1:-1;49399:34:0;49414:6;49422:10;49399:14;:34::i;:::-;49444;49459:6;49467:10;49444:14;:34::i;:::-;48509:977;;;;;;;;:::o;49494:1095::-;49882:14;;-1:-1:-1;;;;;;;;49766:17:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49766:17:0;;;;;;49882:14;49964:6;49959:454;49976:1;49972;:5;49959:454;;;50011:7;50019:1;50011:10;;;;;;;;:::i;:::-;;;;;;;;;;;;50051:18;;50157:26;;;;50202:21;;;;;50242:14;;;;50275;;;;50308;;;;50038:299;;;;;50096:10;50038:299;;;33683:74:1;50133:4:0;33773:18:1;;;33766:83;33865:18;;;33858:34;;;;33908:18;;;33901:34;;;;33984:4;33972:17;33951:19;;;33944:46;34006:19;;;33999:35;34050:19;;;34043:35;50011:10:0;;-1:-1:-1;50038:39:0;;;;;;;33655:19:1;;50038:299:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50383:3;;;;;49959:454;;;;50457:124;50489:18;50522:6;50543;50564;50457:17;:124::i;:::-;50425:156;;;;-1:-1:-1;50425:156:0;;-1:-1:-1;49494:1095:0;-1:-1:-1;;;;;;;;49494:1095:0:o;38594:463::-;-1:-1:-1;;;;;;;;;;;;;;;;;38871:178:0;38917:4;38936:9;38960:4;38979:9;39003:8;39026:12;38871:31;:178::i;52434:173::-;52525:29;52532:6;52540:5;52547:6;52525;:29::i;:::-;52565:34;;;;;;;;35327:25:1;;;52565:22:0;35388:55:1;;;35368:18;;;35361:83;52565:22:0;;;;;35300:18:1;;52565:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52434:173;;;;:::o;12333:315::-;12508:50;;;;;12532:10;12508:50;;;37995:74:1;12552:4:0;38085:18:1;;;38078:83;12561:5:0;;12508:23;;;;;;37968:18:1;;12508:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;12504:137;;;12583:46;12595:5;12602;12609:8;12619:9;;12583:11;:46::i;:::-;12333:315;;;;;:::o;12076:249::-;12234:83;;;;;:28;;;;;;:83;;12263:10;;12283:4;;12290:5;;12297:8;;12307:9;;;;12234:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12076:249;;;;;:::o;4463:103::-;3710:13;:11;:13::i;:::-;4528:30:::1;4555:1;4528:18;:30::i;:::-;4463:103::o:0;39065:755::-;-1:-1:-1;;;;;;;;;;;;;;;;;39426:23:0;;;;39464:10;39497:4;39517:20;;39552:15;;;;39582:16;;;;39517:6;39582:16;:::i;:::-;39426:183;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39634:178;39680:4;39699:9;39723:4;39742:9;39766:8;39789:12;39634:31;:178::i;:::-;39622:190;39065:755;-1:-1:-1;;;;;;;;39065:755:0:o;45344:350::-;-1:-1:-1;;;;;;;;;;;;;;;;;45512:8:0;30472;30454:15;:26;30450:75;;;30504:9;;;;;;;;;;;;;;30450:75;45590:96:::1;45610:5;45630:12;45657:18;45590:5;:96::i;:::-;45578:108:::0;45344:350;-1:-1:-1;;;;;;45344:350:0:o;46403:1038::-;46575:15;;;;30115:42;46660:13;;;;:6;:13;:::i;:::-;:21;;;;:39;;;-1:-1:-1;46685:9:0;:14;46660:39;46656:241;;;46716:79;46736:13;;;;:6;:13;:::i;:::-;46759:4;46766:6;:21;;;46789:5;46716:19;:79::i;:::-;46810:75;46828:13;;;;:6;:13;:::i;:::-;46843:18;46863:6;:21;;;46810:17;:75::i;:::-;30115:42;46913:13;;;;;;;;:::i;:::-;:21;;;;:39;;;-1:-1:-1;46938:9:0;:14;46913:39;46909:241;;;46969:79;46989:13;;;;;;;;:::i;:::-;47012:4;47019:6;:21;;;47042:5;46969:19;:79::i;:::-;47063:75;47081:13;;;;;;;;:::i;:::-;47096:18;47116:6;:21;;;47063:17;:75::i;:::-;47203:70;;;;;:44;;;;;;47255:9;;47203:70;;47266:6;;47203:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47162:111;;-1:-1:-1;47162:111:0;;-1:-1:-1;47162:111:0;-1:-1:-1;47162:111:0;-1:-1:-1;47305:41:0;47320:13;;;;:6;:13;:::i;:::-;47335:10;47305:14;:41::i;:::-;47357;47372:13;;;;;;;;:::i;47357:41::-;47411:22;47428:4;47411:16;:22::i;:::-;46403:1038;;;;;;;:::o;51765:159::-;51877:39;;;;;51850:7;;51877:33;;;;;;:39;;51911:4;;;;51877:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51870:46;51765:159;-1:-1:-1;;;;51765:159:0:o;11706:362::-;11914:50;;;;;11938:10;11914:50;;;37995:74:1;11958:4:0;38085:18:1;;;38078:83;11967:17:0;;11914:23;;;;;;37968:18:1;;11914:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:70;11910:151;;;12001:48;12019:5;12026;12033:6;12041:1;12044;12047;12001:17;:48::i;:::-;11706:362;;;;;;:::o;23783:789::-;23849:22;23906:4;23894:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23884:34;;23944:6;23939:626;23952:15;;;23939:626;;;23986:12;;24031:4;24050;;24055:1;24050:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;24023:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23985:73;;;;24080:7;24075:313;;24209:2;24193:6;:13;:18;24189:32;;;24213:8;;;24189:32;24294:4;24286:6;24282:17;24272:27;;24354:6;24343:28;;;;;;;;;;;;:::i;:::-;24336:36;;;;;;;;;;;:::i;:::-;;;;;;;;24075:313;24417:6;24404:7;24412:1;24404:10;;;;;;;;:::i;:::-;;;;;;;;;;:19;-1:-1:-1;;24535:3:0;;23939:626;;;;23783:789;;;;:::o;36789:466::-;37017:34;37074:173;37114:4;37133:9;37157:4;;37074:173;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37074:173:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37176:10:0;;-1:-1:-1;37176:10:0;;;;37074:173;;;37176:10;;37074:173;37176:10;37074:173;;;;;;;;;-1:-1:-1;37201:8:0;;-1:-1:-1;37224:12:0;;-1:-1:-1;37224:12:0;;-1:-1:-1;37074:25:0;:173::i;:::-;37064:183;36789:466;-1:-1:-1;;;;;;;;;;36789:466:0:o;5362:464::-;3710:13;:11;:13::i;:::-;5464:16:::1;::::0;::::1;::::0;;::::1;::::0;:31:::1;;;5490:5;5484:11;;:2;:11;;;;5464:31;5456:54;;;::::0;::::1;::::0;;44345:2:1;5456:54:0::1;::::0;::::1;44327:21:1::0;44384:2;44364:18;;;44357:30;44423:12;44403:18;;;44396:40;44453:18;;5456:54:0::1;44143:334:1::0;5456:54:0::1;5538:38;::::0;;;;5570:4:::1;5538:38;::::0;::::1;8717:74:1::0;5523:12:0::1;::::0;5538:23:::1;::::0;::::1;::::0;::::1;::::0;8690:18:1;;5538:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5523:53;;5593:6;5603:1;5593:11:::0;5589:230:::1;;5621:47;5649:5;5656:2;5660:7;5621:27;:47::i;:::-;5589:230;;;5719:7;5709:6;:17;;5701:45;;;::::0;::::1;::::0;;44684:2:1;5701:45:0::1;::::0;::::1;44666:21:1::0;44723:2;44703:18;;;44696:30;44762:17;44742:18;;;44735:45;44797:18;;5701:45:0::1;44482:339:1::0;5701:45:0::1;5761:46;5789:5;5796:2;5800:6;5761:27;:46::i;:::-;5445:381;5362:464:::0;;;:::o;47449:1052::-;47811:14;;-1:-1:-1;;;;;;;;47678:15:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47678:15:0;;;;;;;;47893:6;47888:454;47905:1;47901;:5;47888:454;;;47940:7;47948:1;47940:10;;;;;;;;:::i;:::-;;;;;;;;;;;;47980:18;;48086:26;;;;48131:21;;;;;48171:14;;;;48204;;;;48237;;;;47967:299;;;;;48025:10;47967:299;;;33683:74:1;48062:4:0;33773:18:1;;;33766:83;33865:18;;;33858:34;;;;33908:18;;;33901:34;;;;33984:4;33972:17;33951:19;;;33944:46;34006:19;;;33999:35;34050:19;;;34043:35;47940:10:0;;-1:-1:-1;47967:39:0;;;;;;;33655:19:1;;47967:299:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48312:3;;;;;47888:454;;;;48395:98;48424:18;48457:4;48476:6;48395:14;:98::i;:::-;48354:139;;;;-1:-1:-1;48354:139:0;-1:-1:-1;48354:139:0;;-1:-1:-1;47449:1052:0;-1:-1:-1;;;;;;;47449:1052:0:o;11067:334::-;11264:50;;;;;11288:10;11264:50;;;37995:74:1;11308:4:0;38085:18:1;;;38078:83;11317:5:0;;11264:23;;;;;;37968:18:1;;11264:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;11260:134;;;11339:43;11350:5;11357;11364:8;11374:1;11377;11380;11339:10;:43::i;33591:530::-;33858:14;33897:181;33924:4;33943:6;;33964:4;;33983:12;34010:8;34033:12;;34060:7;33897:12;:181::i;:::-;33885:193;;34091:22;34108:4;34091:16;:22::i;4721:201::-;3710:13;:11;:13::i;:::-;4810:22:::1;::::0;::::1;4802:73;;;::::0;::::1;::::0;;45028:2:1;4802:73:0::1;::::0;::::1;45010:21:1::0;45067:2;45047:18;;;45040:30;45106:34;45086:18;;;45079:62;45177:8;45157:18;;;45150:36;45203:19;;4802:73:0::1;44826:402:1::0;4802:73:0::1;4886:28;4905:8;4886:18;:28::i;:::-;4721:201:::0;:::o;10792:267::-;10972:79;;;;;10999:10;10972:79;;;33683:74:1;11019:4:0;33773:18:1;;;33766:83;33865:18;;;33858:34;;;33908:18;;;33901:34;;;33984:4;33972:17;;33951:19;;;33944:46;34006:19;;;33999:35;;;34050:19;;;34043:35;;;10972:26:0;;;;;;33655:19:1;;10972:79:0;33372:712:1;52615:189:0;52715:29;52722:6;52730:5;52737:6;52715;:29::i;:::-;52755:41;;;;;:22;45453:55:1;;;52755:41:0;;;45435:74:1;45525:18;;;45518:34;;;45588:55;;;45568:18;;;45561:83;52755:22:0;;;;;45408:18:1;;52755:41:0;45233:417:1;39828:1081:0;39965:1;39950:12;:16;:36;;;;39985:1;39970:12;:16;39950:36;39942:45;;;;;;40064:15;;40101:33;;;;40112:4;40101:33;:::i;:::-;40063:71;;-1:-1:-1;40063:71:0;-1:-1:-1;40807:94:0;40835:23;;;;:40;;40868:7;40835:40;;;30115:42;40835:40;40877:10;40889:11;40807:27;:94::i;35380:615::-;35700:14;35739:213;35776:4;35795:6;;35816:4;;35835:12;35862:8;35885:12;;35912:7;35934;35739:22;:213::i;:::-;35727:225;;35965:22;35982:4;35965:16;:22::i;32942:641::-;33206:14;33245:171;33284:4;33303:6;;33324:4;;33343:12;33370:8;33393:12;;33245:24;:171::i;:::-;33233:183;-1:-1:-1;33433:21:0;;;;33429:147;;33471:10;33484:27;;;;33495:4;33484:27;:::i;:::-;33526:38;;;;;;;;35327:25:1;;;33526:23:0;35388:55:1;;;35368:18;;;35361:83;33471:40:0;;-1:-1:-1;33526:23:0;;;;;;35300:18:1;;33526:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33456:120;32942:641;;;;;;;;;;;;:::o;3989:130::-;4064:10;4053:7;3870;3897:6;;;;3824:87;4053:7;:21;;;4045:66;;;;;;;45857:2:1;4045:66:0;;;45839:21:1;;;45876:18;;;45869:30;45935:34;45915:18;;;45908:62;45987:18;;4045:66:0;45655:356:1;8005:260:0;8135:12;8153:2;:7;;8168:5;8153:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8134:44;;;8196:7;8191:67;;8227:19;;;;;;;;;;;;;;8191:67;8063:202;8005:260;;:::o;41034:4302::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;41238:12:0;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41367:14:0;41362:3641;41395:11;41383:9;:23;41362:3641;;;41432:5;41438:9;41432:16;;;;;;;;:::i;:::-;;;;;;;41425:23;;41512:4;:10;;;41523:1;41512:13;;;;;;;;:::i;:::-;;;;;;;41505:20;;41615:1;41589:28;;:4;:14;;;:28;;;41585:655;;41638:203;41680:4;:12;;;41715:4;:9;;;41773:4;:13;;;41809:4;:13;;;41638:19;:203::i;:::-;41585:655;;;41914:221;41956:4;:12;;;41999:4;42067;:13;;;42103:4;:13;;;41914:19;:221::i;:::-;42178:46;;;;;;;;42196:12;;;;;42178:46;;;;42210:13;;;;42178:46;;;;;;;42156:68;;41585:655;42314:10;;:17;:21;;42334:1;;42314:21;:::i;:::-;42292:19;;;:43;42352:14;42381:2539;42419:14;;;;:28;;42415:1458;;42504:4;:9;;;42494:25;;;42546:4;:9;;;42557:10;42569:4;:13;;;42584:4;:17;;;42494:130;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42472:152;;42415:1458;;;42873:19;;:25;;42900:26;;;;;42862:65;;42825:34;;42862:65;;42873:25;42900:26;42862:65;48273:42:1;48261:55;;;;48243:74;;48348:2;48333:18;;48326:34;48231:2;48216:18;;48069:297;42862:65:0;;;;;;;;;;;;;42825:102;;42953:14;42969;43002:4;:9;;;42987:30;;;43044:4;:14;;;43085:4;:15;;;43134:5;:19;;;:26;;;43219:4;:22;;;:27;;43245:1;43219:27;:195;;43392:4;:22;;;43219:195;;;43279:4;:15;;;:80;;43310:49;43279:80;;;43297:10;43279:80;43468:21;43516:10;43553:4;:13;;;43593:4;:17;;;42987:646;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42952:681;;;;43680:173;;;;;;;;43732:4;:13;;;43680:173;;;;;;43780:4;:15;;;:49;;43820:8;43821:7;43820:8;:::i;:::-;43780:49;;;43803:8;43804:7;43803:8;:::i;:::-;43680:173;;43658:195;;-1:-1:-1;;;42415:1458:0;43910:5;:19;;;43897:9;:32;43893:1012;;43972:19;;:25;43954:43;;;;44040:19;;:26;;;;;44020:16;;;:46;;;;44040:26;;44020:46;:::i;:::-;;;-1:-1:-1;44091:5:0;;43893:1012;44186:13;;;;44372:10;;:21;;44261:11;;;;;;;44372:21;;;;;;:::i;:::-;;;;;;;44365:28;;44423:20;44422:21;:38;;;;;44447:4;:13;;;44422:38;44418:468;;;44510:19;;:25;44503:58;;;;;44555:4;44503:58;;;8717:74:1;44489:11:0;;44503:43;;;;;8690:18:1;;44503:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44676:19;;:25;44489:72;;-1:-1:-1;44648:69:0;;30035:42;44489:72;44648:27;:69::i;:::-;44825:19;;:25;44852:9;;44803:59;;;;;38025:42:1;38013:55;;;44803:59:0;;;37995:74:1;38105:55;;38085:18;;;38078:83;30035:42:0;;44803:21;;37968:18:1;;44803:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;44462:424;44418:468;44135:770;42381:2539;;;-1:-1:-1;44965:11:0;;41362:3641;;;;45038:12;45019:9;:16;;;:31;45015:90;;;45074:19;;;;;;;;;;;;;;45015:90;45121:32;;;;45117:212;;45191:37;;;;;45222:4;45191:37;;;8717:74:1;30115:42:0;;45170:20;;30115:42;;45191:22;;8690:18:1;;45191:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45170:59;;;;;;;;;;;;;16316:25:1;;16304:2;16289:18;;16170:177;45170:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45244:73;45275:18;45295:21;45244:30;:73::i;:::-;41208:4128;;;;41034:4302;;;;;:::o;36026:755::-;36308:57;;;;;36337:10;36308:57;;;50263:74:1;36308:28:0;;;50353:18:1;;;50346:83;;;50445:18;;;50438:34;;;36261::0;;36308:28;;50236:18:1;;36308:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;36388:58:0;;;;;:16;;;;;;:58;;36405:4;;36411:10;;36423:8;;36433:12;;;;36388:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36468:14;;36378:68;;-1:-1:-1;36459:6:0;36495:279;36512:1;36508;:5;36495:279;;;36532:36;36571:7;36579:1;36571:10;;;;;;;;:::i;:::-;;;;;;;36532:49;;36623:10;36634:1;36623:13;;;;;;;;:::i;:::-;;;;;;;36602:11;:18;;;:34;36598:101;;;36664:19;;;;;;;;;;;;;;36598:101;-1:-1:-1;36744:3:0;;36495:279;;;;36297:484;36026:755;;;;;;;;;:::o;31912:795::-;-1:-1:-1;;;;;;;;32155:14:0;-1:-1:-1;;;;;;;;;;;;;;;32238:6:0;;32305;32300:215;32317:1;32313;:5;32300:215;;;32345:6;;32352:1;32345:9;;;;;;;:::i;:::-;;;;;;32337:17;;;;;;;;;;:::i;:::-;;;32371:68;32391:5;:11;;;32404:4;32410:5;:12;;;32424:5;:14;;;32371:19;:68::i;:::-;32485:3;;32300:215;;;-1:-1:-1;32539:58:0;;;;;:16;;;;;;:58;;32556:4;;;;32562:10;;32574:8;;32584:12;;;;32539:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32527:70;;32626:12;32614:9;:24;32610:90;;;32662:26;;;;;;;;;;;;;;32610:90;32171:536;;31912:795;;;;;;;;;;;:::o;30783:1121::-;30890:8;30886:1011;;;30919:21;;;;;:75;;-1:-1:-1;30945:13:0;;;30115:42;30945:13;:48;;;;;30987:6;30962:21;:31;;30945:48;30915:486;;;31061:54;;;;;30212:1;31061:54;;;37995:74:1;38025:42;38105:55;;38085:18;;;38078:83;30035:42:0;;31061:21;;31090:6;;37968:18:1;;31061:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;30886:1011;;30915:486;31206:65;31238:5;31245:10;30035:42;31264:6;31206:31;:65::i;:::-;31353:32;;;;;38025:42:1;38013:55;;;31353:32:0;;;37995:74:1;38105:55;;38085:18;;;38078:83;30035:42:0;;31353:21;;37968:18:1;;31353:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30886:1011::-;31437:21;;;;;:75;;-1:-1:-1;31463:13:0;;;30115:42;31463:13;:48;;;;;31505:6;31480:21;:31;;31463:48;31433:453;;;30115:42;31578:19;;;31605:6;31578:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;31682:32:0;;;;;48273:42:1;48261:55;;31682:32:0;;;48243:74:1;48333:18;;;48326:34;;;30115:42:0;;-1:-1:-1;31682:20:0;;-1:-1:-1;48216:18:1;;;-1:-1:-1;31682:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;31433:453::-;31808:62;31840:5;31847:10;31859:2;31863:6;31808:31;:62::i;51270:413::-;51365:21;;;;51361:315;;51407:47;;;;;51439:4;51407:47;;;37995:74:1;51407:23:0;38105:55:1;;;38085:18;;;38078:83;51457:6:0;;51407:23;;;;;;37968:18:1;;51407:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:56;51403:262;;;51484:45;51511:5;51518:7;51527:1;51484:26;:45::i;:::-;51591:58;51618:5;51625:7;51634:14;51591:26;:58::i;50597:665::-;50671:21;;;;;:38;;-1:-1:-1;50696:13:0;;;30115:42;50696:13;50671:38;50667:588;;;50741:37;;;;;50772:4;50741:37;;;8717:74:1;50726:12:0;;30115:42;;50741:22;;8690:18:1;;50741:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50726:52;-1:-1:-1;50797:12:0;;50793:82;;50830:29;;;;;;;;16316:25:1;;;30115:42:0;;50830:20;;16289:18:1;;50830:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50793:82;50893:21;:26;50889:124;;50940:57;50971:2;50975:21;50940:30;:57::i;50667:588::-;51060:38;;;;;51092:4;51060:38;;;8717:74:1;51045:12:0;;51060:23;;;;;;8690:18:1;;51060:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51045:53;-1:-1:-1;51117:12:0;;51113:131;;51189:38;;;;;51221:4;51189:38;;;8717:74:1;51150:78:0;;51178:5;;51185:2;;51189:23;;;;;;8690:18:1;;51189:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51150:27;:78::i;38057:529::-;-1:-1:-1;;;;;;;;;;;;;;;;38333:57:0;;;;;38362:10;38333:57;;;50263:74:1;38333:28:0;;;50353:18:1;;;50346:83;;;50445:18;;;50438:34;;;38333:28:0;;;50236:18:1;;38333:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;38415:64:0;;;;;:22;;;;;;:64;;38438:4;;38444:10;;38456:8;;38466:12;;38415:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38403:76;;38515:9;38496;:16;;;:28;38492:87;;;38548:19;;;;;;;;;;;;;;51932:423;52011:73;52043:5;52050:10;52070:4;52077:6;52011:31;:73::i;:::-;52101:46;;;;;52133:4;52101:46;;;37995:74:1;52101:23:0;38105:55:1;;;38085:18;;;38078:83;52150:6:0;;52101:23;;;;;;37968:18:1;;52101:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:55;52097:251;;;52279:57;52306:5;52313:6;52321:14;52279:26;:57::i;5082:191::-;5156:16;5175:6;;;5192:17;;;;;;;;;;5225:40;;5175:6;;;;;;;5225:40;;5156:16;5225:40;5145:128;5082:191;:::o;32715:219::-;32779:19;;;;;;;:13;:19;;;;;;;;32799:10;32779:31;;;;;;;;;;32774:153;;32827:19;;;;;;32861:4;32827:19;;;;;;;;32847:10;32827:31;;;;;;;:38;;;;;;;;32880:12;:24;;;;:35;;;;;;;;;;;;;;;;;;;;;;32715:219::o;7000:470::-;7289:45;;;7278:10;48261:55:1;;;7289:45:0;;;48243:74:1;48333:18;;;;48326:34;;;7289:45:0;;;;;;;;;;48216:18:1;;;;7289:45:0;;;;;;;;;;;;;7278:57;;-1:-1:-1;;;;7278:10:0;;;;:57;;7289:45;7278:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7242:93;;;;7353:7;7352:8;:59;;;-1:-1:-1;7365:11:0;;:16;;;;:45;;;7397:4;7386:24;;;;;;;;;;;;:::i;:::-;7385:25;7365:45;7348:115;;;7435:16;;;;;;;;;;;;;;7478:519;7806:51;;;7795:10;50281:55:1;;;7806:51:0;;;50263:74:1;50373:55;;;50353:18;;;50346:83;50445:18;;;;50438:34;;;7806:51:0;;;;;;;;;;50236:18:1;;;;7806:51:0;;;;;;;;;;;;;7795:63;;-1:-1:-1;;;;7795:10:0;;;;:63;;7806:51;7795:63;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7759:99;;;;7876:7;7875:8;:59;;;-1:-1:-1;7888:11:0;;:16;;;;:45;;;7920:4;7909:24;;;;;;;;;;;;:::i;:::-;7908:25;7888:45;7871:119;;;7958:20;;;;;;;;;;;;;;6525:467;6812:45;;;6801:10;48261:55:1;;;6812:45:0;;;48243:74:1;48333:18;;;;48326:34;;;6812:45:0;;;;;;;;;;48216:18:1;;;;6812:45:0;;;;;;;;;;;;;6801:57;;-1:-1:-1;;;;6801:10:0;;;;:57;;6812:45;6801:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6765:93;;;;6876:7;6875:8;:59;;;-1:-1:-1;6888:11:0;;:16;;;;:45;;;6920:4;6909:24;;;;;;;;;;;;:::i;:::-;6908:25;6888:45;6871:114;;;6958:15;;;;;;;;;;;;;;14:162:1;108:42;101:5;97:54;90:5;87:65;77:93;;166:1;163;156:12;181:383;257:6;265;318:2;306:9;297:7;293:23;289:32;286:52;;;334:1;331;324:12;286:52;373:9;360:23;392:39;425:5;392:39;:::i;:::-;450:5;528:2;513:18;;;;500:32;;-1:-1:-1;;;181:383:1:o;569:184::-;621:77;618:1;611:88;718:4;715:1;708:15;742:4;739:1;732:15;758:253;830:2;824:9;872:4;860:17;;907:18;892:34;;928:22;;;889:62;886:88;;;954:18;;:::i;:::-;990:2;983:22;758:253;:::o;1016:255::-;1088:2;1082:9;1130:6;1118:19;;1167:18;1152:34;;1188:22;;;1149:62;1146:88;;;1214:18;;:::i;1276:253::-;1348:2;1342:9;1390:4;1378:17;;1425:18;1410:34;;1446:22;;;1407:62;1404:88;;;1472:18;;:::i;1534:334::-;1605:2;1599:9;1661:2;1651:13;;1666:66;1647:86;1635:99;;1764:18;1749:34;;1785:22;;;1746:62;1743:88;;;1811:18;;:::i;:::-;1847:2;1840:22;1534:334;;-1:-1:-1;1534:334:1:o;1873:191::-;1941:4;1974:18;1966:6;1963:30;1960:56;;;1996:18;;:::i;:::-;-1:-1:-1;2041:1:1;2037:14;2053:4;2033:25;;1873:191::o;2069:142::-;2137:20;;2166:39;2137:20;2166:39;:::i;:::-;2069:142;;;:::o;2216:245::-;2264:4;2297:18;2289:6;2286:30;2283:56;;;2319:18;;:::i;:::-;-1:-1:-1;2376:2:1;2364:15;2381:66;2360:88;2450:4;2356:99;;2216:245::o;2466:486::-;2508:5;2561:3;2554:4;2546:6;2542:17;2538:27;2528:55;;2579:1;2576;2569:12;2528:55;2619:6;2606:20;2650:52;2666:35;2694:6;2666:35;:::i;:::-;2650:52;:::i;:::-;2727:6;2718:7;2711:23;2781:3;2774:4;2765:6;2757;2753:19;2749:30;2746:39;2743:59;;;2798:1;2795;2788:12;2743:59;2863:6;2856:4;2848:6;2844:17;2837:4;2828:7;2824:18;2811:59;2919:1;2890:20;;;2912:4;2886:31;2879:42;;;;2894:7;2466:486;-1:-1:-1;;;2466:486:1:o;2957:118::-;3043:5;3036:13;3029:21;3022:5;3019:32;3009:60;;3065:1;3062;3055:12;3080:128;3145:20;;3174:28;3145:20;3174:28;:::i;3213:3287::-;3275:5;3328:3;3321:4;3313:6;3309:17;3305:27;3295:55;;3346:1;3343;3336:12;3295:55;3370:86;3386:69;3447:6;3434:20;3386:69;:::i;3370:86::-;3504:20;;3492:33;;;3550:4;3541:14;;;;3480:3;3590:1;3586:28;3574:41;;3570:52;3567:61;-1:-1:-1;3564:81:1;;;3641:1;3638;3631:12;3564:81;3677:4;3669:6;3665:17;3691:2778;3762:4;3751:6;3738:20;3735:1;3731:28;3723:6;3719:41;3715:52;3710:3;3707:61;3691:2778;;;3850:18;3844:3;3831:17;3828:41;3825:61;;;3882:1;3879;3872:12;3825:61;3934:3;3921:17;3913:6;3909:30;4046:4;3977:66;3972:2;3967:3;3963:12;3959:85;3955:96;3952:116;;;4064:1;4061;4054:12;3952:116;4094:22;;:::i;:::-;4164:18;4156:4;4152:2;4148:13;4135:27;4132:51;4129:71;;;4196:1;4193;4186:12;4129:71;4265:4;4256;4252:2;4248:13;4235:27;4231:2;4227:36;4223:47;4312:3;4305:4;4301:2;4297:13;4293:23;4283:51;;4330:1;4327;4320:12;4283:51;4360:82;4376:65;4437:2;4424:16;4376:65;:::i;4360:82::-;4502:16;;4488:31;;;4552:4;4541:16;;;;4470:5;4592:1;4588:24;4580:33;;4576:44;4573:53;-1:-1:-1;4570:73:1;;;4639:1;4636;4629:12;4570:73;4677:4;4673:2;4669:13;4695:1470;4764:4;4757:2;4744:16;4741:1;4737:24;4733:2;4729:33;4725:44;4718:5;4715:55;4695:1470;;;4870:18;4862:5;4849:19;4846:43;4843:63;;;4902:1;4899;4892:12;4843:63;4954:5;4941:19;4937:2;4933:28;5072:6;5003:66;4998:2;4993:3;4989:12;4985:85;4981:98;4978:118;;;5092:1;5089;5082:12;4978:118;5128:22;;:::i;:::-;5183:33;5210:4;5206:2;5202:13;5183:33;:::i;:::-;5174:7;5167:50;5267:18;5261:2;5257;5253:11;5240:25;5237:49;5234:69;;;5299:1;5296;5289:12;5234:69;5347:68;5411:3;5404:4;5397:2;5393;5389:11;5376:25;5372:2;5368:34;5364:45;5347:68;:::i;:::-;5340:4;5331:7;5327:18;5320:96;5458:33;5485:4;5481:2;5477:13;5458:33;:::i;:::-;5453:2;5444:7;5440:16;5433:59;5543:18;5536:3;5532:2;5528:12;5515:26;5512:50;5509:70;;;5575:1;5572;5565:12;5509:70;5623:69;5688:3;5681:4;5673:3;5669:2;5665:12;5652:26;5648:2;5644:35;5640:46;5623:69;:::i;:::-;5616:4;5607:7;5603:18;5596:97;5736:29;5760:3;5756:2;5752:12;5736:29;:::i;:::-;5730:3;5721:7;5717:17;5710:56;5809:32;5836:3;5832:2;5828:12;5809:32;:::i;:::-;5803:3;5794:7;5790:17;5783:59;5885:29;5909:3;5905:2;5901:12;5885:29;:::i;:::-;5879:3;5870:7;5866:17;5859:56;5958:32;5985:3;5981:2;5977:12;5958:32;:::i;:::-;5952:3;5943:7;5939:17;5932:59;6034:35;6061:6;6057:2;6053:15;6034:35;:::i;:::-;6028:3;6015:17;;6008:62;6087:22;;-1:-1:-1;6146:4:1;6135:16;;;;4794;4695:1470;;;-1:-1:-1;6178:22:1;;-1:-1:-1;6238:31:1;;-1:-1:-1;6265:2:1;6257:11;;6238:31;:::i;:::-;6231:4;6220:16;;;6213:57;;;;6344:4;6336:13;;;;6323:27;6381:2;6370:14;;6363:31;6407:18;;6445:14;;;;3786;3691:2778;;;-1:-1:-1;6487:7:1;3213:3287;-1:-1:-1;;;;3213:3287:1:o;6505:166::-;6575:5;6620:3;6611:6;6606:3;6602:16;6598:26;6595:46;;;6637:1;6634;6627:12;6595:46;-1:-1:-1;6659:6:1;6505:166;-1:-1:-1;6505:166:1:o;6676:909::-;6855:6;6863;6871;6879;6887;6940:3;6928:9;6919:7;6915:23;6911:33;6908:53;;;6957:1;6954;6947:12;6908:53;6997:9;6984:23;7030:18;7022:6;7019:30;7016:50;;;7062:1;7059;7052:12;7016:50;7085:69;7146:7;7137:6;7126:9;7122:22;7085:69;:::i;:::-;7075:79;-1:-1:-1;;7223:2:1;7208:18;;7195:32;;-1:-1:-1;7324:2:1;7309:18;;7296:32;;-1:-1:-1;7373:73:1;7438:7;7433:2;7418:18;;7373:73;:::i;:::-;7363:83;;7498:3;7487:9;7483:19;7470:33;7512:41;7545:7;7512:41;:::i;:::-;7572:7;7562:17;;;6676:909;;;;;;;;:::o;7928:258::-;7803:12;;7817:42;7799:61;7787:74;;7910:4;7899:16;;;7893:23;7877:14;;;7870:47;8120:2;8105:18;;8132:48;7928:258;;;;:::o;8802:347::-;8853:8;8863:6;8917:3;8910:4;8902:6;8898:17;8894:27;8884:55;;8935:1;8932;8925:12;8884:55;-1:-1:-1;8958:20:1;;9001:18;8990:30;;8987:50;;;9033:1;9030;9023:12;8987:50;9070:4;9062:6;9058:17;9046:29;;9122:3;9115:4;9106:6;9098;9094:19;9090:30;9087:39;9084:59;;;9139:1;9136;9129:12;9084:59;8802:347;;;;;:::o;9154:367::-;9217:8;9227:6;9281:3;9274:4;9266:6;9262:17;9258:27;9248:55;;9299:1;9296;9289:12;9248:55;-1:-1:-1;9322:20:1;;9365:18;9354:30;;9351:50;;;9397:1;9394;9387:12;9351:50;9434:4;9426:6;9422:17;9410:29;;9494:3;9487:4;9477:6;9474:1;9470:14;9462:6;9458:27;9454:38;9451:47;9448:67;;;9511:1;9508;9501:12;9526:588;9590:5;9638:4;9626:9;9621:3;9617:19;9613:30;9610:50;;;9656:1;9653;9646:12;9610:50;9678:22;;:::i;:::-;9745:23;;9777:22;;9872:2;9857:18;;;9844:32;9892:14;;;9885:31;9669;-1:-1:-1;9967:2:1;9952:18;;9939:32;9994:18;9983:30;;9980:50;;;10026:1;10023;10016:12;9980:50;10062:45;10103:3;10094:6;10083:9;10079:22;10062:45;:::i;:::-;10057:2;10050:5;10046:14;10039:69;;9526:588;;;;:::o;10119:1566::-;10314:6;10322;10330;10338;10346;10354;10362;10370;10378;10386;10439:3;10427:9;10418:7;10414:23;10410:33;10407:53;;;10456:1;10453;10446:12;10407:53;10479:29;10498:9;10479:29;:::i;:::-;10469:39;-1:-1:-1;10577:2:1;10562:18;;10549:32;;-1:-1:-1;10656:2:1;10641:18;;10628:32;10683:18;10672:30;;10669:50;;;10715:1;10712;10705:12;10669:50;10754:58;10804:7;10795:6;10784:9;10780:22;10754:58;:::i;:::-;10831:8;;-1:-1:-1;10728:84:1;-1:-1:-1;;10919:2:1;10904:18;;10891:32;10948:18;10935:32;;10932:52;;;10980:1;10977;10970:12;10932:52;11019:72;11083:7;11072:8;11061:9;11057:24;11019:72;:::i;:::-;11110:8;;-1:-1:-1;10993:98:1;-1:-1:-1;11164:39:1;;-1:-1:-1;11198:3:1;11183:19;;11164:39;:::i;:::-;11154:49;;11256:3;11245:9;11241:19;11228:33;11286:18;11276:8;11273:32;11270:52;;;11318:1;11315;11308:12;11270:52;11357:60;11409:7;11398:8;11387:9;11383:24;11357:60;:::i;:::-;11436:8;;-1:-1:-1;11331:86:1;-1:-1:-1;;11524:3:1;11509:19;;11496:33;11554:18;11541:32;;11538:52;;;11586:1;11583;11576:12;11538:52;11609:70;11671:7;11660:8;11649:9;11645:24;11609:70;:::i;:::-;11599:80;;;10119:1566;;;;;;;;;;;;;:::o;11690:692::-;11938:2;11950:21;;;12020:13;;11923:18;;;12042:22;;;11890:4;;12121:15;;;12095:2;12080:18;;;11890:4;12164:192;12178:6;12175:1;12172:13;12164:192;;;12227:49;12272:3;12263:6;12257:13;7803:12;;7817:42;7799:61;7787:74;;7910:4;7899:16;;;7893:23;7877:14;;7870:47;7722:201;12227:49;12343:2;12331:15;;;;;12305:2;12296:12;;;;;12200:1;12193:9;12164:192;;;-1:-1:-1;12373:3:1;;11690:692;-1:-1:-1;;;;;11690:692:1:o;12387:389::-;12469:8;12479:6;12533:3;12526:4;12518:6;12514:17;12510:27;12500:55;;12551:1;12548;12541:12;12500:55;-1:-1:-1;12574:20:1;;12617:18;12606:30;;12603:50;;;12649:1;12646;12639:12;12603:50;12686:4;12678:6;12674:17;12662:29;;12749:3;12742:4;12734;12726:6;12722:17;12714:6;12710:30;12706:41;12703:50;12700:70;;;12766:1;12763;12756:12;12781:156;12847:20;;12907:4;12896:16;;12886:27;;12876:55;;12927:1;12924;12917:12;12942:1491;13013:5;13066:3;13059:4;13051:6;13047:17;13043:27;13033:55;;13084:1;13081;13074:12;13033:55;13124:6;13111:20;13151:72;13167:55;13215:6;13167:55;:::i;13151:72::-;13247:3;13271:6;13266:3;13259:19;13303:4;13298:3;13294:14;13287:21;;13367:4;13359;13351:6;13347:17;13339:6;13335:30;13331:41;13317:55;;13395:3;13387:6;13384:15;13381:35;;;13412:1;13409;13402:12;13381:35;13448:4;13440:6;13436:17;13462:940;13478:6;13473:3;13470:15;13462:940;;;13556:4;13550:3;13545;13541:13;13537:24;13534:44;;;13574:1;13571;13564:12;13534:44;13604:22;;:::i;:::-;13667:3;13654:17;13684:41;13717:7;13684:41;:::i;:::-;13738:22;;13835:4;13826:14;;;13813:28;13861:16;;;13854:33;13962:2;13953:12;;;13940:26;13986:14;;;13979:31;14046:30;14072:2;14063:12;;14046:30;:::i;:::-;14041:2;14030:14;;14023:54;14152:3;14143:13;;;14130:27;14177:15;;;14170:32;14277:3;14268:13;;;14255:27;14302:15;;;14295:32;14340:18;;14387:4;14378:14;;;;13504:4;13495:14;13462:940;;;-1:-1:-1;14420:7:1;12942:1491;-1:-1:-1;;;;;12942:1491:1:o;14438:1727::-;14697:6;14705;14713;14721;14729;14737;14745;14753;14761;14769;14777:7;14831:3;14819:9;14810:7;14806:23;14802:33;14799:53;;;14848:1;14845;14838:12;14799:53;14871:29;14890:9;14871:29;:::i;:::-;14861:39;;14951:2;14940:9;14936:18;14923:32;14978:18;14970:6;14967:30;14964:50;;;15010:1;15007;15000:12;14964:50;15049:89;15130:7;15121:6;15110:9;15106:22;15049:89;:::i;:::-;15157:8;;-1:-1:-1;15023:115:1;-1:-1:-1;;15245:2:1;15230:18;;15217:32;15274:18;15261:32;;15258:52;;;15306:1;15303;15296:12;15258:52;15345:60;15397:7;15386:8;15375:9;15371:24;15345:60;:::i;:::-;15424:8;;-1:-1:-1;15319:86:1;-1:-1:-1;;15528:2:1;15513:18;;15500:32;;-1:-1:-1;15575:39:1;15609:3;15594:19;;15575:39;:::i;:::-;15565:49;;15667:3;15656:9;15652:19;15639:33;15697:18;15687:8;15684:32;15681:52;;;15729:1;15726;15719:12;15681:52;15768:60;15820:7;15809:8;15798:9;15794:24;15768:60;:::i;:::-;15847:8;;-1:-1:-1;15742:86:1;-1:-1:-1;;15935:3:1;15920:19;;15907:33;15965:18;15952:32;;15949:52;;;15997:1;15994;15987:12;15949:52;16020:80;16092:7;16081:8;16070:9;16066:24;16020:80;:::i;:::-;16010:90;;;16120:39;16154:3;16143:9;16139:19;16120:39;:::i;:::-;16109:50;;14438:1727;;;;;;;;;;;;;;:::o;16352:808::-;16454:6;16462;16470;16478;16486;16494;16547:3;16535:9;16526:7;16522:23;16518:33;16515:53;;;16564:1;16561;16554:12;16515:53;16603:9;16590:23;16622:39;16655:5;16622:39;:::i;:::-;16680:5;-1:-1:-1;16758:2:1;16743:18;;16730:32;;-1:-1:-1;16861:2:1;16846:18;;16833:32;;-1:-1:-1;16910:36:1;16942:2;16927:18;;16910:36;:::i;:::-;16352:808;;;;-1:-1:-1;16352:808:1;;17019:3;17004:19;;16991:33;;17123:3;17108:19;;;17095:33;;-1:-1:-1;16352:808:1;-1:-1:-1;;16352:808:1:o;17165:706::-;17294:6;17302;17310;17318;17371:3;17359:9;17350:7;17346:23;17342:33;17339:53;;;17388:1;17385;17378:12;17339:53;17427:9;17414:23;17446:39;17479:5;17446:39;:::i;:::-;17504:5;-1:-1:-1;17561:2:1;17546:18;;17533:32;17574:41;17533:32;17574:41;:::i;:::-;17634:7;-1:-1:-1;17693:2:1;17678:18;;17665:32;17706:41;17665:32;17706:41;:::i;:::-;17766:7;-1:-1:-1;17792:73:1;17857:7;17852:2;17837:18;;17792:73;:::i;:::-;17782:83;;17165:706;;;;;;;:::o;18241:404::-;18309:6;18317;18370:2;18358:9;18349:7;18345:23;18341:32;18338:52;;;18386:1;18383;18376:12;18338:52;18425:9;18412:23;18444:39;18477:5;18444:39;:::i;:::-;18502:5;-1:-1:-1;18559:2:1;18544:18;;18531:32;18572:41;18531:32;18572:41;:::i;:::-;18632:7;18622:17;;;18241:404;;;;;:::o;18842:993::-;19038:6;19046;19054;19062;19070;19123:3;19111:9;19102:7;19098:23;19094:33;19091:53;;;19140:1;19137;19130:12;19091:53;19179:9;19166:23;19198:39;19231:5;19198:39;:::i;:::-;19256:5;-1:-1:-1;19313:2:1;19298:18;;19285:32;19326:41;19285:32;19326:41;:::i;:::-;19386:7;-1:-1:-1;19445:2:1;19430:18;;19417:32;19458:41;19417:32;19458:41;:::i;:::-;19518:7;-1:-1:-1;19544:73:1;19609:7;19604:2;19589:18;;19544:73;:::i;:::-;19534:83;;19668:3;19657:9;19653:19;19640:33;19696:18;19688:6;19685:30;19682:50;;;19728:1;19725;19718:12;19682:50;19751:78;19821:7;19812:6;19801:9;19797:22;19751:78;:::i;:::-;19741:88;;;18842:993;;;;;;;;:::o;19840:1069::-;19962:6;19970;19978;19986;19994;20002;20055:3;20043:9;20034:7;20030:23;20026:33;20023:53;;;20072:1;20069;20062:12;20023:53;20111:9;20098:23;20130:39;20163:5;20130:39;:::i;:::-;20188:5;-1:-1:-1;20266:2:1;20251:18;;20238:32;;-1:-1:-1;20347:2:1;20332:18;;20319:32;20374:18;20363:30;;20360:50;;;20406:1;20403;20396:12;20360:50;20429:49;20470:7;20461:6;20450:9;20446:22;20429:49;:::i;:::-;20419:59;-1:-1:-1;;20551:2:1;20536:18;;20523:32;;-1:-1:-1;20633:3:1;20618:19;;20605:33;20647:41;20605:33;20647:41;:::i;:::-;20707:7;-1:-1:-1;20767:3:1;20752:19;;20739:33;20797:18;20784:32;;20781:52;;;20829:1;20826;20819:12;20781:52;20852:51;20895:7;20884:8;20873:9;20869:24;20852:51;:::i;:::-;20842:61;;;19840:1069;;;;;;;;:::o;20914:674::-;21000:6;21008;21016;21024;21077:3;21065:9;21056:7;21052:23;21048:33;21045:53;;;21094:1;21091;21084:12;21045:53;21133:9;21120:23;21152:39;21185:5;21152:39;:::i;:::-;21210:5;-1:-1:-1;21267:2:1;21252:18;;21239:32;21280:41;21239:32;21280:41;:::i;:::-;21340:7;-1:-1:-1;21420:2:1;21405:18;;21392:32;;-1:-1:-1;21502:2:1;21487:18;;21474:32;21515:41;21474:32;21515:41;:::i;:::-;20914:674;;;;-1:-1:-1;20914:674:1;;-1:-1:-1;;20914:674:1:o;21593:793::-;21690:6;21698;21706;21714;21722;21775:3;21763:9;21754:7;21750:23;21746:33;21743:53;;;21792:1;21789;21782:12;21743:53;21831:9;21818:23;21850:39;21883:5;21850:39;:::i;:::-;21908:5;-1:-1:-1;21986:2:1;21971:18;;21958:32;;-1:-1:-1;22089:2:1;22074:18;;22061:32;;-1:-1:-1;22170:2:1;22155:18;;22142:32;22197:18;22186:30;;22183:50;;;22229:1;22226;22219:12;22183:50;22268:58;22318:7;22309:6;22298:9;22294:22;22268:58;:::i;:::-;21593:793;;;;-1:-1:-1;21593:793:1;;-1:-1:-1;22345:8:1;;22242:84;21593:793;-1:-1:-1;;;21593:793:1:o;22391:165::-;22461:5;22506:2;22497:6;22492:3;22488:16;22484:25;22481:45;;;22522:1;22519;22512:12;22561:1263;22727:6;22735;22743;22751;22759;22767;22775;22828:3;22816:9;22807:7;22803:23;22799:33;22796:53;;;22845:1;22842;22835:12;22796:53;22884:9;22871:23;22903:39;22936:5;22903:39;:::i;:::-;22961:5;-1:-1:-1;23039:2:1;23024:18;;23011:32;;-1:-1:-1;23120:2:1;23105:18;;23092:32;23147:18;23136:30;;23133:50;;;23179:1;23176;23169:12;23133:50;23202:49;23243:7;23234:6;23223:9;23219:22;23202:49;:::i;:::-;23192:59;-1:-1:-1;;23324:2:1;23309:18;;23296:32;;-1:-1:-1;23373:39:1;23407:3;23392:19;;23373:39;:::i;:::-;23363:49;;23465:3;23454:9;23450:19;23437:33;23495:18;23485:8;23482:32;23479:52;;;23527:1;23524;23517:12;23479:52;23550:51;23593:7;23582:8;23571:9;23567:24;23550:51;:::i;:::-;23540:61;;;23654:3;23643:9;23639:19;23626:33;23684:18;23674:8;23671:32;23668:52;;;23716:1;23713;23706:12;23668:52;23739:79;23810:7;23799:8;23788:9;23784:24;23739:79;:::i;:::-;23729:89;;;22561:1263;;;;;;;;;;:::o;23829:764::-;23964:6;23972;23980;23988;24041:3;24029:9;24020:7;24016:23;24012:33;24009:53;;;24058:1;24055;24048:12;24009:53;24098:9;24085:23;24131:18;24123:6;24120:30;24117:50;;;24163:1;24160;24153:12;24117:50;24186:69;24247:7;24238:6;24227:9;24223:22;24186:69;:::i;:::-;24176:79;-1:-1:-1;;24324:2:1;24309:18;;24296:32;;-1:-1:-1;24425:2:1;24410:18;;24397:32;;-1:-1:-1;24507:2:1;24492:18;;24479:32;24520:41;24479:32;24520:41;:::i;24598:159::-;24661:5;24706:3;24697:6;24692:3;24688:16;24684:26;24681:46;;;24723:1;24720;24713:12;24762:537;24869:6;24877;24885;24938:3;24926:9;24917:7;24913:23;24909:33;24906:53;;;24955:1;24952;24945:12;24906:53;24994:9;24981:23;25013:39;25046:5;25013:39;:::i;:::-;25071:5;-1:-1:-1;25128:2:1;25113:18;;25100:32;25141:41;25100:32;25141:41;:::i;:::-;25201:7;-1:-1:-1;25227:66:1;25285:7;25280:2;25265:18;;25227:66;:::i;:::-;25217:76;;24762:537;;;;;:::o;25741:552::-;25820:6;25828;25836;25889:2;25877:9;25868:7;25864:23;25860:32;25857:52;;;25905:1;25902;25895:12;25857:52;25944:9;25931:23;25963:39;25996:5;25963:39;:::i;:::-;26021:5;-1:-1:-1;26077:2:1;26062:18;;26049:32;26104:18;26093:30;;26090:50;;;26136:1;26133;26126:12;26090:50;26175:58;26225:7;26216:6;26205:9;26201:22;26175:58;:::i;:::-;25741:552;;26252:8;;-1:-1:-1;26149:84:1;;-1:-1:-1;;;;25741:552:1:o;26298:448::-;26395:6;26403;26456:2;26444:9;26435:7;26431:23;26427:32;26424:52;;;26472:1;26469;26462:12;26424:52;26512:9;26499:23;26545:18;26537:6;26534:30;26531:50;;;26577:1;26574;26567:12;26531:50;26616:70;26678:7;26669:6;26658:9;26654:22;26616:70;:::i;:::-;26705:8;;26590:96;;-1:-1:-1;26298:448:1;-1:-1:-1;;;;26298:448:1:o;26751:347::-;26792:3;26830:5;26824:12;26857:6;26852:3;26845:19;26913:6;26906:4;26899:5;26895:16;26888:4;26883:3;26879:14;26873:47;26965:1;26958:4;26949:6;26944:3;26940:16;26936:27;26929:38;27087:4;27017:66;27012:2;27004:6;27000:15;26996:88;26991:3;26987:98;26983:109;26976:116;;;26751:347;;;;:::o;27103:838::-;27263:4;27311:2;27300:9;27296:18;27341:2;27330:9;27323:21;27364:6;27399;27393:13;27430:6;27422;27415:22;27468:2;27457:9;27453:18;27446:25;;27530:2;27520:6;27517:1;27513:14;27502:9;27498:30;27494:39;27480:53;;27568:2;27560:6;27556:15;27589:1;27599:313;27613:6;27610:1;27607:13;27599:313;;;27702:66;27690:9;27682:6;27678:22;27674:95;27669:3;27662:108;27793:39;27825:6;27816;27810:13;27793:39;:::i;:::-;27783:49;-1:-1:-1;27867:2:1;27890:12;;;;27855:15;;;;;27635:1;27628:9;27599:313;;;-1:-1:-1;27929:6:1;;27103:838;-1:-1:-1;;;;;;27103:838:1:o;27946:1458::-;28099:6;28107;28115;28123;28131;28139;28147;28155;28163;28216:3;28204:9;28195:7;28191:23;28187:33;28184:53;;;28233:1;28230;28223:12;28184:53;28272:9;28259:23;28291:39;28324:5;28291:39;:::i;:::-;28349:5;-1:-1:-1;28427:2:1;28412:18;;28399:32;;-1:-1:-1;28508:2:1;28493:18;;28480:32;28535:18;28524:30;;28521:50;;;28567:1;28564;28557:12;28521:50;28606:58;28656:7;28647:6;28636:9;28632:22;28606:58;:::i;:::-;28683:8;;-1:-1:-1;28580:84:1;-1:-1:-1;;28771:2:1;28756:18;;28743:32;28800:18;28787:32;;28784:52;;;28832:1;28829;28822:12;28784:52;28871:72;28935:7;28924:8;28913:9;28909:24;28871:72;:::i;:::-;28962:8;;-1:-1:-1;28845:98:1;-1:-1:-1;;29049:3:1;29034:19;;29021:33;29063:41;29021:33;29063:41;:::i;:::-;29123:7;-1:-1:-1;29183:3:1;29168:19;;29155:33;29213:18;29200:32;;29197:52;;;29245:1;29242;29235:12;29197:52;29284:60;29336:7;29325:8;29314:9;29310:24;29284:60;:::i;:::-;29258:86;;29363:8;29353:18;;;29390:8;29380:18;;;27946:1458;;;;;;;;;;;:::o;29409:524::-;29486:6;29494;29502;29555:2;29543:9;29534:7;29530:23;29526:32;29523:52;;;29571:1;29568;29561:12;29523:52;29610:9;29597:23;29629:39;29662:5;29629:39;:::i;:::-;29687:5;-1:-1:-1;29744:2:1;29729:18;;29716:32;29757:41;29716:32;29757:41;:::i;:::-;29409:524;;29817:7;;-1:-1:-1;;;29897:2:1;29882:18;;;;29869:32;;29409:524::o;29938:824::-;30112:6;30120;30128;30136;30189:3;30177:9;30168:7;30164:23;30160:33;30157:53;;;30206:1;30203;30196:12;30157:53;30245:9;30232:23;30264:39;30297:5;30264:39;:::i;:::-;30322:5;-1:-1:-1;30379:2:1;30364:18;;30351:32;30392:41;30351:32;30392:41;:::i;:::-;30452:7;-1:-1:-1;30478:66:1;30536:7;30531:2;30516:18;;30478:66;:::i;:::-;30468:76;;30595:3;30584:9;30580:19;30567:33;30623:18;30615:6;30612:30;30609:50;;;30655:1;30652;30645:12;30609:50;30678:78;30748:7;30739:6;30728:9;30724:22;30678:78;:::i;:::-;30668:88;;;29938:824;;;;;;;:::o;30767:255::-;30826:6;30879:2;30867:9;30858:7;30854:23;30850:32;30847:52;;;30895:1;30892;30885:12;30847:52;30934:9;30921:23;30953:39;30986:5;30953:39;:::i;:::-;31011:5;30767:255;-1:-1:-1;;;30767:255:1:o;31027:1507::-;31219:6;31227;31235;31243;31251;31259;31267;31275;31283;31291;31344:3;31332:9;31323:7;31319:23;31315:33;31312:53;;;31361:1;31358;31351:12;31312:53;31400:9;31387:23;31419:39;31452:5;31419:39;:::i;:::-;31477:5;-1:-1:-1;31533:2:1;31518:18;;31505:32;31560:18;31549:30;;31546:50;;;31592:1;31589;31582:12;31546:50;31631:89;31712:7;31703:6;31692:9;31688:22;31631:89;:::i;:::-;31739:8;;-1:-1:-1;31605:115:1;-1:-1:-1;;31827:2:1;31812:18;;31799:32;31856:18;31843:32;;31840:52;;;31888:1;31885;31878:12;31840:52;31927:60;31979:7;31968:8;31957:9;31953:24;31927:60;:::i;:::-;32006:8;;-1:-1:-1;31901:86:1;-1:-1:-1;;32114:2:1;32099:18;;32086:32;;-1:-1:-1;32163:39:1;32197:3;32182:19;;32163:39;:::i;:::-;32153:49;;32255:3;32244:9;32240:19;32227:33;32285:18;32275:8;32272:32;32269:52;;;32317:1;32314;32307:12;32269:52;32356:60;32408:7;32397:8;32386:9;32382:24;32356:60;:::i;:::-;32435:8;;-1:-1:-1;32330:86:1;-1:-1:-1;32489:39:1;;-1:-1:-1;32523:3:1;32508:19;;32489:39;:::i;:::-;32479:49;;31027:1507;;;;;;;;;;;;;:::o;32539:641::-;32625:6;32633;32641;32649;32702:2;32690:9;32681:7;32677:23;32673:32;32670:52;;;32718:1;32715;32708:12;32670:52;32763:23;;;-1:-1:-1;32883:2:1;32868:18;;32855:32;;-1:-1:-1;32964:2:1;32949:18;;32936:32;32991:18;32980:30;;32977:50;;;33023:1;33020;33013:12;32977:50;33062:58;33112:7;33103:6;33092:9;33088:22;33062:58;:::i;:::-;32539:641;;;;-1:-1:-1;33139:8:1;-1:-1:-1;;;;32539:641:1:o;33185:182::-;33242:6;33295:2;33283:9;33274:7;33270:23;33266:32;33263:52;;;33311:1;33308;33301:12;33263:52;33334:27;33351:9;33334:27;:::i;34089:602::-;34360:42;34352:6;34348:55;34337:9;34330:74;34452:42;34444:6;34440:55;34435:2;34424:9;34420:18;34413:83;34532:6;34527:2;34516:9;34512:18;34505:34;34575:6;34570:2;34559:9;34555:18;34548:34;34619:3;34613;34602:9;34598:19;34591:32;34311:4;34640:45;34680:3;34669:9;34665:19;34657:6;34640:45;:::i;34696:184::-;34748:77;34745:1;34738:88;34845:4;34842:1;34835:15;34869:4;34866:1;34859:15;37191:192;37270:13;;37323:34;37312:46;;37302:57;;37292:85;;37373:1;37370;37363:12;37388:428;37476:6;37484;37492;37545:2;37533:9;37524:7;37520:23;37516:32;37513:52;;;37561:1;37558;37551:12;37513:52;37584:40;37614:9;37584:40;:::i;:::-;37686:2;37671:18;;37665:25;37780:2;37765:18;;;37759:25;37574:50;;37665:25;;-1:-1:-1;37759:25:1;37388:428;-1:-1:-1;;;37388:428:1:o;38172:230::-;38242:6;38295:2;38283:9;38274:7;38270:23;38266:32;38263:52;;;38311:1;38308;38301:12;38263:52;-1:-1:-1;38356:16:1;;38172:230;-1:-1:-1;38172:230:1:o;38407:325::-;38495:6;38490:3;38483:19;38547:6;38540:5;38533:4;38528:3;38524:14;38511:43;;38599:1;38592:4;38583:6;38578:3;38574:16;38570:27;38563:38;38465:3;38721:4;38651:66;38646:2;38638:6;38634:15;38630:88;38625:3;38621:98;38617:109;38610:116;;38407:325;;;;:::o;38737:629::-;39018:42;39010:6;39006:55;38995:9;38988:74;39110:42;39102:6;39098:55;39093:2;39082:9;39078:18;39071:83;39190:6;39185:2;39174:9;39170:18;39163:34;39233:6;39228:2;39217:9;39213:18;39206:34;39277:3;39271;39260:9;39256:19;39249:32;38969:4;39298:62;39355:3;39344:9;39340:19;39332:6;39324;39298:62;:::i;39371:580::-;39448:4;39454:6;39514:11;39501:25;39604:66;39593:8;39577:14;39573:29;39569:102;39549:18;39545:127;39535:155;;39686:1;39683;39676:12;39535:155;39713:33;;39765:20;;;-1:-1:-1;39808:18:1;39797:30;;39794:50;;;39840:1;39837;39830:12;39794:50;39873:4;39861:17;;-1:-1:-1;39904:14:1;39900:27;;;39890:38;;39887:58;;;39941:1;39938;39931:12;39956:160;40022:20;;40082:1;40071:20;;;40061:31;;40051:59;;40106:1;40103;40096:12;40217:1670;40409:3;40394:19;;40422:57;40398:9;40441:26;40460:6;40441:26;:::i;:::-;7667:42;7656:54;7644:67;;7590:127;40422:57;40508:37;40539:4;40531:6;40527:17;40508:37;:::i;:::-;7667:42;7656:54;40602:4;40587:20;;7644:67;40639:35;40668:4;40656:17;;40639:35;:::i;:::-;40683:54;40731:4;40720:9;40716:20;40700:14;40196:1;40185:20;40173:33;;40121:91;40683:54;;40768:35;40797:4;40789:6;40785:17;40768:35;:::i;:::-;40812:54;40860:4;40849:9;40845:20;40829:14;40196:1;40185:20;40173:33;;40121:91;40812:54;;40897:35;40926:4;40918:6;40914:17;40897:35;:::i;:::-;40941:54;40989:4;40978:9;40974:20;40958:14;40196:1;40185:20;40173:33;;40121:91;40941:54;-1:-1:-1;41061:4:1;41049:17;;;41036:31;41083:20;;;41076:35;41181:4;41169:17;;;41156:31;41203:20;;;41196:37;41303:4;41291:17;;;41278:31;41325:20;;;41318:37;41425:6;41413:19;;;41400:33;41449:22;;;41442:39;41512;41543:6;41531:19;;41512:39;:::i;:::-;7667:42;7656:54;41610:6;41595:22;;7644:67;41688:6;41676:19;;;41663:33;41712:22;;;41705:39;41775;41806:6;41794:19;;41775:39;:::i;:::-;7667:42;7656:54;;41873:6;41858:22;;7644:67;41823:58;7590:127;41892:542;41989:6;41997;42005;42013;42066:3;42054:9;42045:7;42041:23;42037:33;42034:53;;;42083:1;42080;42073:12;42034:53;42128:16;;;-1:-1:-1;42187:49:1;42232:2;42217:18;;42187:49;:::i;:::-;42302:2;42287:18;;42281:25;42398:2;42383:18;;;42377:25;41892:542;;42177:59;;-1:-1:-1;41892:542:1;-1:-1:-1;;;41892:542:1:o;42439:244::-;42596:2;42585:9;42578:21;42559:4;42616:61;42673:2;42662:9;42658:18;42650:6;42642;42616:61;:::i;42688:259::-;42758:6;42811:2;42799:9;42790:7;42786:23;42782:32;42779:52;;;42827:1;42824;42817:12;42779:52;42859:9;42853:16;42878:39;42911:5;42878:39;:::i;42952:271::-;43135:6;43127;43122:3;43109:33;43091:3;43161:16;;43186:13;;;43161:16;42952:271;-1:-1:-1;42952:271:1:o;43228:686::-;43308:6;43361:2;43349:9;43340:7;43336:23;43332:32;43329:52;;;43377:1;43374;43367:12;43329:52;43410:9;43404:16;43443:18;43435:6;43432:30;43429:50;;;43475:1;43472;43465:12;43429:50;43498:22;;43551:4;43543:13;;43539:27;-1:-1:-1;43529:55:1;;43580:1;43577;43570:12;43529:55;43613:2;43607:9;43638:52;43654:35;43682:6;43654:35;:::i;43638:52::-;43713:6;43706:5;43699:21;43761:7;43756:2;43747:6;43743:2;43739:15;43735:24;43732:37;43729:57;;;43782:1;43779;43772:12;43729:57;43830:6;43825:2;43821;43817:11;43812:2;43805:5;43801:14;43795:42;43882:1;43857:18;;;43877:2;43853:27;43846:38;;;;43861:5;43228:686;-1:-1:-1;;;;43228:686:1:o;43919:219::-;44068:2;44057:9;44050:21;44031:4;44088:44;44128:2;44117:9;44113:18;44105:6;44088:44;:::i;46226:184::-;46278:77;46275:1;46268:88;46375:4;46372:1;46365:15;46399:4;46396:1;46389:15;46415:128;46482:9;;;46503:11;;;46500:37;;;46517:18;;:::i;46548:619::-;46797:3;46786:9;46779:22;46760:4;46824:45;46864:3;46853:9;46849:19;46841:6;46824:45;:::i;:::-;46917:42;46909:6;46905:55;46900:2;46889:9;46885:18;46878:83;47009:42;47001:6;46997:55;46992:2;46981:9;46977:18;46970:83;47101:9;47093:6;47089:22;47084:2;47073:9;47069:18;47062:50;47129:32;47154:6;47146;47129:32;:::i;47172:630::-;47241:5;47289:4;47277:9;47272:3;47268:19;47264:30;47261:50;;;47307:1;47304;47297:12;47261:50;47360:4;47354:11;;;47392:17;;47439:18;47424:34;;47460:22;;;47421:62;47418:88;;;47486:18;;:::i;:::-;47528:10;47522:4;47515:24;;47557:6;47548:15;;47593:9;47587:16;47612:41;47645:7;47612:41;:::i;:::-;47662:23;;47751:2;47736:18;;;47730:25;47771:15;;47764:32;;;;47172:630;;-1:-1:-1;47172:630:1:o;47807:257::-;47906:6;47959:2;47947:9;47938:7;47934:23;47930:32;47927:52;;;47975:1;47972;47965:12;47927:52;47998:60;48050:7;48039:9;47998:60;:::i;48371:1013::-;48736:42;48728:6;48724:55;48713:9;48706:74;48830:6;48823:14;48816:22;48811:2;48800:9;48796:18;48789:50;48875:6;48870:2;48859:9;48855:18;48848:34;48930:42;48922:6;48918:55;48913:2;48902:9;48898:18;48891:83;49011:3;49005;48994:9;48990:19;48983:32;48687:4;49038:45;49078:3;49067:9;49063:19;49055:6;49038:45;:::i;:::-;49132:42;49124:6;49120:55;49114:3;49103:9;49099:19;49092:84;49225:42;49217:6;49213:55;49207:3;49196:9;49192:19;49185:84;49318:9;49310:6;49306:22;49300:3;49289:9;49285:19;49278:51;49346:32;49371:6;49363;49346:32;:::i;49389:341::-;49466:6;49474;49527:2;49515:9;49506:7;49502:23;49498:32;49495:52;;;49543:1;49540;49533:12;49495:52;-1:-1:-1;;49588:16:1;;49694:2;49679:18;;;49673:25;49588:16;;49673:25;;-1:-1:-1;49389:341:1:o;49735:191::-;49770:3;49801:66;49794:5;49791:77;49788:103;;49871:18;;:::i;:::-;-1:-1:-1;49911:1:1;49907:13;;49735:191::o;49931:125::-;49996:9;;;50017:10;;;50014:36;;;50030:18;;:::i;50483:245::-;50550:6;50603:2;50591:9;50582:7;50578:23;50574:32;50571:52;;;50619:1;50616;50609:12;50571:52;50651:9;50645:16;50670:28;50692:5;50670:28;:::i;50733:646::-;50992:3;50981:9;50974:22;50955:4;51019:45;51059:3;51048:9;51044:19;51036:6;51019:45;:::i;:::-;51112:42;51104:6;51100:55;51095:2;51084:9;51080:18;51073:83;51204:42;51196:6;51192:55;51187:2;51176:9;51172:18;51165:83;51296:9;51288:6;51284:22;51279:2;51268:9;51264:18;51257:50;51324:49;51366:6;51358;51350;51324:49;:::i;51384:959::-;51508:6;51561:2;51549:9;51540:7;51536:23;51532:32;51529:52;;;51577:1;51574;51567:12;51529:52;51610:9;51604:16;51643:18;51635:6;51632:30;51629:50;;;51675:1;51672;51665:12;51629:50;51698:22;;51751:4;51743:13;;51739:27;-1:-1:-1;51729:55:1;;51780:1;51777;51770:12;51729:55;51813:2;51807:9;51836:72;51852:55;51900:6;51852:55;:::i;51836:72::-;51930:3;51954:6;51949:3;51942:19;51986:2;51981:3;51977:12;51970:19;;52041:2;52031:6;52028:1;52024:14;52020:2;52016:23;52012:32;51998:46;;52067:7;52059:6;52056:19;52053:39;;;52088:1;52085;52078:12;52053:39;52120:2;52116;52112:11;52101:22;;52132:181;52148:6;52143:3;52140:15;52132:181;;;52216:54;52262:7;52257:3;52216:54;:::i;:::-;52211:3;52204:67;52300:2;52295:3;52291:12;52284:19;;52174:4;52169:3;52165:14;52158:21;;52132:181;;52348:651;52435:6;52495:2;52483:9;52474:7;52470:23;52466:32;52510:2;52507:22;;;52525:1;52522;52515:12;52507:22;-1:-1:-1;52567:22:1;;:::i;:::-;52626:9;52613:23;52645:41;52678:7;52645:41;:::i;:::-;52695:22;;52790:2;52775:18;;;52762:32;52810:14;;;52803:31;52886:2;52871:18;;52858:32;52899:30;52858:32;52899:30;:::i;:::-;52956:2;52945:14;;52938:31;52949:5;52348:651;-1:-1:-1;;;52348:651:1:o;53004:673::-;53273:3;53262:9;53255:22;53236:4;53300:62;53357:3;53346:9;53342:19;53334:6;53326;53300:62;:::i;:::-;53410:42;53402:6;53398:55;53393:2;53382:9;53378:18;53371:83;53502:42;53494:6;53490:55;53485:2;53474:9;53470:18;53463:83;53594:9;53586:6;53582:22;53577:2;53566:9;53562:18;53555:50;53622:49;53664:6;53656;53648;53622:49;:::i;:::-;53614:57;53004:673;-1:-1:-1;;;;;;;;;53004:673:1:o;53682:301::-;53811:3;53849:6;53843:13;53895:6;53888:4;53880:6;53876:17;53871:3;53865:37;53957:1;53921:16;;53946:13;;;-1:-1:-1;53921:16:1;53682:301;-1:-1:-1;53682:301:1:o

Swarm Source

ipfs://f4d732f610e8f230a2bc90c91cfdeabcdd828565752199e1013b215972a64090

Block Transaction Gas Used Reward
view all blocks sequenced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.