ETH Price: $3,417.04 (-2.38%)
Gas: 8 Gwei

Contract

0x5954BD7E5E1dB3d421a2e39eF66948aAc524EdC6
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Zap From Token183709752023-10-17 15:25:59274 days ago1697556359IN
ChainTools: Uniswap V3 Utils
0 ETH0.0080451912.10699463
Zap From Token183360952023-10-12 18:22:59279 days ago1697134979IN
ChainTools: Uniswap V3 Utils
0 ETH0.006748719.11722747
Zap From Token183000792023-10-07 17:24:11284 days ago1696699451IN
ChainTools: Uniswap V3 Utils
0 ETH0.003989775.49575293
Zap From Token182809842023-10-05 1:19:11287 days ago1696468751IN
ChainTools: Uniswap V3 Utils
0 ETH0.006215296.09385489
Zap From Token182237852023-09-27 1:20:59295 days ago1695777659IN
ChainTools: Uniswap V3 Utils
0 ETH0.00538667.78449611
Zap From Token182237682023-09-27 1:17:23295 days ago1695777443IN
ChainTools: Uniswap V3 Utils
0 ETH0.005545318.0592944
Zap From Token181691452023-09-19 9:44:11302 days ago1695116651IN
ChainTools: Uniswap V3 Utils
0 ETH0.0067771210.65681157
Zap From Token181615302023-09-18 8:04:23303 days ago1695024263IN
ChainTools: Uniswap V3 Utils
0 ETH0.004985867.72057355
Zap From Token181526042023-09-17 1:44:35305 days ago1694915075IN
ChainTools: Uniswap V3 Utils
0 ETH0.008903788.70866247
Zap From Token181519722023-09-16 23:33:47305 days ago1694907227IN
ChainTools: Uniswap V3 Utils
0 ETH0.004549127.33569847
Zap From Token181450692023-09-16 0:09:59306 days ago1694822999IN
ChainTools: Uniswap V3 Utils
0 ETH0.005923317.65499915
Zap From Token181211332023-09-12 15:26:35309 days ago1694532395IN
ChainTools: Uniswap V3 Utils
0 ETH0.0196816828.44812016
Zap From Token181105122023-09-11 3:44:11311 days ago1694403851IN
ChainTools: Uniswap V3 Utils
0 ETH0.006650278.7441603
Zap From Token180956142023-09-09 1:38:47313 days ago1694223527IN
ChainTools: Uniswap V3 Utils
0 ETH0.007167819.9920404
Zap From Token180811052023-09-07 0:54:23315 days ago1694048063IN
ChainTools: Uniswap V3 Utils
0 ETH0.0074782310.99897153
Zap From Token180807962023-09-06 23:52:11315 days ago1694044331IN
ChainTools: Uniswap V3 Utils
0 ETH0.0069406310.63227275
Zap From Token180801962023-09-06 21:51:47315 days ago1694037107IN
ChainTools: Uniswap V3 Utils
0 ETH0.0134228518.5886678
Zap From Token180723372023-09-05 19:24:23316 days ago1693941863IN
ChainTools: Uniswap V3 Utils
0 ETH0.0115630716.50363667
Zap From Token180691612023-09-05 8:43:35316 days ago1693903415IN
ChainTools: Uniswap V3 Utils
0 ETH0.0074650510.40996533
Zap From Token180654592023-09-04 20:19:23317 days ago1693858763IN
ChainTools: Uniswap V3 Utils
0 ETH0.0170690823.10801997
Zap From Token180578562023-09-03 18:49:11318 days ago1693766951IN
ChainTools: Uniswap V3 Utils
0 ETH0.0126504716.90157246
Zap From Token180554152023-09-03 10:36:35318 days ago1693737395IN
ChainTools: Uniswap V3 Utils
0 ETH0.0077803910.27495569
Zap From Token180278112023-08-30 13:48:35322 days ago1693403315IN
ChainTools: Uniswap V3 Utils
0 ETH0.0186204225.07912268
Zap From Token180205702023-08-29 13:28:23323 days ago1693315703IN
ChainTools: Uniswap V3 Utils
0 ETH0.0131909917.54030312
Zap From Token179996192023-08-26 15:04:59326 days ago1693062299IN
ChainTools: Uniswap V3 Utils
0 ETH0.0119742620.14048706
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
183709752023-10-17 15:25:59274 days ago1697556359
ChainTools: Uniswap V3 Utils
2.28773466 ETH
183709752023-10-17 15:25:59274 days ago1697556359
ChainTools: Uniswap V3 Utils
2.28773466 ETH
183360952023-10-12 18:22:59279 days ago1697134979
ChainTools: Uniswap V3 Utils
2.12481538 ETH
183360952023-10-12 18:22:59279 days ago1697134979
ChainTools: Uniswap V3 Utils
2.12481538 ETH
183000792023-10-07 17:24:11284 days ago1696699451
ChainTools: Uniswap V3 Utils
0.24788539 ETH
183000792023-10-07 17:24:11284 days ago1696699451
ChainTools: Uniswap V3 Utils
0.24788539 ETH
182809842023-10-05 1:19:11287 days ago1696468751
ChainTools: Uniswap V3 Utils
9.65556988 ETH
182809842023-10-05 1:19:11287 days ago1696468751
ChainTools: Uniswap V3 Utils
9.65556988 ETH
182237852023-09-27 1:20:59295 days ago1695777659
ChainTools: Uniswap V3 Utils
2.64097893 ETH
182237852023-09-27 1:20:59295 days ago1695777659
ChainTools: Uniswap V3 Utils
2.64097893 ETH
182237682023-09-27 1:17:23295 days ago1695777443
ChainTools: Uniswap V3 Utils
5.39722787 ETH
182237682023-09-27 1:17:23295 days ago1695777443
ChainTools: Uniswap V3 Utils
5.39722787 ETH
181691452023-09-19 9:44:11302 days ago1695116651
ChainTools: Uniswap V3 Utils
0.75573902 ETH
181691452023-09-19 9:44:11302 days ago1695116651
ChainTools: Uniswap V3 Utils
0.75573902 ETH
181615302023-09-18 8:04:23303 days ago1695024263
ChainTools: Uniswap V3 Utils
0.3567087 ETH
181615302023-09-18 8:04:23303 days ago1695024263
ChainTools: Uniswap V3 Utils
0.3567087 ETH
181526042023-09-17 1:44:35305 days ago1694915075
ChainTools: Uniswap V3 Utils
0.00006212 ETH
181526042023-09-17 1:44:35305 days ago1694915075
ChainTools: Uniswap V3 Utils
0.00006212 ETH
181519722023-09-16 23:33:47305 days ago1694907227
ChainTools: Uniswap V3 Utils
0.03469304 ETH
181519722023-09-16 23:33:47305 days ago1694907227
ChainTools: Uniswap V3 Utils
0.03469304 ETH
181450692023-09-16 0:09:59306 days ago1694822999
ChainTools: Uniswap V3 Utils
1.00357888 ETH
181450692023-09-16 0:09:59306 days ago1694822999
ChainTools: Uniswap V3 Utils
1.00357888 ETH
181211332023-09-12 15:26:35309 days ago1694532395
ChainTools: Uniswap V3 Utils
0.08560329 ETH
181211332023-09-12 15:26:35309 days ago1694532395
ChainTools: Uniswap V3 Utils
0.08560329 ETH
181105122023-09-11 3:44:11311 days ago1694403851
ChainTools: Uniswap V3 Utils
0.04373267 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainToolsV3Utils

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 42000 runs

Other Settings:
default evmVersion, None license
File 1 of 1 : v3Utils.sol
/*                              
                    CHAINTOOLS 2023. DEFI REIMAGINED

                                                               2023

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀            2021           ⣰⣾⣿⣶⡄⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀2019⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀     ⠹⣿V4⡄⡷⠀⠀⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⠀⠀⠀⠀⠀⠀⠀⠀ ⣤⣾⣿⣷⣦⡀⠀⠀⠀⠀   ⣿⣿⡏⠁⠀⠀⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣿⣿⣿⣷⡀⠀⠀⠀⠀ ⢀⣿⣿⣿⣿⣿⠄⠀⠀⠀  ⣰⣿⣿⣧⠀⠀⠀⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣾⣿⣿⣿⣿⣿⣿⡄⠀⠀ ⢀⣴⣿⣿⣿⠟⠛⠋⠀⠀⠀ ⢸⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣿⣿⣿⣿⣿⠟⠉⠉⠉⠁⢀⣴⣿⣿V3⣿⣿⠀⠀⠀⠀⠀  ⣾⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⣾⣿⣿⣿⣿⣿⠛⠀⠀⠀⠀⠀ ⣾⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀ ⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀   
⠀⠀⠀        2017⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿V2⣿⣿⡿⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀ ⢹⣿ ⣿⣿⣿⣿⠙⢿⣆⠀⠀⠀   
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣴⣦⣤⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⠛⠿⠿⠶⠶⣶⠀  ⣿ ⢸⣿⣿⣿⣿⣆⠹⠇⠀⠀   
⠀⠀⠀⠀⠀⠀⢀⣠⣴⣿⣿⣿⣿⣷⡆⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⡇⠉⠛⢿⣷⡄⠀⠀⠀⢸⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀  ⠹⠇⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀   
⠀⠀⠀⠀⣠⣴⣿⣿V1⣿⣿⣿⡏⠛⠃⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣇⠀⠀⠘⠋⠁⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀  ⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀   
⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀ ⠸⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀  ⠀⣿⣿⡟⢿⣿⣿⠀⠀⠀⠀   
⠀⢸⣿⣿⣿⣿⣿⠛⠉⠙⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀ ⢈⣿⣿⡟⢹⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⡿⠈⣿⣿⡟⠀⠀⠀⠀⠀  ⢸⣿⣿⠀⢸⣿⣿⠀⠀⠀⠀   
⠀⠀⠹⣿⣿⣿⣿⣷⡀⠀⠻⣿⣿⣿⣿⣶⣄⠀⠀⠀⢰⣿⣿⡟⠁⣾⣿⣿⠀⠀⠀⠀⠀⠀⢀⣶⣿⠟⠋⠀⢼⣿⣿⠃⠀⠀⠀⠀⠀  ⣿⣿⠁⠀⢹⣿⣿⠀⠀⠀⠀   
⠀⢀⣴⣿⡿⠋⢹⣿⡇⠀⠀⠈⠙⣿⣇⠙⣿⣷⠀⠀⢸⣿⡟⠀⠀⢻⣿⡏⠀⠀⠀⠀⠀⢀⣼⡿⠁⠀⠀⠀⠘⣿⣿⠀⠀⠀⠀⠀   ⢨⣿⡇⠀⠀⠀⣿⣿⠀⠀⠀⠀   
⣴⣿⡟⠉⠀⠀⣾⣿⡇⠀⠀⠀⠀⢈⣿⡄⠀⠉⠀⠀⣼⣿⡆⠀⠀⢸⣿⣷⠀⠀⠀⠀⢴⣿⣿⠀⠀⠀⠀⠀⠀⣿⣯⡀⠀⠀⠀⠀    ⢸⣿⣇⠀⠀⠀⢺⣿⡄⠀⠀⠀   
⠈⠻⠷⠄⠀⠀⣿⣿⣷⣤⣠⠀⠀⠈⠽⠷⠀⠀⠀⠸⠟⠛⠛⠒⠶⠸⣿⣿⣷⣦⣤⣄⠈⠻⠷⠄⠀⠀⠀⠾⠿⠿⣿⣶⣤⠀    ⠘⠛⠛⠛⠒⠀⠸⠿⠿⠦ 


Telegram: https://t.me/ChaintoolsOfficial
Website: https://www.chaintools.ai/
Whitepaper: https://chaintools-whitepaper.gitbook.io/
Twitter: https://twitter.com/ChaintoolsTech
dApp: https://www.chaintools.wtf/
*/

// import "forge-std/console.sol";

interface IERC20 {
    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function transfer(
        address recipient,
        uint256 amount
    ) external returns (bool);

    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

interface IUniswapV2Factory {
    function createPair(
        address tokenA,
        address tokenB
    ) external returns (address pair);
}

interface IUniswapV2Router02 {
    function getAmountsOut(
        uint256 amountIn,
        address[] memory path
    ) external view returns (uint256[] memory amounts);

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
}

interface IV2Pair {
    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function sync() external;

    function token0() external view returns (address);

    function token1() external view returns (address);

    function mint(address to) external returns (uint256 liquidity);

    function kLast() external view returns (uint lastK);

    function getReserves()
        external
        view
        returns (uint stamp, uint res0, uint res1);

    function burn(
        address to
    ) external returns (uint256 amount0, uint256 amount1);
}

interface IV3Pool {
    function liquidity() external view returns (uint128 Liq);

    struct Info {
        // the amount of liquidity owned by this position
        uint128 liquidity;
        // fee growth per unit of liquidity as of the last update to liquidity or fees owed
        uint256 feeGrowthInside0LastX128;
        uint256 feeGrowthInside1LastX128;
        // the fees owed to the position owner in token0/token1
        uint128 tokensOwed0;
        uint128 tokensOwed1;
    }

    function initialize(uint160 sqrtPriceX96) external;

    function positions(
        bytes32 key
    ) external view returns (IV3Pool.Info memory liqInfo);

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

    function burn(
        int24 tickLower,
        int24 tickUpper,
        uint128 amount
    ) external returns (uint256 amount0, uint256 amount1);

    function collect(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount0Requested,
        uint128 amount1Requested
    ) external returns (uint128 amount0, uint128 amount1);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function slot0()
        external
        view
        returns (uint160, int24, uint16, uint16, uint16, uint8, bool);

    function flash(
        address recipient,
        uint256 amount0,
        uint256 amount1,
        bytes calldata data
    ) external;

    function uniswapV3FlashCallback(
        uint256 fee0,
        uint256 fee1,
        bytes memory data
    ) external;

    function mint(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount,
        bytes calldata data
    ) external returns (uint256 amount0, uint256 amount1);
}

interface IWETH {
    function withdraw(uint256 wad) external;

    function approve(address who, uint256 wad) external returns (bool);

    function deposit() external payable;

    function transfer(address dst, uint256 wad) external returns (bool);

    function balanceOf(address _owner) external view returns (uint256);
}

interface IQuoterV2 {
    function quoteExactInputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountIn,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountOut);
}

interface IV3Factory {
    function getPool(
        address token0,
        address token1,
        uint24 poolFee
    ) external view returns (address);

    function createPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external returns (address);
}

interface INonfungiblePositionManager {
    function ownerOf(uint256 tokenId) external view returns (address owner);

    function setApprovalForAll(address operator, bool approved) external;

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

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

    function tokenOfOwnerByIndex(
        address owner,
        uint256 index
    ) external view returns (uint256 tokenId);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) external;

    function transferFrom(address from, address to, uint256 tokenId) external;

    function factory() external view returns (address);

    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

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

    function collect(
        CollectParams calldata params
    ) external payable returns (uint256 amount0, uint256 amount1);

    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    function decreaseLiquidity(
        DecreaseLiquidityParams calldata dl
    ) external returns (uint256 amount0, uint256 amount1);

    function positions(
        uint256 tokenId
    )
        external
        view
        returns (
            uint96 nonce,
            address operator,
            address token0,
            address token1,
            uint24 fee,
            int24 tickLower,
            int24 tickUpper,
            uint128 liquidity,
            uint256 feeGrowthInside0LastX128,
            uint256 feeGrowthInside1LastX128,
            uint128 tokensOwed0,
            uint128 tokensOwed1
        );
}

interface IRouterV3 {
    function factory() external view returns (address);

    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    function WETH9() external view returns (address);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    function exactOutputSingle(
        ExactOutputSingleParams calldata params
    ) external returns (uint256 amountIn);

    function exactInputSingle(
        ExactInputSingleParams calldata params
    ) external payable returns (uint256 amountOut);
}

library FixedPoint96 {
    uint8 internal constant RESOLUTION = 96;
    uint256 internal constant Q96 = 0x1000000000000000000000000;
}

library FullMath {
    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b
            // Compute the product mod 2**256 and mod 2**256 - 1
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(a, b, not(0))
                prod0 := mul(a, b)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                require(denominator > 0);
                assembly {
                    result := div(prod0, denominator)
                }
                return result;
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator
            // Compute largest power of two divisor of denominator.
            // Always >= 1.
            uint256 twos = uint256(-int256(denominator) & int256(denominator));
            // console.log(twos, "TWOS?!??!?!?!");
            // Divide denominator by power of two
            assembly {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos.
            // If twos is zero, then it becomes one
            assembly {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;

            // Invert denominator mod 2**256
            // Now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // correct for four bits. That is, denominator * inv = 1 mod 2**4
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // inverse mod 2**8
            inv *= 2 - denominator * inv; // inverse mod 2**16
            inv *= 2 - denominator * inv; // inverse mod 2**32
            inv *= 2 - denominator * inv; // inverse mod 2**64
            inv *= 2 - denominator * inv; // inverse mod 2**128
            inv *= 2 - denominator * inv; // inverse mod 2**256

            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the precoditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }

    /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    function mulDivRoundingUp(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            result = mulDiv(a, b, denominator);
            if (mulmod(a, b, denominator) > 0) {
                require(result < type(uint256).max);
                result++;
            }
        }
    }
}

library Babylonian {
    // credit for this implementation goes to
    // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687
    function sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;
        // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2);
        // however that code costs significantly more gas
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) {
            xx >>= 128;
            r <<= 64;
        }
        if (xx >= 0x10000000000000000) {
            xx >>= 64;
            r <<= 32;
        }
        if (xx >= 0x100000000) {
            xx >>= 32;
            r <<= 16;
        }
        if (xx >= 0x10000) {
            xx >>= 16;
            r <<= 8;
        }
        if (xx >= 0x100) {
            xx >>= 8;
            r <<= 4;
        }
        if (xx >= 0x10) {
            xx >>= 4;
            r <<= 2;
        }
        if (xx >= 0x8) {
            r <<= 1;
        }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return (r < r1 ? r : r1);
    }
}

library LiquidityAmounts {
    /// @notice Downcasts uint256 to uint128
    /// @param x The uint258 to be downcasted
    /// @return y The passed value, downcasted to uint128
    function toUint128(uint256 x) private pure returns (uint128 y) {
        require((y = uint128(x)) == x);
    }

    /// @notice Computes the amount of token0 for a given amount of liquidity and a price range
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount0 The amount of token0
    function getAmount0ForLiquidity(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount0) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        return
            FullMath.mulDiv(
                uint256(liquidity) << FixedPoint96.RESOLUTION,
                sqrtRatioBX96 - sqrtRatioAX96,
                sqrtRatioBX96
            ) / sqrtRatioAX96;
    }

    /// @notice Computes the amount of token1 for a given amount of liquidity and a price range
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount1 The amount of token1
    function getAmount1ForLiquidity(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount1) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        return
            FullMath.mulDiv(
                liquidity,
                sqrtRatioBX96 - sqrtRatioAX96,
                FixedPoint96.Q96
            );
    }

    /// @notice Computes the token0 and token1 value for a given amount of liquidity, the current
    /// pool prices and the prices at the tick boundaries
    /// @param sqrtRatioX96 A sqrt price representing the current pool prices
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount0 The amount of token0
    /// @return amount1 The amount of token1
    function getAmountsForLiquidity(
        uint160 sqrtRatioX96,
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount0, uint256 amount1) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        if (sqrtRatioX96 <= sqrtRatioAX96) {
            amount0 = getAmount0ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioBX96,
                liquidity
            );
        } else if (sqrtRatioX96 < sqrtRatioBX96) {
            amount0 = getAmount0ForLiquidity(
                sqrtRatioX96,
                sqrtRatioBX96,
                liquidity
            );
            amount1 = getAmount1ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioX96,
                liquidity
            );
        } else {
            amount1 = getAmount1ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioBX96,
                liquidity
            );
        }
    }

    /// @notice Computes the amount of liquidity received for a given amount of token0 and price range
    /// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower))
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param amount0 The amount0 being sent in
    /// @return liquidity The amount of returned liquidity
    function getLiquidityForAmount0(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint256 amount0
    ) internal pure returns (uint128 liquidity) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
        uint256 intermediate = FullMath.mulDiv(
            sqrtRatioAX96,
            sqrtRatioBX96,
            uint256(0x1000000000000000000000000)
        );
        return
            toUint128(
                FullMath.mulDiv(
                    amount0,
                    intermediate,
                    sqrtRatioBX96 - sqrtRatioAX96
                )
            );
    }

    /// @notice Computes the amount of liquidity received for a given amount of token1 and price range
    /// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)).
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param amount1 The amount1 being sent in
    /// @return liquidity The amount of returned liquidity
    function getLiquidityForAmount1(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint256 amount1
    ) internal pure returns (uint128 liquidity) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
        return
            toUint128(
                FullMath.mulDiv(
                    amount1,
                    uint256(0x1000000000000000000000000),
                    sqrtRatioBX96 - sqrtRatioAX96
                )
            );
    }

    /// @notice Computes the maximum amount of liquidity received for a given amount of token0, token1, the current
    /// pool prices and the prices at the tick boundaries
    /// @param sqrtRatioX96 A sqrt price representing the current pool prices
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param amount0 The amount of token0 being sent in
    /// @param amount1 The amount of token1 being sent in
    /// @return liquidity The maximum amount of liquidity received
    function getLiquidityForAmounts(
        uint160 sqrtRatioX96,
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint256 amount0,
        uint256 amount1
    ) internal pure returns (uint128 liquidity) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        if (sqrtRatioX96 <= sqrtRatioAX96) {
            liquidity = getLiquidityForAmount0(
                sqrtRatioAX96,
                sqrtRatioBX96,
                amount0
            );
        } else if (sqrtRatioX96 < sqrtRatioBX96) {
            uint128 liquidity0 = getLiquidityForAmount0(
                sqrtRatioX96,
                sqrtRatioBX96,
                amount0
            );
            uint128 liquidity1 = getLiquidityForAmount1(
                sqrtRatioAX96,
                sqrtRatioX96,
                amount1
            );

            liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;
        } else {
            liquidity = getLiquidityForAmount1(
                sqrtRatioAX96,
                sqrtRatioBX96,
                amount1
            );
        }
    }
}

library TickMath {
    /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128
    int24 internal constant MIN_TICK = -887272;
    /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128
    int24 internal constant MAX_TICK = 887272;

    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)
    uint160 internal constant MIN_SQRT_RATIO = 4295128739;
    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)
    uint160 internal constant MAX_SQRT_RATIO =
        1461446703485210103287273052203988822378723970342;

    /// @notice Calculates sqrt(1.0001^tick) * 2^96
    /// @dev Throws if |tick| > max tick
    /// @param tick The input tick for the above formula
    /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)
    /// at the given tick
    function getSqrtRatioAtTick(
        int24 tick
    ) internal pure returns (uint160 sqrtPriceX96) {
        uint256 absTick = tick < 0
            ? uint256(-int256(tick))
            : uint256(int256(tick));
        require(absTick <= uint256(int256(MAX_TICK)), "T");

        uint256 ratio = absTick & 0x1 != 0
            ? 0xfffcb933bd6fad37aa2d162d1a594001
            : 0x100000000000000000000000000000000;
        if (absTick & 0x2 != 0)
            ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
        if (absTick & 0x4 != 0)
            ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
        if (absTick & 0x8 != 0)
            ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
        if (absTick & 0x10 != 0)
            ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
        if (absTick & 0x20 != 0)
            ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
        if (absTick & 0x40 != 0)
            ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
        if (absTick & 0x80 != 0)
            ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
        if (absTick & 0x100 != 0)
            ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
        if (absTick & 0x200 != 0)
            ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
        if (absTick & 0x400 != 0)
            ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
        if (absTick & 0x800 != 0)
            ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
        if (absTick & 0x1000 != 0)
            ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
        if (absTick & 0x2000 != 0)
            ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
        if (absTick & 0x4000 != 0)
            ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
        if (absTick & 0x8000 != 0)
            ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
        if (absTick & 0x10000 != 0)
            ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
        if (absTick & 0x20000 != 0)
            ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
        if (absTick & 0x40000 != 0)
            ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
        if (absTick & 0x80000 != 0)
            ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

        if (tick > 0) ratio = type(uint256).max / ratio;

        // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.
        // we then downcast because we know the result always fits within 160 bits due to our tick input constraint
        // we round up in the division so getTickAtSqrtRatio of the output price is always consistent
        sqrtPriceX96 = uint160(
            (ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)
        );
    }
}

interface IYieldVault {
    function balanceOf(
        uint tokenId
    ) external view returns (uint128 b0, uint128 b1);
}

interface IV2Factory {
    function getPair(address, address) external view returns (address);
}

interface IChainTools {
    function adjustFomo(uint16 a, uint256 b, address w) external;

    function zapFromETH(
        uint256 minOut,
        address to,
        uint256 flag,
        address upper
    ) external payable returns (uint256 tokenId);

    function getYieldBooster() external view returns (address yb);

    function swapBack() external;

    function flashReward() external;

    function getUpperRef(address who) external view returns (address ref);
}

contract ChainToolsV3Utils {
    //New - Router
    IUniswapV2Router02 internal immutable router;
    INonfungiblePositionManager internal immutable positionManager;
    IV2Factory internal immutable v2Factory;
    address internal immutable quoter;
    address internal CTLS;
    address internal immutable WETH;
    address internal immutable multiSig;
    address internal immutable dev = msg.sender;
    address internal immutable v3Router;
    address internal immutable uniswapV3Pool;
    IYieldVault internal yieldVault;

    error Auth();
    error Max0();
    error Max1();

    constructor(address _ctls, address _v3pool) {
        positionManager = INonfungiblePositionManager(
            0xC36442b4a4522E871399CD717aBDD847Ab11FE88
        );
        v2Factory = IV2Factory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f);
        router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        CTLS = _ctls;
        v3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
        WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

        IERC20(WETH).approve(address(positionManager), type(uint256).max);
        IERC20(CTLS).approve(address(positionManager), type(uint256).max);
        quoter = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6;
        multiSig = 0xb0Df68E0bf4F54D06A4a448735D2a3d7D97A2222;
        IERC20(WETH).approve(address(v3Router), type(uint256).max);
        IERC20(CTLS).approve(address(v3Router), type(uint256).max);
        uniswapV3Pool = _v3pool;
    }


    function getAmountOut(
        uint amountIn,
        uint reserveIn,
        uint reserveOut
    ) internal pure returns (uint amountOut) {
        uint amountInWithFee = amountIn * 997;
        amountOut =
            (amountInWithFee * reserveOut) /
            ((reserveIn * 1000) + amountInWithFee);
    }

    function _swapV2TokenIn(
        address token,
        address _pair,
        uint amount,
        uint minOut,
        bool isToken0Weth
    ) internal returns (uint amountOut) {
        token.call(
                abi.encodeWithSelector(
                    IERC20.transferFrom.selector,
                    msg.sender,
                    _pair,
                    amount
                )
        );

        if (isToken0Weth) {
            
            (uint reserve0, uint reserve1, ) = IV2Pair(_pair)
                .getReserves();
            uint balAft = IERC20(token).balanceOf(_pair);
            amountOut = getAmountOut(balAft - reserve1, reserve1, reserve0);
            if (minOut > amountOut) revert Max0();
            assembly {

                let inputMem := mload(0x40)
                mstore(
                    inputMem,
                    0x022c0d9f00000000000000000000000000000000000000000000000000000000
                )
                mstore(add(inputMem, 0x04), amountOut)
                mstore(add(inputMem, 0x24), 0)
                mstore(add(inputMem, 0x44), address())
                mstore(add(inputMem, 0x64), 0x80)
                mstore(add(inputMem, 0x84), 0)
                pop(call(gas(), _pair, 0, inputMem, 0xA4, 0, 0))
            }
        } else {
            (uint256 reserve0, uint256 reserve1, ) = IV2Pair(_pair)
                .getReserves();

            uint256 balAft = IERC20(token).balanceOf(_pair);
            amountOut = getAmountOut(balAft - reserve0, reserve0, reserve1);
            if (minOut > amountOut) revert Max0();
            
            assembly {
                let inputMem := mload(0x40)
                mstore(
                    inputMem,
                    0x022c0d9f00000000000000000000000000000000000000000000000000000000
                )
                mstore(add(inputMem, 0x04), 0)
                mstore(add(inputMem, 0x24), amountOut)
                mstore(add(inputMem, 0x44), address())
                mstore(add(inputMem, 0x64), 0x80)
                mstore(add(inputMem, 0x84), 0)
                pop(call(gas(), _pair, 0, inputMem, 0xA4, 0, 0))
            }
         
        }

        IWETH(WETH).withdraw(amountOut);
    }

    function zapFromToken(
        address fromToken,
        uint256 amountIn,
        uint256 minOut,
        uint256 minOut2,
        bool isV2,
        uint24 poolFee,
        uint256 flag,
        address ref
    ) external returns (uint256 tokenId, uint amountOutV2OrV3) {
        
        {
            address _weth = WETH;
            if (fromToken == WETH) {
                fromToken.call(
                    abi.encodeWithSelector(
                        IERC20.transferFrom.selector,
                        msg.sender,
                        address(this),
                        amountIn
                    )
                );
                assembly {
                    let inputMem := mload(0x40)
                    mstore(
                        inputMem,
                        0x2e1a7d4d00000000000000000000000000000000000000000000000000000000
                    )
                    mstore(add(inputMem, 0x04), amountIn)
                    pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0))
                }
                return (
                    IChainTools(CTLS).zapFromETH{value: amountIn}(
                        minOut2,
                        msg.sender,
                        flag,
                        ref
                    ),
                    amountIn
                );
            }
        }

        if (isV2) {
            {
                address pair = v2Factory.getPair(fromToken, WETH);
                amountOutV2OrV3 = _swapV2TokenIn(fromToken, pair, amountIn, minOut, IV2Pair(pair).token0() == WETH);

                return (
                    IChainTools(CTLS).zapFromETH{value: address(this).balance}(
                        minOut2,
                        msg.sender,
                        flag,
                        ref
                    ),
                    amountOutV2OrV3
                );
            }
        } else {
            fromToken.call(
                abi.encodeWithSelector(
                    IERC20.transferFrom.selector,
                    msg.sender,
                    address(this),
                    amountIn
                )
            );
            {
                if (fromToken != address(CTLS) && fromToken != WETH) {
                    if (
                        IERC20(fromToken).allowance(
                            address(this),
                            address(v3Router)
                        ) < amountIn
                    ) {
                        fromToken.call(
                            abi.encodeWithSelector(
                                IERC20.approve.selector,
                                address(v3Router),
                                amountIn
                            )
                        );
                    }
                }
            }
            uint256 gotOut = IRouterV3(v3Router).exactInputSingle(
                IRouterV3.ExactInputSingleParams({
                    tokenIn: fromToken,
                    tokenOut: WETH,
                    fee: poolFee,
                    recipient: address(this),
                    deadline: block.timestamp,
                    amountIn: amountIn,
                    amountOutMinimum: minOut,
                    sqrtPriceLimitX96: 0
                })
            );
            {
                address _weth = WETH;

                assembly {
                    let inputMem := mload(0x40)
                    mstore(
                        inputMem,
                        0x2e1a7d4d00000000000000000000000000000000000000000000000000000000
                    )
                    mstore(add(inputMem, 0x04), gotOut)
                    pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0))
                }
                return (
                    IChainTools(CTLS).zapFromETH{value: gotOut}(
                        minOut2,
                        msg.sender,
                        flag,
                        ref
                    ),
                    gotOut
                );
            }
        }
    }

    fallback() external payable {}

    receive() external payable {}

    function getPosition(
        uint256 tokenId
    )
        external
        view
        returns (address token0, address token1, uint128 liquidity)
    {
        (, , token0, token1, , , , liquidity, , , , ) = positionManager
            .positions(tokenId);
    }

    function findPoolFee(
        address token0,
        address token1
    ) public view returns (uint24 poolFee) {
        address factory = IRouterV3(v3Router).factory();
        uint128 highestLiq;
        try IV3Factory(factory).getPool(token0, token1, 100) returns (
            address pool100
        ) {
            if (pool100 != address(0)) {
                try IV3Pool(pool100).liquidity() returns (uint128 liq) {
                    if (liq > highestLiq) {
                        poolFee = 100;
                        highestLiq = liq;
                    }
                } catch {}
            }
        } catch {}
        try IV3Factory(factory).getPool(token0, token1, 500) returns (
            address pool500
        ) {
            if (pool500 != address(0)) {
                try IV3Pool(pool500).liquidity() returns (uint128 liq) {
                    if (liq > highestLiq) {
                        poolFee = 500;
                        highestLiq = liq;
                    }
                } catch {}
            }
        } catch {}
        try IV3Factory(factory).getPool(token0, token1, 3000) returns (
            address pool3000
        ) {
            if (pool3000 != address(0)) {
                try IV3Pool(pool3000).liquidity() returns (uint128 liq) {
                    if (liq > highestLiq) {
                        poolFee = 3000;
                        highestLiq = liq;
                    }
                } catch {}
            }
        } catch {}

        try IV3Factory(factory).getPool(token0, token1, 10000) returns (
            address pool10000
        ) {
            if (pool10000 != address(0)) {
                try IV3Pool(pool10000).liquidity() returns (uint128 liq) {
                    if (liq > highestLiq) {
                        poolFee = 10000;
                        highestLiq = liq;
                    }
                } catch {}
            }
        } catch {}
    }

    function getDeviation(
        uint256 amountIn,
        uint256 startTickDeviation
    ) external pure returns (uint256 adjusted) {
        adjusted = (amountIn * (10000 + startTickDeviation)) / 20000;
    }

    function getStartTickDeviation(
        int24 currentTick
    ) external pure returns (uint256 perc) {
        int24 startTickDeviation;

        if (currentTick > -106400) {
            startTickDeviation = currentTick + -106400;
        } else {
            startTickDeviation = -106400 + currentTick;
        }
        if (startTickDeviation < 0) {
            startTickDeviation = -startTickDeviation;
        }
        perc = (uint256(int256(startTickDeviation)) * 75) / 107400;
    }

    function getCurrentTick() external view returns (int24 cTick) {
        (, cTick, , , , , ) = IV3Pool(uniswapV3Pool).slot0();
        cTick = (cTick / 200) * 200;
    }

    function getTickDistance(
        uint256 flag
    ) external pure returns (int24 tickDistance) {
        if (flag == 0) {
            //default
            tickDistance = 30000;
        } else if (flag == 1) {
            tickDistance = 20000;
        } else if (flag == 2) {
            tickDistance = 10000;
        } else if (flag == 3) {
            tickDistance = 5000;
        } else if (flag == 4) {
            tickDistance = 2000;
        } else if (flag == 5) {
            tickDistance = 1000;
        } else if (flag == 6) {
            tickDistance = 600;
        } else {
            revert("invalid_flag");
        }
    }

    function setVault(address vault) external {
        require(msg.sender == multiSig || msg.sender == dev, "dev");
        yieldVault = IYieldVault(vault);
    }

    function setCTLS(address ctlsNew) external {
        require(msg.sender == multiSig || msg.sender == dev, "dev");
        CTLS = ctlsNew;
    }

    function balanceOfMany(
        uint256[] calldata tokenIds
    )
        external
        view
        returns (
            uint128 balance0Total,
            uint128 balance1Total,
            uint256[] memory returnTokenIds,
            uint128[] memory balances0,
            uint128[] memory balances1
        )
    {
        uint256 size = tokenIds.length;
        balances0 = new uint128[](size);
        balances1 = new uint128[](size);

        unchecked {
            for (uint256 i; i < size; ++i) {
                uint256 tokenId = tokenIds[i];
                (uint128 bal0, uint128 bal1) = yieldVault.balanceOf(tokenId);

                balance0Total += bal0;
                balance1Total += bal1;

                balances0[i] = bal0;
                balances1[i] = bal1;
            }
        }

        returnTokenIds = tokenIds;
    }

    function findApprovalToken(
        address pool
    ) external view returns (address token) {
        return
            this.findApprovalToken(
                IV3Pool(pool).token0(),
                IV3Pool(pool).token1()
            );
    }

    function findApprovalToken(
        address token0,
        address token1
    ) external view returns (address token) {
        require(token0 == WETH || token1 == WETH, "Not WETH Pair");
        token = token0 == WETH ? token1 : token0;
        if (token == CTLS || token == WETH) {
            token = address(0);
        }
    }

    function withdraw(
        address token,
        address toAddress,
        uint256 amount
    ) external {
        require(msg.sender == multiSig, "multiSig");
        if (amount != 0) IERC20(token).transfer(toAddress, amount);
        if (address(this).balance > 0) {
            multiSig.call{value: address(this).balance}("");
        }
    }

    //CallStatic
    function getV2RemovedLiqudityFeeOnTransfer(
        address pair,
        uint amount
    ) external returns (uint a0, uint a1) {
        uint balance0Before = IERC20(IV2Pair(pair).token0()).balanceOf(
            msg.sender
        );
        uint balance1Before = IERC20(IV2Pair(pair).token1()).balanceOf(
            msg.sender
        );

        IERC20(pair).transferFrom(msg.sender, pair, amount);

        IV2Pair(pair).burn(msg.sender);

        uint balance0After = IERC20(IV2Pair(pair).token0()).balanceOf(
            msg.sender
        );
        uint balance1After = IERC20(IV2Pair(pair).token1()).balanceOf(
            msg.sender
        );

        a0 = balance0After - balance0Before;
        a1 = balance1After - balance1Before;
    }

    function getPositionAmounts(
        uint256 tokenId
    )
        external
        view
        returns (
            address token0,
            address token1,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        )
    {
        int24 lower;
        int24 upper;
        int24 current = this.getCurrentTick();

        (
            ,
            ,
            token0,
            token1,
            ,
            lower,
            upper,
            liquidity,
            ,
            ,
            ,

        ) = positionManager.positions(tokenId);

        (amount0, amount1) = LiquidityAmounts.getAmountsForLiquidity(
            TickMath.getSqrtRatioAtTick(current),
            TickMath.getSqrtRatioAtTick(lower),
            TickMath.getSqrtRatioAtTick(upper),
            liquidity
        );
    }

    function getAmountsFromLiquidity(
        uint128 liquidity,
        int24 lower,
        int24 upper
    ) external view returns (uint256 amount0, uint256 amount1) {
        int24 current = this.getCurrentTick();

        (amount0, amount1) = LiquidityAmounts.getAmountsForLiquidity(
            TickMath.getSqrtRatioAtTick(current),
            TickMath.getSqrtRatioAtTick(lower),
            TickMath.getSqrtRatioAtTick(upper),
            liquidity
        );
    }

    function findMaxAddDouble(
        uint256 amount0Desired,
        uint256 amount1Desired,
        int24 lower,
        int24 upper
    ) external view returns (uint256 amount0Max, uint256 amount1Max) {
        // int24 current = this.getCurrentTick();
        int24 cTick;
        uint160 sqrtPrice;
        (sqrtPrice, cTick, , , , , ) = IV3Pool(uniswapV3Pool).slot0();

        (amount0Max, amount1Max) = LiquidityAmounts.getAmountsForLiquidity(
            sqrtPrice,
            TickMath.getSqrtRatioAtTick(lower),
            TickMath.getSqrtRatioAtTick(upper),
            //Liq
            LiquidityAmounts.getLiquidityForAmounts(
                sqrtPrice,
                TickMath.getSqrtRatioAtTick(lower),
                TickMath.getSqrtRatioAtTick(upper),
                amount0Desired,
                amount1Desired
            )
        );
    }

    function findMaxAddSingle(
        bool isAmount0,
        uint256 amountDesired,
        int24 lower,
        int24 upper
    ) external pure returns (uint256 amountMax) {
        if (isAmount0) {
            (amountMax) = LiquidityAmounts.getAmount0ForLiquidity(
                TickMath.getSqrtRatioAtTick(lower),
                TickMath.getSqrtRatioAtTick(upper),
                //Liq
                LiquidityAmounts.getLiquidityForAmount0(
                    TickMath.getSqrtRatioAtTick(lower),
                    TickMath.getSqrtRatioAtTick(upper),
                    amountDesired
                )
            );
        } else {
            (amountMax) = LiquidityAmounts.getAmount1ForLiquidity(
                TickMath.getSqrtRatioAtTick(lower),
                TickMath.getSqrtRatioAtTick(upper),
                //Liq
                LiquidityAmounts.getLiquidityForAmount1(
                    TickMath.getSqrtRatioAtTick(lower),
                    TickMath.getSqrtRatioAtTick(upper),
                    amountDesired
                )
            );
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 42000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_ctls","type":"address"},{"internalType":"address","name":"_v3pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Auth","type":"error"},{"inputs":[],"name":"Max0","type":"error"},{"inputs":[],"name":"Max1","type":"error"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"balanceOfMany","outputs":[{"internalType":"uint128","name":"balance0Total","type":"uint128"},{"internalType":"uint128","name":"balance1Total","type":"uint128"},{"internalType":"uint256[]","name":"returnTokenIds","type":"uint256[]"},{"internalType":"uint128[]","name":"balances0","type":"uint128[]"},{"internalType":"uint128[]","name":"balances1","type":"uint128[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"name":"findApprovalToken","outputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"findApprovalToken","outputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"int24","name":"lower","type":"int24"},{"internalType":"int24","name":"upper","type":"int24"}],"name":"findMaxAddDouble","outputs":[{"internalType":"uint256","name":"amount0Max","type":"uint256"},{"internalType":"uint256","name":"amount1Max","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isAmount0","type":"bool"},{"internalType":"uint256","name":"amountDesired","type":"uint256"},{"internalType":"int24","name":"lower","type":"int24"},{"internalType":"int24","name":"upper","type":"int24"}],"name":"findMaxAddSingle","outputs":[{"internalType":"uint256","name":"amountMax","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"name":"findPoolFee","outputs":[{"internalType":"uint24","name":"poolFee","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"int24","name":"lower","type":"int24"},{"internalType":"int24","name":"upper","type":"int24"}],"name":"getAmountsFromLiquidity","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentTick","outputs":[{"internalType":"int24","name":"cTick","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"startTickDeviation","type":"uint256"}],"name":"getDeviation","outputs":[{"internalType":"uint256","name":"adjusted","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPosition","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPositionAmounts","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"currentTick","type":"int24"}],"name":"getStartTickDeviation","outputs":[{"internalType":"uint256","name":"perc","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"flag","type":"uint256"}],"name":"getTickDistance","outputs":[{"internalType":"int24","name":"tickDistance","type":"int24"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getV2RemovedLiqudityFeeOnTransfer","outputs":[{"internalType":"uint256","name":"a0","type":"uint256"},{"internalType":"uint256","name":"a1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ctlsNew","type":"address"}],"name":"setCTLS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"minOut2","type":"uint256"},{"internalType":"bool","name":"isV2","type":"bool"},{"internalType":"uint24","name":"poolFee","type":"uint24"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"ref","type":"address"}],"name":"zapFromToken","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amountOutV2OrV3","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101a0604052336101405234801562000016575f80fd5b50604051620047f0380380620047f083398101604081905262000039916200030b565b73c36442b4a4522e871399cd717abdd847ab11fe8860a0819052735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f60c052737a250d5630b4cf539739df2c5dacb4c659f2488d6080525f80546001600160a01b0319166001600160a01b03851617905573e592427a0aece92de3edee1f18e0157c058615646101605273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261010081905260405163095ea7b360e01b815260048101929092525f1960248301529063095ea7b3906044016020604051808303815f875af115801562000114573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200013a919062000341565b505f5460a05160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200018d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001b3919062000341565b5073b27308f9f90d607463bb33ea1bebb41c27ce5ab660e05273b0df68e0bf4f54d06a4a448735d2a3d7d97a222261012052610100516101605160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200023a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000260919062000341565b505f546101605160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af1158015620002b4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620002da919062000341565b506001600160a01b0316610180525062000369565b80516001600160a01b038116811462000306575f80fd5b919050565b5f80604083850312156200031d575f80fd5b6200032883620002ef565b91506200033860208401620002ef565b90509250929050565b5f6020828403121562000352575f80fd5b8151801515811462000362575f80fd5b9392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516143a26200044e5f395f8181611a2901526129ac01525f81816113c901528181611449015281816115d80152611ece01525f8181611cbc0152611dfc01525f8181611c7d01528181611dbd015281816127fa015261293f01525f818161046a015281816104bf0152818161057a015281816105fb01528181610dda01528181611025015281816110c5015281816113320152818161155f015281816116ca0152612fac01525f50505f61104f01525f81816126f70152612a9201525f50506143a25ff3fe60806040526004361061011a575f3560e01c80636817031b1161009b578063cad9a4f31161006d578063d9caed1211610055578063d9caed12146103c5578063eaaf0390146103e4578063eb02c3011461040357005b8063cad9a4f314610330578063d26265e01461034f57005b80636817031b146102a05780637a5a5420146102bf5780637d4b1404146102de578063c95e542b146102fd57005b80632c2cad7f116100ec5780633dc63b73116100d45780633dc63b731461024057806353aad1d91461026d57806354a26f5c1461028157005b80632c2cad7f146101ef578063396a28ba1461020e57005b80630fad9b09146101235780632143fcd81461016c5780632a71d801146101a05780632ba35fdb146101d057005b3661012157005b005b34801561012e575f80fd5b5061014261013d366004613a27565b610467565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610177575f80fd5b5061018b610186366004613a5e565b610657565b60408051928352602083019190915201610163565b3480156101ab575f80fd5b506101bf6101ba366004613a88565b610b9e565b604051610163959493929190613b42565b3480156101db575f80fd5b5061018b6101ea366004613bf1565b610dd6565b3480156101fa575f80fd5b5061018b610209366004613c9c565b6117df565b348015610219575f80fd5b5061022d610228366004613ce4565b611882565b60405160029190910b8152602001610163565b34801561024b575f80fd5b5061025f61025a366004613cfb565b611960565b604051908152602001610163565b348015610278575f80fd5b5061022d611a26565b34801561028c575f80fd5b5061014261029b366004613d16565b611adc565b3480156102ab575f80fd5b506101216102ba366004613d16565b611c65565b3480156102ca575f80fd5b5061025f6102d9366004613d31565b611d8b565b3480156102e9575f80fd5b506101216102f8366004613d16565b611da5565b348015610308575f80fd5b5061031c610317366004613a27565b611eca565b60405162ffffff9091168152602001610163565b34801561033b575f80fd5b5061025f61034a366004613d51565b6125cd565b34801561035a575f80fd5b5061036e610369366004613ce4565b612650565b6040805173ffffffffffffffffffffffffffffffffffffffff96871681529590941660208601526fffffffffffffffffffffffffffffffff909216928401929092526060830191909152608082015260a001610163565b3480156103d0575f80fd5b506101216103df366004613da1565b6127e2565b3480156103ef575f80fd5b5061018b6103fe366004613ddf565b6129a6565b34801561040e575f80fd5b5061042261041d366004613ce4565b612a8d565b6040805173ffffffffffffffffffffffffffffffffffffffff94851681529390921660208401526fffffffffffffffffffffffffffffffff1690820152606001610163565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061050d57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f4e6f74205745544820506169720000000000000000000000000000000000000060448201526064015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146105d157826105d3565b815b5f5490915073ffffffffffffffffffffffffffffffffffffffff8083169116148061064957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b1561065157505f5b92915050565b5f805f8473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106c79190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610731573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107559190613e31565b90505f8573ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107c59190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa15801561082f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108539190613e31565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff881660248201819052604482018890529192506323b872dd906064016020604051808303815f875af11580156108cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f09190613e48565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8716906389afcb449060240160408051808303815f875af1158015610959573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097d9190613e63565b50505f8673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ed9190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610a57573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a7b9190613e31565b90505f8773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aeb9190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610b55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b799190613e31565b9050610b858483613eb2565b9550610b918382613eb2565b9450505050509250929050565b5f8060608080858067ffffffffffffffff811115610bbe57610bbe613ec5565b604051908082528060200260200182016040528015610be7578160200160208202803683370190505b5092508067ffffffffffffffff811115610c0357610c03613ec5565b604051908082528060200260200182016040528015610c2c578160200160208202803683370190505b5091505f5b81811015610d92575f898983818110610c4c57610c4c613ef2565b6001546040517f9cc7f70800000000000000000000000000000000000000000000000000000000815260209290920293909301356004820181905293505f9283925073ffffffffffffffffffffffffffffffffffffffff1690639cc7f708906024016040805180830381865afa158015610cc8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f2a565b91509150818a019950808901985081878581518110610d0d57610d0d613ef2565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505080868581518110610d5257610d52613ef2565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050505050806001019050610c31565b508787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250989b979a5091985093965091949350505050565b5f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff808216908c1603610fd9576040805133602482015230604482015260648082018d905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052905173ffffffffffffffffffffffffffffffffffffffff8d1691610ead91613f57565b5f604051808303815f865af19150503d805f8114610ee6576040519150601f19603f3d011682016040523d82523d5f602084013e610eeb565b606091505b5050506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528a60048201525f806024835f865af150505f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018a90523360248201526044810187905273ffffffffffffffffffffffffffffffffffffffff868116606483015290911690637a3e3495908c9060840160206040518083038185885af1158015610fa9573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fce9190613e31565b8a92509250506117d2565b508515611236576040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301527f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015611096573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ba9190613e16565b90506111838b828c8c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611143573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111679190613e16565b73ffffffffffffffffffffffffffffffffffffffff1614612b42565b5f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018b90523360248201526044810188905273ffffffffffffffffffffffffffffffffffffffff8781166064830152929450911690637a3e349590479060840160206040518083038185885af1158015611209573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061122e9190613e31565b9250506117d2565b6040805133602482015230604482015260648082018c905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052905173ffffffffffffffffffffffffffffffffffffffff8c16916112ca91613f57565b5f604051808303815f865af19150503d805f8114611303576040519150601f19603f3d011682016040523d82523d5f602084013e611308565b606091505b50505f5473ffffffffffffffffffffffffffffffffffffffff8c81169116148015915061138157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614155b15611538576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301528a91908c169063dd62ed3e90604401602060405180830381865afa158015611419573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143d9190613e31565b101561153857604080517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916114f69190613f57565b5f604051808303815f865af19150503d805f811461152f576040519150601f19603f3d011682016040523d82523d5f602084013e611534565b606091505b5050505b604080516101008101825273ffffffffffffffffffffffffffffffffffffffff8c811682527f00000000000000000000000000000000000000000000000000000000000000008116602083015262ffffff88168284015230606083015242608083015260a082018c905260c082018b90525f60e0830181905292517f414bf3890000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000919091169163414bf3899161168591906004015f6101008201905073ffffffffffffffffffffffffffffffffffffffff80845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af11580156116a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c59190613e31565b90505f7f000000000000000000000000000000000000000000000000000000000000000090506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af150505f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018b90523360248201526044810188905273ffffffffffffffffffffffffffffffffffffffff878116606483015290911690637a3e349590849060840160206040518083038185885af11580156117a6573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906117cb9190613e31565b9350909150505b9850989650505050505050565b5f805f3073ffffffffffffffffffffffffffffffffffffffff166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561182b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061184f9190613f8e565b905061187561185d82613021565b61186687613021565b61186f87613021565b89613488565b9097909650945050505050565b5f815f036118935750617530919050565b816001036118a45750614e20919050565b816002036118b55750612710919050565b816003036118c65750611388919050565b816004036118d757506107d0919050565b816005036118e857506103e8919050565b816006036118f95750610258919050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c69645f666c61670000000000000000000000000000000000000000604482015260640161056f565b919050565b5f807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60608360020b13156119be576119b7837ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6060613fa9565b90506119eb565b6119e8837ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6060613fa9565b90505b5f8160020b1215611a02576119ff81613fea565b90505b6201a388611a15600283900b604b614026565b611a1f919061406a565b9392505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015611a90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061408e565b50939550611acc945060c89350859250614120915050565b611ad79060c8614193565b905090565b5f3073ffffffffffffffffffffffffffffffffffffffff16630fad9b098373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b42573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b669190613e16565b8473ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611baf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bd39190613e16565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015611c41573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106519190613e16565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480611cde57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b611d44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f6465760000000000000000000000000000000000000000000000000000000000604482015260640161056f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f614e20611d9b836127106141b9565b611a159085614026565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480611e1e57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b611e84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f6465760000000000000000000000000000000000000000000000000000000000604482015260640161056f565b5f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f35573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f599190613e16565b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526064604483018190529293505f9290841691631698ee829101602060405180830381865afa925050508015612014575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261201191810190613e16565b60015b156120f75773ffffffffffffffffffffffffffffffffffffffff8116156120f5578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156120ba575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526120b7918101906141cc565b60015b156120f557826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1611156120f357606494508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526101f46044830152831690631698ee8290606401602060405180830381865afa9250505080156121ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526121aa91810190613e16565b60015b156122915773ffffffffffffffffffffffffffffffffffffffff81161561228f578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612253575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612250918101906141cc565b60015b1561228f57826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561228d576101f494508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301528581166024830152610bb86044830152831690631698ee8290606401602060405180830381865afa925050508015612347575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261234491810190613e16565b60015b1561242b5773ffffffffffffffffffffffffffffffffffffffff811615612429578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123ed575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526123ea918101906141cc565b60015b1561242957826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561242757610bb894508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526127106044830152831690631698ee8290606401602060405180830381865afa9250505080156124e1575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124de91810190613e16565b60015b156125c55773ffffffffffffffffffffffffffffffffffffffff8116156125c3578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612587575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612584918101906141cc565b60015b156125c357826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1611156125c15761271094508092505b505b505b505092915050565b5f8415612610576126096125e084613021565b6125e984613021565b6126046125f587613021565b6125fe87613021565b89613571565b61362c565b9050612648565b61264561261c84613021565b61262584613021565b61264061263187613021565b61263a87613021565b896136e8565b613740565b90505b949350505050565b5f805f805f805f803073ffffffffffffffffffffffffffffffffffffffff166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c59190613f8e565b6040517f99fbab88000000000000000000000000000000000000000000000000000000008152600481018b90529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906399fbab889060240161018060405180830381865afa158015612752573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061277691906141f2565b909192939495969798999a509091929394959697989950909192939495965090919250909150905050809a50819650829750839b50849c5050505050506127d16127bf82613021565b6127c885613021565b61186f85613021565b989a97995095979596945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f6d756c7469536967000000000000000000000000000000000000000000000000604482015260640161056f565b801561291f576040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303815f875af11580156128f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061291d9190613e48565b505b47156129a15760405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169047905f81818185875af1925050503d805f8114612998576040519150601f19603f3d011682016040523d82523d5f602084013e61299d565b606091505b5050505b505050565b5f805f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612a13573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a37919061408e565b50939650939450612a7e9350849250612a539150899050613021565b612a5c88613021565b612a7985612a698c613021565b612a728c613021565b8f8f6137c2565b613488565b90999098509650505050505050565b5f805f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166399fbab88856040518263ffffffff1660e01b8152600401612aeb91815260200190565b61018060405180830381865afa158015612b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b2b91906141f2565b50979e969d50919b50949950505050505050505050565b6040805133602482015273ffffffffffffffffffffffffffffffffffffffff8681166044830152606480830187905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f92881691612bda91613f57565b5f604051808303815f865af19150503d805f8114612c13576040519150601f19603f3d011682016040523d82523d5f602084013e612c18565b606091505b5050508115612dd1575f808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c9091906142cb565b506040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529294509092505f918a16906370a0823190602401602060405180830381865afa158015612d03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d279190613e31565b9050612d3d612d368383613eb2565b83856138e1565b935083861115612d79576040517f0d35962a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081528460048201525f6024820152306044820152608060648201525f60848201525f8060a4835f8d5af15050505050612f7d565b5f808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612e1c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4091906142cb565b506040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529294509092505f918a16906370a0823190602401602060405180830381865afa158015612eb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed79190613e31565b9050612eed612ee68483613eb2565b84846138e1565b935083861115612f29576040517f0d35962a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081525f6004820152846024820152306044820152608060648201525f60848201525f8060a4835f8d5af150505050505b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d906024015f604051808303815f87803b158015613002575f80fd5b505af1158015613014573d5f803e3d5ffd5b5050505095945050505050565b5f805f8360020b12613036578260020b613043565b8260020b613043906142f6565b9050620d89e88111156130b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5400000000000000000000000000000000000000000000000000000000000000604482015260640161056f565b5f816001165f036130d4577001000000000000000000000000000000006130e6565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615613125576080613120826ffff97272373d413259a46990580e213a614026565b901c90505b600482161561314f57608061314a826ffff2e50f5f656932ef12357cf3c7fdcc614026565b901c90505b6008821615613179576080613174826fffe5caca7e10e4e61c3624eaa0941cd0614026565b901c90505b60108216156131a357608061319e826fffcb9843d60f6159c9db58835c926644614026565b901c90505b60208216156131cd5760806131c8826fff973b41fa98c081472e6896dfb254c0614026565b901c90505b60408216156131f75760806131f2826fff2ea16466c96a3843ec78b326b52861614026565b901c90505b608082161561322157608061321c826ffe5dee046a99a2a811c461f1969c3053614026565b901c90505b61010082161561324c576080613247826ffcbe86c7900a88aedcffc83b479aa3a4614026565b901c90505b610200821615613277576080613272826ff987a7253ac413176f2b074cf7815e54614026565b901c90505b6104008216156132a257608061329d826ff3392b0822b70005940c7a398e4b70f3614026565b901c90505b6108008216156132cd5760806132c8826fe7159475a2c29b7443b29c7fa6e889d9614026565b901c90505b6110008216156132f85760806132f3826fd097f3bdfd2022b8845ad8f792aa5825614026565b901c90505b61200082161561332357608061331e826fa9f746462d870fdf8a65dc1f90e061e5614026565b901c90505b61400082161561334e576080613349826f70d869a156d2a1b890bb3df62baf32f7614026565b901c90505b618000821615613379576080613374826f31be135f97d08fd981231505542fcfa6614026565b901c90505b620100008216156133a55760806133a0826f09aa508b5b7a84e1c677de54f3e99bc9614026565b901c90505b620200008216156133d05760806133cb826e5d6af8dedb81196699c329225ee604614026565b901c90505b620400008216156133fa5760806133f5826d2216e584f5fa1ea926041bedfe98614026565b901c90505b6208000082161561342257608061341d826b048a170391f7dc42444e8fa2614026565b901c90505b5f8460020b131561345a57613457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61406a565b90505b6134696401000000008261432c565b15613475576001613477565b5f5b6126489060ff16602083901c6141b9565b5f808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134c2579293925b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16116135075761350085858561362c565b9150613568565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16101561355a5761354686858561362c565b9150613553858785613740565b9050613568565b613565858585613740565b90505b94509492505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1611156135aa579192915b5f6135ef8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000061391c565b905061362361361e8483613603898961433f565b73ffffffffffffffffffffffffffffffffffffffff1661391c565b6139e5565b95945050505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613665579192915b73ffffffffffffffffffffffffffffffffffffffff84166136de7bffffffffffffffffffffffffffffffff000000000000000000000000606085901b166136ac878761433f565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1661391c565b612648919061406a565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613721579192915b61264861361e836c01000000000000000000000000613603888861433f565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613779579192915b6126486fffffffffffffffffffffffffffffffff8316613799868661433f565b73ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000061391c565b5f8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156137fb579293925b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161161384057613839858585613571565b9050613623565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1610156138cc575f613880878686613571565b90505f61388e8789866136e8565b9050806fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff16106138c157806138c3565b815b92505050613623565b6138d78585846136e8565b9695505050505050565b5f806138ef856103e5614026565b9050806138fe856103e8614026565b61390891906141b9565b6139128483614026565b613623919061406a565b5f80807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff858709858702925082811083820303915050805f0361396f575f8411613964575f80fd5b508290049050611a1f565b80841161397a575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b806fffffffffffffffffffffffffffffffff8116811461195b575f80fd5b73ffffffffffffffffffffffffffffffffffffffff81168114613a24575f80fd5b50565b5f8060408385031215613a38575f80fd5b8235613a4381613a03565b91506020830135613a5381613a03565b809150509250929050565b5f8060408385031215613a6f575f80fd5b8235613a7a81613a03565b946020939093013593505050565b5f8060208385031215613a99575f80fd5b823567ffffffffffffffff80821115613ab0575f80fd5b818501915085601f830112613ac3575f80fd5b813581811115613ad1575f80fd5b8660208260051b8501011115613ae5575f80fd5b60209290920196919550909350505050565b5f8151808452602080850194508084015f5b83811015613b375781516fffffffffffffffffffffffffffffffff1687529582019590820190600101613b09565b509495945050505050565b5f60a082016fffffffffffffffffffffffffffffffff808916845260208189168186015260a06040860152829150875180845260c08601925081890193505f5b81811015613b9e57845184529382019392820192600101613b82565b5050508381036060850152613bb38187613af7565b9150508281036080840152613bc88185613af7565b98975050505050505050565b8015158114613a24575f80fd5b62ffffff81168114613a24575f80fd5b5f805f805f805f80610100898b031215613c09575f80fd5b8835613c1481613a03565b97506020890135965060408901359550606089013594506080890135613c3981613bd4565b935060a0890135613c4981613be1565b925060c0890135915060e0890135613c6081613a03565b809150509295985092959890939650565b6fffffffffffffffffffffffffffffffff81168114613a24575f80fd5b8060020b8114613a24575f80fd5b5f805f60608486031215613cae575f80fd5b8335613cb981613c71565b92506020840135613cc981613c8e565b91506040840135613cd981613c8e565b809150509250925092565b5f60208284031215613cf4575f80fd5b5035919050565b5f60208284031215613d0b575f80fd5b8135611a1f81613c8e565b5f60208284031215613d26575f80fd5b8135611a1f81613a03565b5f8060408385031215613d42575f80fd5b50508035926020909101359150565b5f805f8060808587031215613d64575f80fd5b8435613d6f81613bd4565b9350602085013592506040850135613d8681613c8e565b91506060850135613d9681613c8e565b939692955090935050565b5f805f60608486031215613db3575f80fd5b8335613dbe81613a03565b92506020840135613dce81613a03565b929592945050506040919091013590565b5f805f8060808587031215613df2575f80fd5b84359350602085013592506040850135613d8681613c8e565b805161195b81613a03565b5f60208284031215613e26575f80fd5b8151611a1f81613a03565b5f60208284031215613e41575f80fd5b5051919050565b5f60208284031215613e58575f80fd5b8151611a1f81613bd4565b5f8060408385031215613e74575f80fd5b505080516020909101519092909150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561065157610651613e85565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b805161195b81613c71565b5f8060408385031215613f3b575f80fd5b8251613f4681613c71565b6020840151909250613a5381613c71565b5f82515f5b81811015613f765760208186018101518583015201613f5c565b505f920191825250919050565b805161195b81613c8e565b5f60208284031215613f9e575f80fd5b8151611a1f81613c8e565b600281810b9083900b01627fffff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008212171561065157610651613e85565b5f8160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361401e5761401e613e85565b5f0392915050565b808202811582820484141761065157610651613e85565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826140785761407861403d565b500490565b805161ffff8116811461195b575f80fd5b5f805f805f805f60e0888a0312156140a4575f80fd5b87516140af81613a03565b60208901519097506140c081613c8e565b95506140ce6040890161407d565b94506140dc6060890161407d565b93506140ea6080890161407d565b925060a088015160ff811681146140ff575f80fd5b60c089015190925061411081613bd4565b8091505092959891949750929550565b5f8160020b8360020b806141365761413661403d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008314161561418a5761418a613e85565b90059392505050565b5f8260020b8260020b028060020b91508082146141b2576141b2613e85565b5092915050565b8082018082111561065157610651613e85565b5f602082840312156141dc575f80fd5b8151611a1f81613c71565b805161195b81613be1565b5f805f805f805f805f805f806101808d8f03121561420e575f80fd5b8c516bffffffffffffffffffffffff81168114614229575f80fd5b9b5061423760208e01613e0b565b9a5061424560408e01613e0b565b995061425360608e01613e0b565b985061426160808e016141e7565b975061426f60a08e01613f83565b965061427d60c08e01613f83565b955061428b60e08e01613f1f565b94506101008d015193506101208d015192506142aa6101408e01613f1f565b91506142b96101608e01613f1f565b90509295989b509295989b509295989b565b5f805f606084860312156142dd575f80fd5b8351925060208401519150604084015190509250925092565b5f7f8000000000000000000000000000000000000000000000000000000000000000820361432657614326613e85565b505f0390565b5f8261433a5761433a61403d565b500690565b73ffffffffffffffffffffffffffffffffffffffff8281168282160390808211156141b2576141b2613e8556fea2646970667358221220a58660a48ab2dc011b97e80b3f8f0e42b5e93f736cb96410943cb8fcb00d2b8b64736f6c63430008150033000000000000000000000000dbecdd726f6ad8e24afc78fe3cc8eb7b73c2d94d000000000000000000000000ceb492c5e67385e2a08265352d646a0c32a5d085

Deployed Bytecode

0x60806040526004361061011a575f3560e01c80636817031b1161009b578063cad9a4f31161006d578063d9caed1211610055578063d9caed12146103c5578063eaaf0390146103e4578063eb02c3011461040357005b8063cad9a4f314610330578063d26265e01461034f57005b80636817031b146102a05780637a5a5420146102bf5780637d4b1404146102de578063c95e542b146102fd57005b80632c2cad7f116100ec5780633dc63b73116100d45780633dc63b731461024057806353aad1d91461026d57806354a26f5c1461028157005b80632c2cad7f146101ef578063396a28ba1461020e57005b80630fad9b09146101235780632143fcd81461016c5780632a71d801146101a05780632ba35fdb146101d057005b3661012157005b005b34801561012e575f80fd5b5061014261013d366004613a27565b610467565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610177575f80fd5b5061018b610186366004613a5e565b610657565b60408051928352602083019190915201610163565b3480156101ab575f80fd5b506101bf6101ba366004613a88565b610b9e565b604051610163959493929190613b42565b3480156101db575f80fd5b5061018b6101ea366004613bf1565b610dd6565b3480156101fa575f80fd5b5061018b610209366004613c9c565b6117df565b348015610219575f80fd5b5061022d610228366004613ce4565b611882565b60405160029190910b8152602001610163565b34801561024b575f80fd5b5061025f61025a366004613cfb565b611960565b604051908152602001610163565b348015610278575f80fd5b5061022d611a26565b34801561028c575f80fd5b5061014261029b366004613d16565b611adc565b3480156102ab575f80fd5b506101216102ba366004613d16565b611c65565b3480156102ca575f80fd5b5061025f6102d9366004613d31565b611d8b565b3480156102e9575f80fd5b506101216102f8366004613d16565b611da5565b348015610308575f80fd5b5061031c610317366004613a27565b611eca565b60405162ffffff9091168152602001610163565b34801561033b575f80fd5b5061025f61034a366004613d51565b6125cd565b34801561035a575f80fd5b5061036e610369366004613ce4565b612650565b6040805173ffffffffffffffffffffffffffffffffffffffff96871681529590941660208601526fffffffffffffffffffffffffffffffff909216928401929092526060830191909152608082015260a001610163565b3480156103d0575f80fd5b506101216103df366004613da1565b6127e2565b3480156103ef575f80fd5b5061018b6103fe366004613ddf565b6129a6565b34801561040e575f80fd5b5061042261041d366004613ce4565b612a8d565b6040805173ffffffffffffffffffffffffffffffffffffffff94851681529390921660208401526fffffffffffffffffffffffffffffffff1690820152606001610163565b5f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061050d57507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f4e6f74205745544820506169720000000000000000000000000000000000000060448201526064015b60405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146105d157826105d3565b815b5f5490915073ffffffffffffffffffffffffffffffffffffffff8083169116148061064957507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b1561065157505f5b92915050565b5f805f8473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106c79190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610731573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107559190613e31565b90505f8573ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107c59190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa15801561082f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108539190613e31565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff881660248201819052604482018890529192506323b872dd906064016020604051808303815f875af11580156108cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f09190613e48565b506040517f89afcb4400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8716906389afcb449060240160408051808303815f875af1158015610959573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097d9190613e63565b50505f8673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ed9190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610a57573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a7b9190613e31565b90505f8773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aeb9190613e16565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610b55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b799190613e31565b9050610b858483613eb2565b9550610b918382613eb2565b9450505050509250929050565b5f8060608080858067ffffffffffffffff811115610bbe57610bbe613ec5565b604051908082528060200260200182016040528015610be7578160200160208202803683370190505b5092508067ffffffffffffffff811115610c0357610c03613ec5565b604051908082528060200260200182016040528015610c2c578160200160208202803683370190505b5091505f5b81811015610d92575f898983818110610c4c57610c4c613ef2565b6001546040517f9cc7f70800000000000000000000000000000000000000000000000000000000815260209290920293909301356004820181905293505f9283925073ffffffffffffffffffffffffffffffffffffffff1690639cc7f708906024016040805180830381865afa158015610cc8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f2a565b91509150818a019950808901985081878581518110610d0d57610d0d613ef2565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505080868581518110610d5257610d52613ef2565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050505050806001019050610c31565b508787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250989b979a5091985093965091949350505050565b5f807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff808216908c1603610fd9576040805133602482015230604482015260648082018d905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052905173ffffffffffffffffffffffffffffffffffffffff8d1691610ead91613f57565b5f604051808303815f865af19150503d805f8114610ee6576040519150601f19603f3d011682016040523d82523d5f602084013e610eeb565b606091505b5050506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528a60048201525f806024835f865af150505f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018a90523360248201526044810187905273ffffffffffffffffffffffffffffffffffffffff868116606483015290911690637a3e3495908c9060840160206040518083038185885af1158015610fa9573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fce9190613e31565b8a92509250506117d2565b508515611236576040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811660248301525f917f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f9091169063e6a4390590604401602060405180830381865afa158015611096573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ba9190613e16565b90506111838b828c8c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611143573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111679190613e16565b73ffffffffffffffffffffffffffffffffffffffff1614612b42565b5f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018b90523360248201526044810188905273ffffffffffffffffffffffffffffffffffffffff8781166064830152929450911690637a3e349590479060840160206040518083038185885af1158015611209573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061122e9190613e31565b9250506117d2565b6040805133602482015230604482015260648082018c905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052905173ffffffffffffffffffffffffffffffffffffffff8c16916112ca91613f57565b5f604051808303815f865af19150503d805f8114611303576040519150601f19603f3d011682016040523d82523d5f602084013e611308565b606091505b50505f5473ffffffffffffffffffffffffffffffffffffffff8c81169116148015915061138157507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614155b15611538576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564811660248301528a91908c169063dd62ed3e90604401602060405180830381865afa158015611419573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143d9190613e31565b101561153857604080517f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916114f69190613f57565b5f604051808303815f865af19150503d805f811461152f576040519150601f19603f3d011682016040523d82523d5f602084013e611534565b606091505b5050505b604080516101008101825273ffffffffffffffffffffffffffffffffffffffff8c811682527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116602083015262ffffff88168284015230606083015242608083015260a082018c905260c082018b90525f60e0830181905292517f414bf3890000000000000000000000000000000000000000000000000000000081527f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564919091169163414bf3899161168591906004015f6101008201905073ffffffffffffffffffffffffffffffffffffffff80845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af11580156116a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c59190613e31565b90505f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af150505f546040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018b90523360248201526044810188905273ffffffffffffffffffffffffffffffffffffffff878116606483015290911690637a3e349590849060840160206040518083038185885af11580156117a6573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906117cb9190613e31565b9350909150505b9850989650505050505050565b5f805f3073ffffffffffffffffffffffffffffffffffffffff166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561182b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061184f9190613f8e565b905061187561185d82613021565b61186687613021565b61186f87613021565b89613488565b9097909650945050505050565b5f815f036118935750617530919050565b816001036118a45750614e20919050565b816002036118b55750612710919050565b816003036118c65750611388919050565b816004036118d757506107d0919050565b816005036118e857506103e8919050565b816006036118f95750610258919050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c69645f666c61670000000000000000000000000000000000000000604482015260640161056f565b919050565b5f807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60608360020b13156119be576119b7837ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6060613fa9565b90506119eb565b6119e8837ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6060613fa9565b90505b5f8160020b1215611a02576119ff81613fea565b90505b6201a388611a15600283900b604b614026565b611a1f919061406a565b9392505050565b5f7f000000000000000000000000ceb492c5e67385e2a08265352d646a0c32a5d08573ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015611a90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ab4919061408e565b50939550611acc945060c89350859250614120915050565b611ad79060c8614193565b905090565b5f3073ffffffffffffffffffffffffffffffffffffffff16630fad9b098373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b42573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b669190613e16565b8473ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611baf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bd39190613e16565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa158015611c41573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106519190613e16565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222161480611cde57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a5feaa84fd119cf27baedc7a31015bc4d6133ca916145b611d44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f6465760000000000000000000000000000000000000000000000000000000000604482015260640161056f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f614e20611d9b836127106141b9565b611a159085614026565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222161480611e1e57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a5feaa84fd119cf27baedc7a31015bc4d6133ca916145b611e84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f6465760000000000000000000000000000000000000000000000000000000000604482015260640161056f565b5f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f807f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f35573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f599190613e16565b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526064604483018190529293505f9290841691631698ee829101602060405180830381865afa925050508015612014575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261201191810190613e16565b60015b156120f75773ffffffffffffffffffffffffffffffffffffffff8116156120f5578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156120ba575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526120b7918101906141cc565b60015b156120f557826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1611156120f357606494508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526101f46044830152831690631698ee8290606401602060405180830381865afa9250505080156121ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526121aa91810190613e16565b60015b156122915773ffffffffffffffffffffffffffffffffffffffff81161561228f578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612253575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612250918101906141cc565b60015b1561228f57826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561228d576101f494508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301528581166024830152610bb86044830152831690631698ee8290606401602060405180830381865afa925050508015612347575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261234491810190613e16565b60015b1561242b5773ffffffffffffffffffffffffffffffffffffffff811615612429578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123ed575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526123ea918101906141cc565b60015b1561242957826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561242757610bb894508092505b505b505b6040517f1698ee8200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015285811660248301526127106044830152831690631698ee8290606401602060405180830381865afa9250505080156124e1575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124de91810190613e16565b60015b156125c55773ffffffffffffffffffffffffffffffffffffffff8116156125c3578073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612587575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612584918101906141cc565b60015b156125c357826fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1611156125c15761271094508092505b505b505b505092915050565b5f8415612610576126096125e084613021565b6125e984613021565b6126046125f587613021565b6125fe87613021565b89613571565b61362c565b9050612648565b61264561261c84613021565b61262584613021565b61264061263187613021565b61263a87613021565b896136e8565b613740565b90505b949350505050565b5f805f805f805f803073ffffffffffffffffffffffffffffffffffffffff166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c59190613f8e565b6040517f99fbab88000000000000000000000000000000000000000000000000000000008152600481018b90529091507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe8873ffffffffffffffffffffffffffffffffffffffff16906399fbab889060240161018060405180830381865afa158015612752573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061277691906141f2565b909192939495969798999a509091929394959697989950909192939495965090919250909150905050809a50819650829750839b50849c5050505050506127d16127bf82613021565b6127c885613021565b61186f85613021565b989a97995095979596945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a22221614612881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f6d756c7469536967000000000000000000000000000000000000000000000000604482015260640161056f565b801561291f576040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303815f875af11580156128f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061291d9190613e48565b505b47156129a15760405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222169047905f81818185875af1925050503d805f8114612998576040519150601f19603f3d011682016040523d82523d5f602084013e61299d565b606091505b5050505b505050565b5f805f807f000000000000000000000000ceb492c5e67385e2a08265352d646a0c32a5d08573ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612a13573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a37919061408e565b50939650939450612a7e9350849250612a539150899050613021565b612a5c88613021565b612a7985612a698c613021565b612a728c613021565b8f8f6137c2565b613488565b90999098509650505050505050565b5f805f7f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe8873ffffffffffffffffffffffffffffffffffffffff166399fbab88856040518263ffffffff1660e01b8152600401612aeb91815260200190565b61018060405180830381865afa158015612b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b2b91906141f2565b50979e969d50919b50949950505050505050505050565b6040805133602482015273ffffffffffffffffffffffffffffffffffffffff8681166044830152606480830187905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f92881691612bda91613f57565b5f604051808303815f865af19150503d805f8114612c13576040519150601f19603f3d011682016040523d82523d5f602084013e612c18565b606091505b5050508115612dd1575f808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c9091906142cb565b506040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529294509092505f918a16906370a0823190602401602060405180830381865afa158015612d03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d279190613e31565b9050612d3d612d368383613eb2565b83856138e1565b935083861115612d79576040517f0d35962a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081528460048201525f6024820152306044820152608060648201525f60848201525f8060a4835f8d5af15050505050612f7d565b5f808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612e1c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4091906142cb565b506040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529294509092505f918a16906370a0823190602401602060405180830381865afa158015612eb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed79190613e31565b9050612eed612ee68483613eb2565b84846138e1565b935083861115612f29576040517f0d35962a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081525f6004820152846024820152306044820152608060648201525f60848201525f8060a4835f8d5af150505050505b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d906024015f604051808303815f87803b158015613002575f80fd5b505af1158015613014573d5f803e3d5ffd5b5050505095945050505050565b5f805f8360020b12613036578260020b613043565b8260020b613043906142f6565b9050620d89e88111156130b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f5400000000000000000000000000000000000000000000000000000000000000604482015260640161056f565b5f816001165f036130d4577001000000000000000000000000000000006130e6565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615613125576080613120826ffff97272373d413259a46990580e213a614026565b901c90505b600482161561314f57608061314a826ffff2e50f5f656932ef12357cf3c7fdcc614026565b901c90505b6008821615613179576080613174826fffe5caca7e10e4e61c3624eaa0941cd0614026565b901c90505b60108216156131a357608061319e826fffcb9843d60f6159c9db58835c926644614026565b901c90505b60208216156131cd5760806131c8826fff973b41fa98c081472e6896dfb254c0614026565b901c90505b60408216156131f75760806131f2826fff2ea16466c96a3843ec78b326b52861614026565b901c90505b608082161561322157608061321c826ffe5dee046a99a2a811c461f1969c3053614026565b901c90505b61010082161561324c576080613247826ffcbe86c7900a88aedcffc83b479aa3a4614026565b901c90505b610200821615613277576080613272826ff987a7253ac413176f2b074cf7815e54614026565b901c90505b6104008216156132a257608061329d826ff3392b0822b70005940c7a398e4b70f3614026565b901c90505b6108008216156132cd5760806132c8826fe7159475a2c29b7443b29c7fa6e889d9614026565b901c90505b6110008216156132f85760806132f3826fd097f3bdfd2022b8845ad8f792aa5825614026565b901c90505b61200082161561332357608061331e826fa9f746462d870fdf8a65dc1f90e061e5614026565b901c90505b61400082161561334e576080613349826f70d869a156d2a1b890bb3df62baf32f7614026565b901c90505b618000821615613379576080613374826f31be135f97d08fd981231505542fcfa6614026565b901c90505b620100008216156133a55760806133a0826f09aa508b5b7a84e1c677de54f3e99bc9614026565b901c90505b620200008216156133d05760806133cb826e5d6af8dedb81196699c329225ee604614026565b901c90505b620400008216156133fa5760806133f5826d2216e584f5fa1ea926041bedfe98614026565b901c90505b6208000082161561342257608061341d826b048a170391f7dc42444e8fa2614026565b901c90505b5f8460020b131561345a57613457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61406a565b90505b6134696401000000008261432c565b15613475576001613477565b5f5b6126489060ff16602083901c6141b9565b5f808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134c2579293925b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16116135075761350085858561362c565b9150613568565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16101561355a5761354686858561362c565b9150613553858785613740565b9050613568565b613565858585613740565b90505b94509492505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1611156135aa579192915b5f6135ef8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000061391c565b905061362361361e8483613603898961433f565b73ffffffffffffffffffffffffffffffffffffffff1661391c565b6139e5565b95945050505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613665579192915b73ffffffffffffffffffffffffffffffffffffffff84166136de7bffffffffffffffffffffffffffffffff000000000000000000000000606085901b166136ac878761433f565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1661391c565b612648919061406a565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613721579192915b61264861361e836c01000000000000000000000000613603888861433f565b5f8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115613779579192915b6126486fffffffffffffffffffffffffffffffff8316613799868661433f565b73ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000061391c565b5f8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156137fb579293925b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161161384057613839858585613571565b9050613623565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1610156138cc575f613880878686613571565b90505f61388e8789866136e8565b9050806fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff16106138c157806138c3565b815b92505050613623565b6138d78585846136e8565b9695505050505050565b5f806138ef856103e5614026565b9050806138fe856103e8614026565b61390891906141b9565b6139128483614026565b613623919061406a565b5f80807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff858709858702925082811083820303915050805f0361396f575f8411613964575f80fd5b508290049050611a1f565b80841161397a575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b806fffffffffffffffffffffffffffffffff8116811461195b575f80fd5b73ffffffffffffffffffffffffffffffffffffffff81168114613a24575f80fd5b50565b5f8060408385031215613a38575f80fd5b8235613a4381613a03565b91506020830135613a5381613a03565b809150509250929050565b5f8060408385031215613a6f575f80fd5b8235613a7a81613a03565b946020939093013593505050565b5f8060208385031215613a99575f80fd5b823567ffffffffffffffff80821115613ab0575f80fd5b818501915085601f830112613ac3575f80fd5b813581811115613ad1575f80fd5b8660208260051b8501011115613ae5575f80fd5b60209290920196919550909350505050565b5f8151808452602080850194508084015f5b83811015613b375781516fffffffffffffffffffffffffffffffff1687529582019590820190600101613b09565b509495945050505050565b5f60a082016fffffffffffffffffffffffffffffffff808916845260208189168186015260a06040860152829150875180845260c08601925081890193505f5b81811015613b9e57845184529382019392820192600101613b82565b5050508381036060850152613bb38187613af7565b9150508281036080840152613bc88185613af7565b98975050505050505050565b8015158114613a24575f80fd5b62ffffff81168114613a24575f80fd5b5f805f805f805f80610100898b031215613c09575f80fd5b8835613c1481613a03565b97506020890135965060408901359550606089013594506080890135613c3981613bd4565b935060a0890135613c4981613be1565b925060c0890135915060e0890135613c6081613a03565b809150509295985092959890939650565b6fffffffffffffffffffffffffffffffff81168114613a24575f80fd5b8060020b8114613a24575f80fd5b5f805f60608486031215613cae575f80fd5b8335613cb981613c71565b92506020840135613cc981613c8e565b91506040840135613cd981613c8e565b809150509250925092565b5f60208284031215613cf4575f80fd5b5035919050565b5f60208284031215613d0b575f80fd5b8135611a1f81613c8e565b5f60208284031215613d26575f80fd5b8135611a1f81613a03565b5f8060408385031215613d42575f80fd5b50508035926020909101359150565b5f805f8060808587031215613d64575f80fd5b8435613d6f81613bd4565b9350602085013592506040850135613d8681613c8e565b91506060850135613d9681613c8e565b939692955090935050565b5f805f60608486031215613db3575f80fd5b8335613dbe81613a03565b92506020840135613dce81613a03565b929592945050506040919091013590565b5f805f8060808587031215613df2575f80fd5b84359350602085013592506040850135613d8681613c8e565b805161195b81613a03565b5f60208284031215613e26575f80fd5b8151611a1f81613a03565b5f60208284031215613e41575f80fd5b5051919050565b5f60208284031215613e58575f80fd5b8151611a1f81613bd4565b5f8060408385031215613e74575f80fd5b505080516020909101519092909150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561065157610651613e85565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b805161195b81613c71565b5f8060408385031215613f3b575f80fd5b8251613f4681613c71565b6020840151909250613a5381613c71565b5f82515f5b81811015613f765760208186018101518583015201613f5c565b505f920191825250919050565b805161195b81613c8e565b5f60208284031215613f9e575f80fd5b8151611a1f81613c8e565b600281810b9083900b01627fffff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008212171561065157610651613e85565b5f8160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361401e5761401e613e85565b5f0392915050565b808202811582820484141761065157610651613e85565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826140785761407861403d565b500490565b805161ffff8116811461195b575f80fd5b5f805f805f805f60e0888a0312156140a4575f80fd5b87516140af81613a03565b60208901519097506140c081613c8e565b95506140ce6040890161407d565b94506140dc6060890161407d565b93506140ea6080890161407d565b925060a088015160ff811681146140ff575f80fd5b60c089015190925061411081613bd4565b8091505092959891949750929550565b5f8160020b8360020b806141365761413661403d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008314161561418a5761418a613e85565b90059392505050565b5f8260020b8260020b028060020b91508082146141b2576141b2613e85565b5092915050565b8082018082111561065157610651613e85565b5f602082840312156141dc575f80fd5b8151611a1f81613c71565b805161195b81613be1565b5f805f805f805f805f805f806101808d8f03121561420e575f80fd5b8c516bffffffffffffffffffffffff81168114614229575f80fd5b9b5061423760208e01613e0b565b9a5061424560408e01613e0b565b995061425360608e01613e0b565b985061426160808e016141e7565b975061426f60a08e01613f83565b965061427d60c08e01613f83565b955061428b60e08e01613f1f565b94506101008d015193506101208d015192506142aa6101408e01613f1f565b91506142b96101608e01613f1f565b90509295989b509295989b509295989b565b5f805f606084860312156142dd575f80fd5b8351925060208401519150604084015190509250925092565b5f7f8000000000000000000000000000000000000000000000000000000000000000820361432657614326613e85565b505f0390565b5f8261433a5761433a61403d565b500690565b73ffffffffffffffffffffffffffffffffffffffff8281168282160390808211156141b2576141b2613e8556fea2646970667358221220a58660a48ab2dc011b97e80b3f8f0e42b5e93f736cb96410943cb8fcb00d2b8b64736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000dbecdd726f6ad8e24afc78fe3cc8eb7b73c2d94d000000000000000000000000ceb492c5e67385e2a08265352d646a0c32a5d085

-----Decoded View---------------
Arg [0] : _ctls (address): 0xdbecDd726f6ad8e24aFc78fe3cC8eb7B73C2D94d
Arg [1] : _v3pool (address): 0xcEB492C5E67385E2A08265352d646a0c32A5d085

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000dbecdd726f6ad8e24afc78fe3cc8eb7b73c2d94d
Arg [1] : 000000000000000000000000ceb492c5e67385e2a08265352d646a0c32a5d085


Deployed Bytecode Sourcemap

32622:18728:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46427:341;;;;;;;;;;-1:-1:-1;46427:341:0;;;;;:::i;:::-;;:::i;:::-;;;742:42:1;730:55;;;712:74;;700:2;685:18;46427:341:0;;;;;;;;47159:776;;;;;;;;;;-1:-1:-1;47159:776:0;;;;;:::i;:::-;;:::i;:::-;;;;1291:25:1;;;1347:2;1332:18;;1325:34;;;;1264:18;47159:776:0;1117:248:1;45271:887:0;;;;;;;;;;-1:-1:-1;45271:887:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;36803:4189::-;;;;;;;;;;-1:-1:-1;36803:4189:0;;;;;:::i;:::-;;:::i;48845:482::-;;;;;;;;;;-1:-1:-1;48845:482:0;;;;;:::i;:::-;;:::i;44280:659::-;;;;;;;;;;-1:-1:-1;44280:659:0;;;;;:::i;:::-;;:::i;:::-;;;6048:1:1;6037:21;;;;6019:40;;6007:2;5992:18;44280:659:0;5877:188:1;43590:503:0;;;;;;;;;;-1:-1:-1;43590:503:0;;;;;:::i;:::-;;:::i;:::-;;;6464:25:1;;;6452:2;6437:18;43590:503:0;6318:177:1;44101:171:0;;;;;;;;;;;;;:::i;46166:253::-;;;;;;;;;;-1:-1:-1;46166:253:0;;;;;:::i;:::-;;:::i;44947:162::-;;;;;;;;;;-1:-1:-1;44947:162:0;;;;;:::i;:::-;;:::i;43369:213::-;;;;;;;;;;-1:-1:-1;43369:213:0;;;;;:::i;:::-;;:::i;45117:146::-;;;;;;;;;;-1:-1:-1;45117:146:0;;;;;:::i;:::-;;:::i;41358:2003::-;;;;;;;;;;-1:-1:-1;41358:2003:0;;;;;:::i;:::-;;:::i;:::-;;;7179:8:1;7167:21;;;7149:40;;7137:2;7122:18;41358:2003:0;7005:190:1;50230:1117:0;;;;;;;;;;-1:-1:-1;50230:1117:0;;;;;:::i;:::-;;:::i;47943:894::-;;;;;;;;;;-1:-1:-1;47943:894:0;;;;;:::i;:::-;;:::i;:::-;;;;8058:42:1;8127:15;;;8109:34;;8179:15;;;;8174:2;8159:18;;8152:43;8243:34;8231:47;;;8211:18;;;8204:75;;;;8310:2;8295:18;;8288:34;;;;8353:3;8338:19;;8331:35;8035:3;8020:19;47943:894:0;7789:583:1;46776:357:0;;;;;;;;;;-1:-1:-1;46776:357:0;;;;;:::i;:::-;;:::i;49335:887::-;;;;;;;;;;-1:-1:-1;49335:887:0;;;;;:::i;:::-;;:::i;41075:275::-;;;;;;;;;;-1:-1:-1;41075:275:0;;;;;:::i;:::-;;:::i;:::-;;;;9572:42:1;9641:15;;;9623:34;;9693:15;;;;9688:2;9673:18;;9666:43;9757:34;9745:47;9725:18;;;9718:75;9550:2;9535:18;41075:275:0;9360:439:1;46427:341:0;46534:13;46578:4;46568:14;;:6;:14;;;:32;;;;46596:4;46586:14;;:6;:14;;;46568:32;46560:58;;;;;;;10006:2:1;46560:58:0;;;9988:21:1;10045:2;10025:18;;;10018:30;10084:15;10064:18;;;10057:43;10117:18;;46560:58:0;;;;;;;;;46647:4;46637:14;;:6;:14;;;:32;;46663:6;46637:32;;;46654:6;46637:32;46693:4;;46629:40;;-1:-1:-1;46693:4:0;46684:13;;;46693:4;;46684:13;;:30;;;46710:4;46701:13;;:5;:13;;;46684:30;46680:81;;;-1:-1:-1;46747:1:0;46680:81;46427:341;;;;:::o;47159:776::-;47272:7;47281;47301:19;47338:4;47330:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47323:76;;;;;47378:10;47323:76;;;712:74:1;47323:40:0;;;;;;;;685:18:1;;47323:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47301:98;;47410:19;47447:4;47439:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47432:76;;;;;47487:10;47432:76;;;712:74:1;47432:40:0;;;;;;;;685:18:1;;47432:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47521:51;;;;;47547:10;47521:51;;;10997:34:1;47521:25:0;;;11047:18:1;;;11040:43;;;11099:18;;;11092:34;;;47410:98:0;;-1:-1:-1;47521:25:0;;10909:18:1;;47521:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;47585:30:0;;;;;47604:10;47585:30;;;712:74:1;47585:18:0;;;;;;685::1;;47585:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;47628:18;47664:4;47656:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47649:76;;;;;47704:10;47649:76;;;712:74:1;47649:40:0;;;;;;;;685:18:1;;47649:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47628:97;;47736:18;47772:4;47764:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47757:76;;;;;47812:10;47757:76;;;712:74:1;47757:40:0;;;;;;;;685:18:1;;47757:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47736:97;-1:-1:-1;47851:30:0;47867:14;47851:13;:30;:::i;:::-;47846:35;-1:-1:-1;47897:30:0;47913:14;47897:13;:30;:::i;:::-;47892:35;;47290:645;;;;47159:776;;;;;:::o;45271:887::-;45403:21;;45475:31;;;45631:8;;45669:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45669:19:0;;45657:31;;45725:4;45711:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45711:19:0;;45699:31;;45773:9;45768:334;45788:4;45784:1;:8;45768:334;;;45818:15;45836:8;;45845:1;45836:11;;;;;;;:::i;:::-;45897:10;;:29;;;;;45836:11;;;;;;;;;;45897:29;;;6464:25:1;;;45836:11:0;-1:-1:-1;45867:12:0;;;;-1:-1:-1;45897:10:0;;;:20;;6437:18:1;;45897:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45866:60;;;;45964:4;45947:21;;;;46004:4;45987:21;;;;46044:4;46029:9;46039:1;46029:12;;;;;;;;:::i;:::-;;;;;;:19;;;;;;;;;;;46082:4;46067:9;46077:1;46067:12;;;;;;;;:::i;:::-;;;;;;:19;;;;;;;;;;;45799:303;;;45794:3;;;;;45768:334;;;;46142:8;;46125:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45271:887:0;;;;-1:-1:-1;46125:25:0;;-1:-1:-1;45271:887:0;;-1:-1:-1;45271:887:0;;;-1:-1:-1;;;;45271:887:0:o;36803:4189::-;37046:15;;37137:4;37160:17;;;;;;;;37156:1029;;37235:212;;;37339:10;37235:212;;;10997:34:1;37384:4:0;11047:18:1;;;11040:43;11099:18;;;;11092:34;;;37235:212:0;;;;;;;;;;10909:18:1;;;;37235:212:0;;;;;;;;;37284:28;37235:212;;;37198:268;;:14;;;;:268;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37539:4;37533:11;37634:66;37599:8;37566:157;37773:8;37766:4;37756:8;37752:19;37745:37;37849:1;37846;37840:4;37830:8;37827:1;37820:5;37813;37808:43;-1:-1:-1;;37931:4:0;;37919:200;;;;;;;;13518:25:1;;;38025:10:0;13620:18:1;;;13613:43;13672:18;;;13665:34;;;37931:4:0;13735:15:1;;;13715:18;;;13708:43;37931:4:0;;;;37919:28;;37955:8;;13490:19:1;;37919:200:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38142:8;37889:280;;;;;;;37156:1029;37106:1090;38212:4;38208:2777;;;38267:34;;;;;:17;14015:15:1;;;38267:34:0;;;13997::1;38296:4:0;14067:15:1;;14047:18;;;14040:43;38252:12:0;;38267:9;:17;;;;;;13909:18:1;;38267:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38252:49;;38338:81;38353:9;38364:4;38370:8;38380:6;38414:4;38388:30;;38396:4;38388:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:30;;;38338:14;:81::i;:::-;38482:4;;38470:213;;;;;;;;13518:25:1;;;38589:10:0;13620:18:1;;;13613:43;13672:18;;;13665:34;;;38482:4:0;13735:15:1;;;13715:18;;;13708:43;38320:99:0;;-1:-1:-1;38482:4:0;;;38470:28;;38506:21;;13490:19:1;;38470:213:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38440:300;;;;;38208:2777;38821:192;;;38917:10;38821:192;;;10997:34:1;38958:4:0;11047:18:1;;;11040:43;11099:18;;;;11092:34;;;38821:192:0;;;;;;;;;;10909:18:1;;;;38821:192:0;;;;;;;;;38866:28;38821:192;;;38788:240;;:14;;;;:240;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39087:4:0;;;39066:26;;;39087:4;;39066:26;;;;-1:-1:-1;39066:47:0;;;39109:4;39096:17;;:9;:17;;;;39066:47;39062:635;;;39168:146;;;;;39234:4;39168:146;;;13997:34:1;39168:27:0;39278:8;14067:15:1;;14047:18;;;14040:43;39317:8:0;;39168:27;;;;;;13909:18:1;;39168:146:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;39138:540;;;39421:206;;;39544:8;39376:14;14286:55:1;;;39421:206:0;;;14268:74:1;14358:18;;;;14351:34;;;39421:206:0;;;;;;;;;;14241:18:1;;;;39421:206:0;;;;;;;;;39478:23;39421:206;;;39376:278;;:14;;;;:278;;39421:206;39376:278;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39138:540;39798:392;;;;;;;;39743:36;39798:392;;;;;39905:4;39798:392;;;;;;;;;;;;;39986:4;39798:392;;;;40024:15;39798:392;;;;;;;;;;;;;;;;39726:14;39798:392;;;;;;39743:462;;;;;39753:8;39743:36;;;;;;;:462;;39798:392;39743:462;;14566:4:1;14608:3;14597:9;14593:19;14585:27;;14631:42;14719:2;14710:6;14704:13;14700:22;14689:9;14682:41;14791:2;14783:4;14775:6;14771:17;14765:24;14761:33;14754:4;14743:9;14739:20;14732:63;14863:8;14855:4;14847:6;14843:17;14837:24;14833:39;14826:4;14815:9;14811:20;14804:69;14941:2;14933:4;14925:6;14921:17;14915:24;14911:33;14904:4;14893:9;14889:20;14882:63;15001:4;14993:6;14989:17;14983:24;14976:4;14965:9;14961:20;14954:54;15064:4;15056:6;15052:17;15046:24;15039:4;15028:9;15024:20;15017:54;15127:4;15119:6;15115:17;15109:24;15102:4;15091:9;15087:20;15080:54;15202:2;15194:4;15186:6;15182:17;15176:24;15172:33;15165:4;15154:9;15150:20;15143:63;;14396:816;;;;;39743:462:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39726:479;;40239:13;40255:4;40239:20;;40334:4;40328:11;40429:66;40394:8;40361:157;40568:6;40561:4;40551:8;40547:19;40540:35;40642:1;40639;40633:4;40623:8;40620:1;40613:5;40606;40601:43;-1:-1:-1;;40724:4:0;;40712:198;;;;;;;;13518:25:1;;;40816:10:0;13620:18:1;;;13613:43;13672:18;;;13665:34;;;40724:4:0;13735:15:1;;;13715:18;;;13708:43;40724:4:0;;;;40712:28;;40748:6;;13490:19:1;;40712:198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40682:276;-1:-1:-1;40933:6:0;;-1:-1:-1;;38208:2777:0;36803:4189;;;;;;;;;;;:::o;48845:482::-;48980:15;48997;49025:13;49041:4;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49025:37;;49096:223;49150:36;49178:7;49150:27;:36::i;:::-;49201:34;49229:5;49201:27;:34::i;:::-;49250;49278:5;49250:27;:34::i;:::-;49299:9;49096:39;:223::i;:::-;49075:244;;;;-1:-1:-1;48845:482:0;-1:-1:-1;;;;;48845:482:0:o;44280:659::-;44358:18;44393:4;44401:1;44393:9;44389:543;;-1:-1:-1;44457:5:0;44280:659;;;:::o;44389:543::-;44484:4;44492:1;44484:9;44480:452;;-1:-1:-1;44525:5:0;44280:659;;;:::o;44480:452::-;44552:4;44560:1;44552:9;44548:384;;-1:-1:-1;44593:5:0;44280:659;;;:::o;44548:384::-;44620:4;44628:1;44620:9;44616:316;;-1:-1:-1;44661:4:0;44280:659;;;:::o;44616:316::-;44687:4;44695:1;44687:9;44683:249;;-1:-1:-1;44728:4:0;44280:659;;;:::o;44683:249::-;44754:4;44762:1;44754:9;44750:182;;-1:-1:-1;44795:4:0;44280:659;;;:::o;44750:182::-;44821:4;44829:1;44821:9;44817:115;;-1:-1:-1;44862:3:0;44280:659;;;:::o;44817:115::-;44898:22;;;;;15810:2:1;44898:22:0;;;15792:21:1;15849:2;15829:18;;;15822:30;15888:14;15868:18;;;15861:42;15920:18;;44898:22:0;15608:336:1;44817:115:0;44280:659;;;:::o;43590:503::-;43679:12;43704:24;43759:7;43745:11;:21;;;43741:171;;;43804:21;:11;43818:7;43804:21;:::i;:::-;43783:42;;43741:171;;;43879:21;43889:11;43879:7;:21;:::i;:::-;43858:42;;43741:171;43947:1;43926:18;:22;;;43922:95;;;43986:19;43987:18;43986:19;:::i;:::-;43965:40;;43922:95;44079:6;44035:40;44043:26;;;;44073:2;44035:40;:::i;:::-;44034:51;;;;:::i;:::-;44027:58;43590:503;-1:-1:-1;;;43590:503:0:o;44101:171::-;44150:11;44204:13;44196:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;44174:52:0;;-1:-1:-1;44246:11:0;;-1:-1:-1;44254:3:0;;-1:-1:-1;44174:52:0;;-1:-1:-1;44246:11:0;;-1:-1:-1;;44246:11:0:i;:::-;44245:19;;44261:3;44245:19;:::i;:::-;44237:27;;44101:171;:::o;46166:253::-;46246:13;46292:4;:22;;;46341:4;46333:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46382:4;46374:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46292:119;;;;;;;;;;13946:42:1;14015:15;;;46292:119:0;;;13997:34:1;14067:15;;14047:18;;;14040:43;13909:18;;46292:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;44947:162::-;45008:10;:22;45022:8;45008:22;;;:43;;-1:-1:-1;45034:10:0;:17;45048:3;45034:17;;45008:43;45000:59;;;;;;;18858:2:1;45000:59:0;;;18840:21:1;18897:1;18877:18;;;18870:29;18935:5;18915:18;;;18908:33;18958:18;;45000:59:0;18656:326:1;45000:59:0;45070:10;:31;;;;;;;;;;;;;;;44947:162::o;43369:213::-;43485:16;43569:5;43538:26;43546:18;43538:5;:26;:::i;:::-;43526:39;;:8;:39;:::i;45117:146::-;45179:10;:22;45193:8;45179:22;;;:43;;-1:-1:-1;45205:10:0;:17;45219:3;45205:17;;45179:43;45171:59;;;;;;;18858:2:1;45171:59:0;;;18840:21:1;18897:1;18877:18;;;18870:29;18935:5;18915:18;;;18908:33;18958:18;;45171:59:0;18656:326:1;45171:59:0;45241:4;:14;;;;;;;;;;;;;;;45117:146::o;41358:2003::-;41457:14;41484:15;41512:8;41502:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41575:48;;;;;:27;19407:15:1;;;41575:48:0;;;19389:34:1;19459:15;;;19439:18;;;19432:43;41619:3:0;19491:18:1;;;19484:49;;;41484:47:0;;-1:-1:-1;41542:18:0;;41575:27;;;;;;19301:18:1;41575:48:0;;;;;;;;;;;;;;;;;;-1:-1:-1;41575:48:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41571:434;;;41693:21;;;;41689:296;;41747:7;41739:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41739:28:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41735:235;;;41823:10;41817:16;;:3;:16;;;41813:129;;;41872:3;41862:13;;41915:3;41902:16;;41813:129;41768:193;41735:235;41624:372;41571:434;42019:48;;;;;:27;19407:15:1;;;42019:48:0;;;19389:34:1;19459:15;;;19439:18;;;19432:43;42063:3:0;19491:18:1;;;19484:49;42019:27:0;;;;;19301:18:1;;42019:48:0;;;;;;;;;;;;;;;;;;-1:-1:-1;42019:48:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42015:434;;;42137:21;;;;42133:296;;42191:7;42183:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42183:28:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42179:235;;;42267:10;42261:16;;:3;:16;;;42257:129;;;42316:3;42306:13;;42359:3;42346:16;;42257:129;42212:193;42179:235;42068:372;42015:434;42463:49;;;;;:27;19407:15:1;;;42463:49:0;;;19389:34:1;19459:15;;;19439:18;;;19432:43;42507:4:0;19491:18:1;;;19484:49;42463:27:0;;;;;19301:18:1;;42463:49:0;;;;;;;;;;;;;;;;;;-1:-1:-1;42463:49:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42459:439;;;42583:22;;;;42579:299;;42638:8;42630:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42630:29:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42626:237;;;42715:10;42709:16;;:3;:16;;;42705:130;;;42764:4;42754:14;;42808:3;42795:16;;42705:130;42660:194;42626:237;42513:376;42459:439;42914:50;;;;;:27;19407:15:1;;;42914:50:0;;;19389:34:1;19459:15;;;19439:18;;;19432:43;42958:5:0;19491:18:1;;;19484:49;42914:27:0;;;;;19301:18:1;;42914:50:0;;;;;;;;;;;;;;;;;;-1:-1:-1;42914:50:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42910:444;;;43036:23;;;;43032:302;;43092:9;43084:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43084:30:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;43080:239;;;43170:10;43164:16;;:3;:16;;;43160:131;;;43219:5;43209:15;;43264:3;43251:16;;43160:131;43115:195;43080:239;42965:380;42910:444;41473:1888;;41358:2003;;;;:::o;50230:1117::-;50387:17;50421:9;50417:923;;;50461:410;50519:34;50547:5;50519:27;:34::i;:::-;50572;50600:5;50572:27;:34::i;:::-;50648:208;50710:34;50738:5;50710:27;:34::i;:::-;50767;50795:5;50767:27;:34::i;:::-;50824:13;50648:39;:208::i;:::-;50461:39;:410::i;:::-;50447:424;;50417:923;;;50918:410;50976:34;51004:5;50976:27;:34::i;:::-;51029;51057:5;51029:27;:34::i;:::-;51105:208;51167:34;51195:5;51167:27;:34::i;:::-;51224;51252:5;51224:27;:34::i;:::-;51281:13;51105:39;:208::i;:::-;50918:39;:410::i;:::-;50904:424;;50417:923;50230:1117;;;;;;:::o;47943:894::-;48068:14;48097;48126:17;48158:15;48188;48231:11;48253;48275:13;48291:4;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48538:34;;;;;;;;6464:25:1;;;48275:37:0;;-1:-1:-1;48538:15:0;:25;;;;;6437:18:1;;48538:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48325:247;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48606:223;48660:36;48688:7;48660:27;:36::i;:::-;48711:34;48739:5;48711:27;:34::i;:::-;48760;48788:5;48760:27;:34::i;48606:223::-;47943:894;;;;-1:-1:-1;47943:894:0;;48585:244;;47943:894;-1:-1:-1;;;;;47943:894:0:o;46776:357::-;46906:10;:22;46920:8;46906:22;;46898:43;;;;;;;22618:2:1;46898:43:0;;;22600:21:1;22657:1;22637:18;;;22630:29;22695:10;22675:18;;;22668:38;22723:18;;46898:43:0;22416:331:1;46898:43:0;46956:11;;46952:58;;46969:41;;;;;:22;14286:55:1;;;46969:41:0;;;14268:74:1;14358:18;;;14351:34;;;46969:22:0;;;;;14241:18:1;;46969:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;46952:58;47025:21;:25;47021:105;;47067:47;;:13;:8;:13;;47088:21;;47067:47;;;;47088:21;47067:13;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47021:105;46776:357;;;:::o;49335:887::-;49501:18;49521;49603:11;49625:17;49692:13;49684:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;49653:61:0;;-1:-1:-1;49653:61:0;;-1:-1:-1;49754:460:0;;-1:-1:-1;49653:61:0;;-1:-1:-1;49832:34:0;;-1:-1:-1;49860:5:0;;-1:-1:-1;49832:27:0;:34::i;:::-;49881;49909:5;49881:27;:34::i;:::-;49949:254;50007:9;50035:34;50063:5;50035:27;:34::i;:::-;50088;50116:5;50088:27;:34::i;:::-;50141:14;50174;49949:39;:254::i;:::-;49754:39;:460::i;:::-;49727:487;;;;-1:-1:-1;49335:887:0;-1:-1:-1;;;;;;;49335:887:0:o;41075:275::-;41179:14;41195;41211:17;41294:15;:39;;;41334:7;41294:48;;;;;;;;;;;;;6464:25:1;;6452:2;6437:18;;6318:177;41294:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;41246:96:0;;;;-1:-1:-1;41246:96:0;;-1:-1:-1;41075:275:0;;-1:-1:-1;;;;;;;;;;41075:275:0:o;34499:2296::-;34724:182;;;34820:10;34724:182;;;10997:34:1;34695:10:0;11067:15:1;;;11047:18;;;11040:43;11099:18;;;;11092:34;;;34724:182:0;;;;;;;;;;10909:18:1;;;;34724:182:0;;;;;;;;;34769:28;34724:182;;;34695:222;;-1:-1:-1;;34695:10:0;;;:222;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34934:12;34930:1814;;;34978:13;34993;35020:5;35012:44;;;:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;35087:30:0;;;;;:23;730:55:1;;;35087:30:0;;;712:74:1;34977:81:0;;-1:-1:-1;34977:81:0;;-1:-1:-1;35073:11:0;;35087:23;;;;;685:18:1;;35087:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35073:44;-1:-1:-1;35144:51:0;35157:17;35166:8;35073:44;35157:17;:::i;:::-;35176:8;35186;35144:12;:51::i;:::-;35132:63;;35223:9;35214:6;:18;35210:37;;;35241:6;;;;;;;;;;;;;;35210:37;35314:4;35308:11;35397:66;35366:8;35337:145;35528:9;35521:4;35511:8;35507:19;35500:38;35584:1;35577:4;35567:8;35563:19;35556:30;35632:9;35625:4;35615:8;35611:19;35604:38;35688:4;35681;35671:8;35667:19;35660:33;35739:1;35732:4;35722:8;35718:19;35711:30;35804:1;35801;35795:4;35785:8;35782:1;35775:5;35768;35763:43;35759:48;;35271:551;;;34930:1814;;;35855:16;35873;35903:5;35895:44;;;:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;35975:30:0;;;;;:23;730:55:1;;;35975:30:0;;;712:74:1;35854:87:0;;-1:-1:-1;35854:87:0;;-1:-1:-1;35958:14:0;;35975:23;;;;;685:18:1;;35975:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35958:47;-1:-1:-1;36032:51:0;36045:17;36054:8;35958:47;36045:17;:::i;:::-;36064:8;36074;36032:12;:51::i;:::-;36020:63;;36111:9;36102:6;:18;36098:37;;;36129:6;;;;;;;;;;;;;;36098:37;36214:4;36208:11;36297:66;36266:8;36237:145;36428:1;36421:4;36411:8;36407:19;36400:30;36476:9;36469:4;36459:8;36455:19;36448:38;36532:9;36525:4;36515:8;36511:19;36504:38;36588:4;36581;36571:8;36567:19;36560:33;36639:1;36632:4;36622:8;36618:19;36611:30;36704:1;36701;36695:4;36685:8;36682:1;36675:5;36668;36663:43;36659:48;;36173:549;;;34930:1814;36756:31;;;;;;;;6464:25:1;;;36762:4:0;36756:20;;;;;6437:18:1;;36756:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34499:2296;;;;;;;:::o;28930:2958::-;29009:20;29042:15;29067:1;29060:4;:8;;;:83;;29137:4;29130:12;;29060:83;;;29100:4;29093:12;;29092:13;;;:::i;:::-;29042:101;-1:-1:-1;28194:6:0;29162:36;;;29154:50;;;;;;;23671:2:1;29154:50:0;;;23653:21:1;23710:1;23690:18;;;23683:29;23748:3;23728:18;;;23721:31;23769:18;;29154:50:0;23469:324:1;29154:50:0;29217:13;29233:7;29243:3;29233:13;29250:1;29233:18;:119;;29317:35;29233:119;;;29267:34;29233:119;29217:135;;;-1:-1:-1;29377:3:0;29367:13;;:18;29363:96;;29456:3;29409:42;:5;29417:34;29409:42;:::i;:::-;29408:51;;29400:59;;29363:96;29484:3;29474:13;;:18;29470:96;;29563:3;29516:42;:5;29524:34;29516:42;:::i;:::-;29515:51;;29507:59;;29470:96;29591:3;29581:13;;:18;29577:96;;29670:3;29623:42;:5;29631:34;29623:42;:::i;:::-;29622:51;;29614:59;;29577:96;29698:4;29688:14;;:19;29684:97;;29778:3;29731:42;:5;29739:34;29731:42;:::i;:::-;29730:51;;29722:59;;29684:97;29806:4;29796:14;;:19;29792:97;;29886:3;29839:42;:5;29847:34;29839:42;:::i;:::-;29838:51;;29830:59;;29792:97;29914:4;29904:14;;:19;29900:97;;29994:3;29947:42;:5;29955:34;29947:42;:::i;:::-;29946:51;;29938:59;;29900:97;30022:4;30012:14;;:19;30008:97;;30102:3;30055:42;:5;30063:34;30055:42;:::i;:::-;30054:51;;30046:59;;30008:97;30130:5;30120:15;;:20;30116:98;;30211:3;30164:42;:5;30172:34;30164:42;:::i;:::-;30163:51;;30155:59;;30116:98;30239:5;30229:15;;:20;30225:98;;30320:3;30273:42;:5;30281:34;30273:42;:::i;:::-;30272:51;;30264:59;;30225:98;30348:5;30338:15;;:20;30334:98;;30429:3;30382:42;:5;30390:34;30382:42;:::i;:::-;30381:51;;30373:59;;30334:98;30457:5;30447:15;;:20;30443:98;;30538:3;30491:42;:5;30499:34;30491:42;:::i;:::-;30490:51;;30482:59;;30443:98;30566:6;30556:16;;:21;30552:99;;30648:3;30601:42;:5;30609:34;30601:42;:::i;:::-;30600:51;;30592:59;;30552:99;30676:6;30666:16;;:21;30662:99;;30758:3;30711:42;:5;30719:34;30711:42;:::i;:::-;30710:51;;30702:59;;30662:99;30786:6;30776:16;;:21;30772:99;;30868:3;30821:42;:5;30829:34;30821:42;:::i;:::-;30820:51;;30812:59;;30772:99;30896:6;30886:16;;:21;30882:99;;30978:3;30931:42;:5;30939:34;30931:42;:::i;:::-;30930:51;;30922:59;;30882:99;31006:7;30996:17;;:22;30992:99;;31088:3;31042:41;:5;31050:33;31042:41;:::i;:::-;31041:50;;31033:58;;30992:99;31116:7;31106:17;;:22;31102:98;;31197:3;31152:40;:5;31160:32;31152:40;:::i;:::-;31151:49;;31143:57;;31102:98;31225:7;31215:17;;:22;31211:96;;31304:3;31261:38;:5;31269:30;31261:38;:::i;:::-;31260:47;;31252:55;;31211:96;31332:7;31322:17;;:22;31318:91;;31406:3;31368:33;:5;31376:25;31368:33;:::i;:::-;31367:42;;31359:50;;31318:91;31433:1;31426:4;:8;;;31422:47;;;31444:25;31464:5;31444:17;:25;:::i;:::-;31436:33;;31422:47;31838:17;31847:7;31838:5;:17;:::i;:::-;:22;:30;;31867:1;31838:30;;;31863:1;31838:30;31821:48;;;;31831:2;31822:11;;;31821:48;:::i;22787:1092::-;22972:15;22989;23037:13;23021:29;;:13;:29;;;23017:111;;;23099:13;;23114;23017:111;23161:13;23145:29;;:12;:29;;;23141:731;;23201:129;23242:13;23274;23306:9;23201:22;:129::i;:::-;23191:139;;23141:731;;;23367:13;23352:28;;:12;:28;;;23348:524;;;23407:128;23448:12;23479:13;23511:9;23407:22;:128::i;:::-;23397:138;;23560:128;23601:13;23633:12;23664:9;23560:22;:128::i;:::-;23550:138;;23348:524;;;23731:129;23772:13;23804;23836:9;23731:22;:129::i;:::-;23721:139;;23348:524;22787:1092;;;;;;;:::o;24355:693::-;24507:17;24557:13;24541:29;;:13;:29;;;24537:111;;;24619:13;;24634;24537:111;24659:20;24682:133;24712:13;24682:133;;24740:13;24682:133;;24776:27;24682:15;:133::i;:::-;24659:156;-1:-1:-1;24846:194:0;24874:151;24912:7;24659:156;24977:29;24993:13;24977;:29;:::i;:::-;24874:151;;:15;:151::i;:::-;24846:9;:194::i;:::-;24826:214;24355:693;-1:-1:-1;;;;;24355:693:0:o;20872:524::-;21026:15;21074:13;21058:29;;:13;:29;;;21054:111;;;21136:13;;21151;21054:111;21198:190;;;:174;21232:45;13354:2;21232:45;;;;21296:29;21375:13;21296;:29;:::i;:::-;21198:174;;21344:13;21198:174;;:15;:174::i;:::-;:190;;;;:::i;25495:550::-;25647:17;25697:13;25681:29;;:13;:29;;;25677:111;;;25759:13;;25774;25677:111;25819:218;25847:175;25885:7;25923:27;25974:29;25990:13;25974;:29;:::i;21761:475::-;21915:15;21963:13;21947:29;;:13;:29;;;21943:111;;;22025:13;;22040;21943:111;22087:141;;;;22149:29;22165:13;22149;:29;:::i;:::-;22087:141;;13395:27;22087:15;:141::i;26655:1197::-;26864:17;26914:13;26898:29;;:13;:29;;;26894:111;;;26976:13;;26991;26894:111;27038:13;27022:29;;:12;:29;;;27018:827;;27080:127;27121:13;27153;27185:7;27080:22;:127::i;:::-;27068:139;;27018:827;;;27244:13;27229:28;;:12;:28;;;27225:620;;;27274:18;27295:126;27336:12;27367:13;27399:7;27295:22;:126::i;:::-;27274:147;;27436:18;27457:126;27498:13;27530:12;27561:7;27457:22;:126::i;:::-;27436:147;;27625:10;27612:23;;:10;:23;;;:49;;27651:10;27612:49;;;27638:10;27612:49;27600:61;;27259:414;;27225:620;;;27706:127;27747:13;27779;27811:7;27706:22;:127::i;:::-;27694:139;26655:1197;-1:-1:-1;;;;;;26655:1197:0:o;34172:319::-;34299:14;;34349;:8;34360:3;34349:14;:::i;:::-;34326:37;-1:-1:-1;34326:37:0;34447:16;:9;34459:4;34447:16;:::i;:::-;34446:36;;;;:::i;:::-;34400:28;34418:10;34400:15;:28;:::i;:::-;34399:84;;;;:::i;13824:4293::-;13940:14;;;14516:6;14513:1;14510;14503:20;14557:1;14554;14550:9;14541:18;;14613:5;14609:2;14606:13;14598:5;14594:2;14590:14;14586:34;14577:43;;;14718:5;14727:1;14718:10;14714:209;;14771:1;14757:11;:15;14749:24;;;;;;-1:-1:-1;14834:23:0;;;;-1:-1:-1;14894:13:0;;14714:209;15066:5;15052:11;:19;15044:28;;;;;;15381:17;15467:11;15464:1;15461;15454:25;15870:12;15893:20;;;:42;;16097:22;;;;;16992:1;16973;:15;;16972:21;;17239:17;;;17235:21;;17228:28;17302:17;;;17298:21;;17291:28;17366:17;;;17362:21;;17355:28;17430:17;;;17426:21;;17419:28;17494:17;;;17490:21;;17483:28;17559:17;;;17555:21;;;17548:28;16520:12;;;;16516:23;;;16541:1;16512:31;15616:20;;;15605:32;;;16581:12;;;;15664:21;;;;16246:16;;;;16572:21;;;;18059:11;;;;;-1:-1:-1;;13824:4293:0;;;;;:::o;20395:112::-;20497:1;20477:21;;;;;20469:30;;;;;14:154:1;100:42;93:5;89:54;82:5;79:65;69:93;;158:1;155;148:12;69:93;14:154;:::o;173:388::-;241:6;249;302:2;290:9;281:7;277:23;273:32;270:52;;;318:1;315;308:12;270:52;357:9;344:23;376:31;401:5;376:31;:::i;:::-;426:5;-1:-1:-1;483:2:1;468:18;;455:32;496:33;455:32;496:33;:::i;:::-;548:7;538:17;;;173:388;;;;;:::o;797:315::-;865:6;873;926:2;914:9;905:7;901:23;897:32;894:52;;;942:1;939;932:12;894:52;981:9;968:23;1000:31;1025:5;1000:31;:::i;:::-;1050:5;1102:2;1087:18;;;;1074:32;;-1:-1:-1;;;797:315:1:o;1370:615::-;1456:6;1464;1517:2;1505:9;1496:7;1492:23;1488:32;1485:52;;;1533:1;1530;1523:12;1485:52;1573:9;1560:23;1602:18;1643:2;1635:6;1632:14;1629:34;;;1659:1;1656;1649:12;1629:34;1697:6;1686:9;1682:22;1672:32;;1742:7;1735:4;1731:2;1727:13;1723:27;1713:55;;1764:1;1761;1754:12;1713:55;1804:2;1791:16;1830:2;1822:6;1819:14;1816:34;;;1846:1;1843;1836:12;1816:34;1899:7;1894:2;1884:6;1881:1;1877:14;1873:2;1869:23;1865:32;1862:45;1859:65;;;1920:1;1917;1910:12;1859:65;1951:2;1943:11;;;;;1973:6;;-1:-1:-1;1370:615:1;;-1:-1:-1;;;;1370:615:1:o;1990:476::-;2043:3;2081:5;2075:12;2108:6;2103:3;2096:19;2134:4;2163:2;2158:3;2154:12;2147:19;;2200:2;2193:5;2189:14;2221:1;2231:210;2245:6;2242:1;2239:13;2231:210;;;2310:13;;2325:34;2306:54;2294:67;;2381:12;;;;2416:15;;;;2267:1;2260:9;2231:210;;;-1:-1:-1;2457:3:1;;1990:476;-1:-1:-1;;;;;1990:476:1:o;2471:1225::-;2825:4;2873:3;2862:9;2858:19;2896:34;2969:2;2961:6;2957:15;2946:9;2939:34;2992:2;3042;3034:6;3030:15;3025:2;3014:9;3010:18;3003:43;3082:3;3077:2;3066:9;3062:18;3055:31;3106:6;3095:17;;3141:6;3135:13;3172:6;3164;3157:22;3210:3;3199:9;3195:19;3188:26;;3249:2;3241:6;3237:15;3223:29;;3270:1;3280:169;3294:6;3291:1;3288:13;3280:169;;;3355:13;;3343:26;;3424:15;;;;3389:12;;;;3316:1;3309:9;3280:169;;;3284:3;;;3494:9;3489:3;3485:19;3480:2;3469:9;3465:18;3458:47;3528:41;3565:3;3557:6;3528:41;:::i;:::-;3514:55;;;3618:9;3610:6;3606:22;3600:3;3589:9;3585:19;3578:51;3646:44;3683:6;3675;3646:44;:::i;:::-;3638:52;2471:1225;-1:-1:-1;;;;;;;;2471:1225:1:o;3701:118::-;3787:5;3780:13;3773:21;3766:5;3763:32;3753:60;;3809:1;3806;3799:12;3824:119;3909:8;3902:5;3898:20;3891:5;3888:31;3878:59;;3933:1;3930;3923:12;3948:939;4066:6;4074;4082;4090;4098;4106;4114;4122;4175:3;4163:9;4154:7;4150:23;4146:33;4143:53;;;4192:1;4189;4182:12;4143:53;4231:9;4218:23;4250:31;4275:5;4250:31;:::i;:::-;4300:5;-1:-1:-1;4352:2:1;4337:18;;4324:32;;-1:-1:-1;4403:2:1;4388:18;;4375:32;;-1:-1:-1;4454:2:1;4439:18;;4426:32;;-1:-1:-1;4510:3:1;4495:19;;4482:33;4524:30;4482:33;4524:30;:::i;:::-;4573:7;-1:-1:-1;4632:3:1;4617:19;;4604:33;4646:32;4604:33;4646:32;:::i;:::-;4697:7;-1:-1:-1;4751:3:1;4736:19;;4723:33;;-1:-1:-1;4808:3:1;4793:19;;4780:33;4822;4780;4822;:::i;:::-;4874:7;4864:17;;;3948:939;;;;;;;;;;;:::o;4892:146::-;4978:34;4971:5;4967:46;4960:5;4957:57;4947:85;;5028:1;5025;5018:12;5043:118;5130:5;5127:1;5116:20;5109:5;5106:31;5096:59;;5151:1;5148;5141:12;5166:521;5239:6;5247;5255;5308:2;5296:9;5287:7;5283:23;5279:32;5276:52;;;5324:1;5321;5314:12;5276:52;5363:9;5350:23;5382:31;5407:5;5382:31;:::i;:::-;5432:5;-1:-1:-1;5489:2:1;5474:18;;5461:32;5502:31;5461:32;5502:31;:::i;:::-;5552:7;-1:-1:-1;5611:2:1;5596:18;;5583:32;5624:31;5583:32;5624:31;:::i;:::-;5674:7;5664:17;;;5166:521;;;;;:::o;5692:180::-;5751:6;5804:2;5792:9;5783:7;5779:23;5775:32;5772:52;;;5820:1;5817;5810:12;5772:52;-1:-1:-1;5843:23:1;;5692:180;-1:-1:-1;5692:180:1:o;6070:243::-;6127:6;6180:2;6168:9;6159:7;6155:23;6151:32;6148:52;;;6196:1;6193;6186:12;6148:52;6235:9;6222:23;6254:29;6277:5;6254:29;:::i;6500:247::-;6559:6;6612:2;6600:9;6591:7;6587:23;6583:32;6580:52;;;6628:1;6625;6618:12;6580:52;6667:9;6654:23;6686:31;6711:5;6686:31;:::i;6752:248::-;6820:6;6828;6881:2;6869:9;6860:7;6856:23;6852:32;6849:52;;;6897:1;6894;6887:12;6849:52;-1:-1:-1;;6920:23:1;;;6990:2;6975:18;;;6962:32;;-1:-1:-1;6752:248:1:o;7200:584::-;7279:6;7287;7295;7303;7356:3;7344:9;7335:7;7331:23;7327:33;7324:53;;;7373:1;7370;7363:12;7324:53;7412:9;7399:23;7431:28;7453:5;7431:28;:::i;:::-;7478:5;-1:-1:-1;7530:2:1;7515:18;;7502:32;;-1:-1:-1;7586:2:1;7571:18;;7558:32;7599:31;7558:32;7599:31;:::i;:::-;7649:7;-1:-1:-1;7708:2:1;7693:18;;7680:32;7721:31;7680:32;7721:31;:::i;:::-;7200:584;;;;-1:-1:-1;7200:584:1;;-1:-1:-1;;7200:584:1:o;8377:456::-;8454:6;8462;8470;8523:2;8511:9;8502:7;8498:23;8494:32;8491:52;;;8539:1;8536;8529:12;8491:52;8578:9;8565:23;8597:31;8622:5;8597:31;:::i;:::-;8647:5;-1:-1:-1;8704:2:1;8689:18;;8676:32;8717:33;8676:32;8717:33;:::i;:::-;8377:456;;8769:7;;-1:-1:-1;;;8823:2:1;8808:18;;;;8795:32;;8377:456::o;8838:517::-;8920:6;8928;8936;8944;8997:3;8985:9;8976:7;8972:23;8968:33;8965:53;;;9014:1;9011;9004:12;8965:53;9050:9;9037:23;9027:33;;9107:2;9096:9;9092:18;9079:32;9069:42;;9161:2;9150:9;9146:18;9133:32;9174:29;9197:5;9174:29;:::i;10146:138::-;10225:13;;10247:31;10225:13;10247:31;:::i;10289:251::-;10359:6;10412:2;10400:9;10391:7;10387:23;10383:32;10380:52;;;10428:1;10425;10418:12;10380:52;10460:9;10454:16;10479:31;10504:5;10479:31;:::i;10545:184::-;10615:6;10668:2;10656:9;10647:7;10643:23;10639:32;10636:52;;;10684:1;10681;10674:12;10636:52;-1:-1:-1;10707:16:1;;10545:184;-1:-1:-1;10545:184:1:o;11137:245::-;11204:6;11257:2;11245:9;11236:7;11232:23;11228:32;11225:52;;;11273:1;11270;11263:12;11225:52;11305:9;11299:16;11324:28;11346:5;11324:28;:::i;11387:245::-;11466:6;11474;11527:2;11515:9;11506:7;11502:23;11498:32;11495:52;;;11543:1;11540;11533:12;11495:52;-1:-1:-1;;11566:16:1;;11622:2;11607:18;;;11601:25;11566:16;;11601:25;;-1:-1:-1;11387:245:1:o;11637:184::-;11689:77;11686:1;11679:88;11786:4;11783:1;11776:15;11810:4;11807:1;11800:15;11826:128;11893:9;;;11914:11;;;11911:37;;;11928:18;;:::i;11959:184::-;12011:77;12008:1;12001:88;12108:4;12105:1;12098:15;12132:4;12129:1;12122:15;12148:184;12200:77;12197:1;12190:88;12297:4;12294:1;12287:15;12321:4;12318:1;12311:15;12337:138;12416:13;;12438:31;12416:13;12438:31;:::i;12480:385::-;12559:6;12567;12620:2;12608:9;12599:7;12595:23;12591:32;12588:52;;;12636:1;12633;12626:12;12588:52;12668:9;12662:16;12687:31;12712:5;12687:31;:::i;:::-;12787:2;12772:18;;12766:25;12737:5;;-1:-1:-1;12800:33:1;12766:25;12800:33;:::i;12870:412::-;12999:3;13037:6;13031:13;13062:1;13072:129;13086:6;13083:1;13080:13;13072:129;;;13184:4;13168:14;;;13164:25;;13158:32;13145:11;;;13138:53;13101:12;13072:129;;;-1:-1:-1;13256:1:1;13220:16;;13245:13;;;-1:-1:-1;13220:16:1;12870:412;-1:-1:-1;12870:412:1:o;15217:134::-;15294:13;;15316:29;15294:13;15316:29;:::i;15356:247::-;15424:6;15477:2;15465:9;15456:7;15452:23;15448:32;15445:52;;;15493:1;15490;15483:12;15445:52;15525:9;15519:16;15544:29;15567:5;15544:29;:::i;15949:243::-;16045:1;16016:16;;;16034;;;;16012:39;16075:8;16066:18;;16095:66;16086:76;;16063:100;16060:126;;;16166:18;;:::i;16197:238::-;16231:3;16278:5;16275:1;16264:20;16308:66;16299:7;16296:79;16293:105;;16378:18;;:::i;:::-;16418:1;16414:15;;16197:238;-1:-1:-1;;16197:238:1:o;16440:168::-;16513:9;;;16544;;16561:15;;;16555:22;;16541:37;16531:71;;16582:18;;:::i;16613:184::-;16665:77;16662:1;16655:88;16762:4;16759:1;16752:15;16786:4;16783:1;16776:15;16802:120;16842:1;16868;16858:35;;16873:18;;:::i;:::-;-1:-1:-1;16907:9:1;;16802:120::o;16927:163::-;17005:13;;17058:6;17047:18;;17037:29;;17027:57;;17080:1;17077;17070:12;17095:920;17209:6;17217;17225;17233;17241;17249;17257;17310:3;17298:9;17289:7;17285:23;17281:33;17278:53;;;17327:1;17324;17317:12;17278:53;17359:9;17353:16;17378:31;17403:5;17378:31;:::i;:::-;17478:2;17463:18;;17457:25;17428:5;;-1:-1:-1;17491:31:1;17457:25;17491:31;:::i;:::-;17541:7;-1:-1:-1;17567:48:1;17611:2;17596:18;;17567:48;:::i;:::-;17557:58;;17634:48;17678:2;17667:9;17663:18;17634:48;:::i;:::-;17624:58;;17701:49;17745:3;17734:9;17730:19;17701:49;:::i;:::-;17691:59;;17795:3;17784:9;17780:19;17774:26;17844:4;17835:7;17831:18;17822:7;17819:31;17809:59;;17864:1;17861;17854:12;17809:59;17939:3;17924:19;;17918:26;17887:7;;-1:-1:-1;17953:30:1;17918:26;17953:30;:::i;:::-;18002:7;17992:17;;;17095:920;;;;;;;;;;:::o;18020:389::-;18058:1;18099;18096;18085:16;18135:1;18132;18121:16;18156:3;18146:37;;18163:18;;:::i;:::-;18284:66;18279:3;18276:75;18207:66;18202:3;18199:75;18195:157;18192:183;;;18355:18;;:::i;:::-;18389:14;;;18020:389;-1:-1:-1;;;18020:389:1:o;18414:237::-;18452:7;18529:1;18526;18515:16;18511:1;18508;18497:16;18493:39;18566:11;18563:1;18552:26;18541:37;;18609:11;18600:7;18597:24;18587:58;;18625:18;;:::i;:::-;18587:58;18414:237;;;;:::o;18987:125::-;19052:9;;;19073:10;;;19070:36;;;19086:18;;:::i;19544:251::-;19614:6;19667:2;19655:9;19646:7;19642:23;19638:32;19635:52;;;19683:1;19680;19673:12;19635:52;19715:9;19709:16;19734:31;19759:5;19734:31;:::i;21084:136::-;21162:13;;21184:30;21162:13;21184:30;:::i;21225:1186::-;21388:6;21396;21404;21412;21420;21428;21436;21444;21452;21460;21468:7;21477;21531:3;21519:9;21510:7;21506:23;21502:33;21499:53;;;21548:1;21545;21538:12;21499:53;21580:9;21574:16;21630:26;21623:5;21619:38;21612:5;21609:49;21599:77;;21672:1;21669;21662:12;21599:77;21695:5;-1:-1:-1;21719:49:1;21764:2;21749:18;;21719:49;:::i;:::-;21709:59;;21787:49;21832:2;21821:9;21817:18;21787:49;:::i;:::-;21777:59;;21855:49;21900:2;21889:9;21885:18;21855:49;:::i;:::-;21845:59;;21923:49;21967:3;21956:9;21952:19;21923:49;:::i;:::-;21913:59;;21991:48;22034:3;22023:9;22019:19;21991:48;:::i;:::-;21981:58;;22058:48;22101:3;22090:9;22086:19;22058:48;:::i;:::-;22048:58;;22125:50;22170:3;22159:9;22155:19;22125:50;:::i;:::-;22115:60;;22215:3;22204:9;22200:19;22194:26;22184:36;;22260:3;22249:9;22245:19;22239:26;22229:36;;22285:50;22330:3;22319:9;22315:19;22285:50;:::i;:::-;22274:61;;22355:50;22400:3;22389:9;22385:19;22355:50;:::i;:::-;22344:61;;21225:1186;;;;;;;;;;;;;;:::o;22962:306::-;23050:6;23058;23066;23119:2;23107:9;23098:7;23094:23;23090:32;23087:52;;;23135:1;23132;23125:12;23087:52;23164:9;23158:16;23148:26;;23214:2;23203:9;23199:18;23193:25;23183:35;;23258:2;23247:9;23243:18;23237:25;23227:35;;22962:306;;;;;:::o;23273:191::-;23308:3;23339:66;23332:5;23329:77;23326:103;;23409:18;;:::i;:::-;-1:-1:-1;23449:1:1;23445:13;;23273:191::o;23798:112::-;23830:1;23856;23846:35;;23861:18;;:::i;:::-;-1:-1:-1;23895:9:1;;23798:112::o;23915:208::-;23984:42;24059:10;;;24047;;;24043:27;;24082:12;;;24079:38;;;24097:18;;:::i

Swarm Source

ipfs://a58660a48ab2dc011b97e80b3f8f0e42b5e93f736cb96410943cb8fcb00d2b8b

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

Provides utility/helper functions for Uniswap V3.

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.