Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
SigmaIndexPoolV1
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /* ========== Internal Inheritance ========== */ import "./BToken.sol"; import "./BMath.sol"; /* ========== Internal Interfaces ========== */ import "../interfaces/IIndexPool.sol"; import "../interfaces/ICompLikeToken.sol"; /************************************************************************************************ Originally from https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol This source code has been modified from the original, which was copied from the github repository at commit hash f4ed5d65362a8d6cec21662fb6eae233b0babc1f. Subject to the GPL-3.0 license *************************************************************************************************/ contract SigmaIndexPoolV1 is BToken, BMath, IIndexPool { /* ========== Modifiers ========== */ modifier _lock_ { require(!_mutex, "ERR_REENTRY"); _mutex = true; _; _mutex = false; } modifier _viewlock_() { require(!_mutex, "ERR_REENTRY"); _; } modifier _control_ { require(msg.sender == _controller, "ERR_NOT_CONTROLLER"); _; } modifier _public_ { require(_publicSwap, "ERR_NOT_PUBLIC"); _; } /* ========== Storage ========== */ bool internal _mutex; // Account with CONTROL role. Able to modify the swap fee, // adjust token weights, bind and unbind tokens and lock // public swaps & joins. address internal _controller; // Contract that handles unbound tokens. TokenUnbindHandler internal _unbindHandler; // True if PUBLIC can call SWAP & JOIN functions bool internal _publicSwap; // `setSwapFee` requires CONTROL uint256 internal _swapFee; // Array of underlying tokens in the pool. address[] internal _tokens; // Internal records of the pool's underlying tokens mapping(address => Record) internal _records; // Total denormalized weight of the pool. uint256 internal _totalWeight; // Minimum balances for tokens which have been added without the // requisite initial balance. mapping(address => uint256) internal _minimumBalances; // Recipient for exit fees address internal _exitFeeRecipient; /* ========== Controls ========== */ /** * @dev Sets the controller address and the token name & symbol. * * Note: This saves on storage costs for multi-step pool deployment. * * @param controller Controller of the pool * @param name Name of the pool token * @param symbol Symbol of the pool token */ function configure( address controller, string calldata name, string calldata symbol ) external override { require(_controller == address(0), "ERR_CONFIGURED"); require(controller != address(0), "ERR_NULL_ADDRESS"); _controller = controller; // default fee is 2% _swapFee = BONE / 50; _initializeToken(name, symbol); } /** * @dev Sets up the initial assets for the pool. * * Note: `tokenProvider` must have approved the pool to transfer the * corresponding `balances` of `tokens`. * * @param tokens Underlying tokens to initialize the pool with * @param balances Initial balances to transfer * @param denorms Initial denormalized weights for the tokens * @param tokenProvider Address to transfer the balances from * @param unbindHandler Address that receives tokens removed from the pool * @param exitFeeRecipient Address that receives exit fees */ function initialize( address[] calldata tokens, uint256[] calldata balances, uint96[] calldata denorms, address tokenProvider, address unbindHandler, address exitFeeRecipient ) external override _control_ { require(_tokens.length == 0, "ERR_INITIALIZED"); uint256 len = tokens.length; require(len >= MIN_BOUND_TOKENS, "ERR_MIN_TOKENS"); require(len <= MAX_BOUND_TOKENS, "ERR_MAX_TOKENS"); require(balances.length == len && denorms.length == len, "ERR_ARR_LEN"); uint256 totalWeight = 0; for (uint256 i = 0; i < len; i++) { address token = tokens[i]; uint96 denorm = denorms[i]; uint256 balance = balances[i]; require(denorm >= MIN_WEIGHT, "ERR_MIN_WEIGHT"); require(denorm <= MAX_WEIGHT, "ERR_MAX_WEIGHT"); require(balance >= MIN_BALANCE, "ERR_MIN_BALANCE"); _records[token] = Record({ bound: true, ready: true, lastDenormUpdate: uint40(now), denorm: denorm, desiredDenorm: denorm, index: uint8(i), balance: balance }); _tokens.push(token); totalWeight = badd(totalWeight, denorm); _pullUnderlying(token, tokenProvider, balance); } require(totalWeight <= MAX_TOTAL_WEIGHT, "ERR_MAX_TOTAL_WEIGHT"); _totalWeight = totalWeight; _publicSwap = true; emit LOG_PUBLIC_SWAP_TOGGLED(true); _mintPoolShare(INIT_POOL_SUPPLY); _pushPoolShare(tokenProvider, INIT_POOL_SUPPLY); _unbindHandler = TokenUnbindHandler(unbindHandler); _exitFeeRecipient = exitFeeRecipient; } /** * @dev Set the swap fee. * Note: Swap fee must be between 0.0001% and 10% */ function setSwapFee(uint256 swapFee) external override _control_ { require(swapFee >= MIN_FEE && swapFee <= MAX_FEE, "ERR_INVALID_FEE"); _swapFee = swapFee; emit LOG_SWAP_FEE_UPDATED(swapFee); } /** * @dev Set the controller address. */ function setController(address controller) external override _control_ { require(controller != address(0), "ERR_NULL_ADDRESS"); _controller = controller; emit LOG_CONTROLLER_UPDATED(controller); } /** * @dev Delegate a comp-like governance token to an address * specified by the controller. */ function delegateCompLikeToken(address token, address delegatee) external override _control_ { ICompLikeToken(token).delegate(delegatee); } /** * @dev Set the exit fee recipient address. */ function setExitFeeRecipient(address exitFeeRecipient) external override _control_ { require(exitFeeRecipient != address(0), "ERR_NULL_ADDRESS"); _exitFeeRecipient = exitFeeRecipient; emit LOG_EXIT_FEE_RECIPIENT_UPDATED(exitFeeRecipient); } /** * @dev Toggle public trading for the index pool. * This will enable or disable swaps and single-token joins and exits. */ function setPublicSwap(bool enabled) external override _control_ { _publicSwap = enabled; emit LOG_PUBLIC_SWAP_TOGGLED(enabled); } /* ========== Token Management Actions ========== */ /** * @dev Sets the desired weights for the pool tokens, which * will be adjusted over time as they are swapped. * * Note: This does not check for duplicate tokens or that the total * of the desired weights is equal to the target total weight (25). * Those assumptions should be met in the controller. Further, the * provided tokens should only include the tokens which are not set * for removal. */ function reweighTokens( address[] calldata tokens, uint96[] calldata desiredDenorms ) external override _lock_ _control_ { require(desiredDenorms.length == tokens.length, "ERR_ARR_LEN"); for (uint256 i = 0; i < tokens.length; i++) _setDesiredDenorm(tokens[i], desiredDenorms[i]); } /** * @dev Update the underlying assets held by the pool and their associated * weights. Tokens which are not currently bound will be gradually added * as they are swapped in to reach the provided minimum balances, which must * be an amount of tokens worth the minimum weight of the total pool value. * If a currently bound token is not received in this call, the token's * desired weight will be set to 0. */ function reindexTokens( address[] calldata tokens, uint96[] calldata desiredDenorms, uint256[] calldata minimumBalances ) external override _lock_ _control_ { require( desiredDenorms.length == tokens.length && minimumBalances.length == tokens.length, "ERR_ARR_LEN" ); // This size may not be the same as the input size, as it is possible // to temporarily exceed the index size while tokens are being phased in // or out. uint256 tLen = _tokens.length; bool[] memory receivedIndices = new bool[](tLen); // We need to read token records in two separate loops, so // write them to memory to avoid duplicate storage reads. Record[] memory records = new Record[](tokens.length); // Read all the records from storage and mark which of the existing tokens // were represented in the reindex call. for (uint256 i = 0; i < tokens.length; i++) { records[i] = _records[tokens[i]]; if (records[i].bound) receivedIndices[records[i].index] = true; } // If any bound tokens were not sent in this call, set their desired weights to 0. for (uint256 i = 0; i < tLen; i++) { if (!receivedIndices[i]) { _setDesiredDenorm(_tokens[i], 0); } } for (uint256 i = 0; i < tokens.length; i++) { address token = tokens[i]; // If an input weight is less than the minimum weight, use that instead. uint96 denorm = desiredDenorms[i]; if (denorm < MIN_WEIGHT) denorm = uint96(MIN_WEIGHT); if (!records[i].bound) { // If the token is not bound, bind it. _bind(token, minimumBalances[i], denorm); } else { _setDesiredDenorm(token, denorm); } } } /** * @dev Updates the minimum balance for an uninitialized token. * This becomes useful if a token's external price significantly * rises after being bound, since the pool can not send a token * out until it reaches the minimum balance. */ function setMinimumBalance( address token, uint256 minimumBalance ) external override _lock_ _control_ { Record storage record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); require(!record.ready, "ERR_READY"); require(now - record.lastDenormUpdate >= MIN_BAL_UPDATE_DELAY, "MIN_BAL_UPDATE_DELAY"); record.lastDenormUpdate = uint40(now); _minimumBalances[token] = minimumBalance; emit LOG_MINIMUM_BALANCE_UPDATED(token, minimumBalance); } /* ========== Liquidity Provider Actions ========== */ /** * @dev Mint new pool tokens by providing the proportional amount of each * underlying token's balance relative to the proportion of pool tokens minted. * * For any underlying tokens which are not initialized, the caller must provide * the proportional share of the minimum balance for the token rather than the * actual balance. * * @param poolAmountOut Amount of pool tokens to mint * @param maxAmountsIn Maximum amount of each token to pay in the same * order as the pool's _tokens list. */ function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external override _lock_ _public_ { uint256 poolTotal = totalSupply(); uint256 ratio = bdiv(poolAmountOut, poolTotal); require(ratio != 0, "ERR_MATH_APPROX"); require(maxAmountsIn.length == _tokens.length, "ERR_ARR_LEN"); for (uint256 i = 0; i < maxAmountsIn.length; i++) { address t = _tokens[i]; (Record memory record, uint256 realBalance) = _getInputToken(t); uint256 tokenAmountIn = bmul(ratio, record.balance); require(tokenAmountIn != 0, "ERR_MATH_APPROX"); require(tokenAmountIn <= maxAmountsIn[i], "ERR_LIMIT_IN"); _updateInputToken(t, record, badd(realBalance, tokenAmountIn)); emit LOG_JOIN(msg.sender, t, tokenAmountIn); _pullUnderlying(t, msg.sender, tokenAmountIn); } _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOut); } /** * @dev Pay `tokenAmountIn` of `tokenIn` to mint at least `minPoolAmountOut` * pool tokens. * * The pool implicitly swaps `(1- weightTokenIn) * tokenAmountIn` to the other * underlying tokens. Thus a swap fee is charged against the input tokens. * * @param tokenIn Token to send the pool * @param tokenAmountIn Exact amount of `tokenIn` to pay * @param minPoolAmountOut Minimum amount of pool tokens to mint * @return poolAmountOut - Amount of pool tokens minted */ function joinswapExternAmountIn( address tokenIn, uint256 tokenAmountIn, uint256 minPoolAmountOut ) external override _lock_ _public_ returns (uint256/* poolAmountOut */) { (Record memory inRecord, uint256 realInBalance) = _getInputToken(tokenIn); require(tokenAmountIn != 0, "ERR_ZERO_IN"); require( tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), "ERR_MAX_IN_RATIO" ); uint256 poolAmountOut = calcPoolOutGivenSingleIn( inRecord.balance, inRecord.denorm, _totalSupply, _totalWeight, tokenAmountIn, _swapFee ); require(poolAmountOut >= minPoolAmountOut, "ERR_LIMIT_OUT"); _updateInputToken(tokenIn, inRecord, badd(realInBalance, tokenAmountIn)); emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn); _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOut); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); return poolAmountOut; } /** * @dev Pay up to `maxAmountIn` of `tokenIn` to mint exactly `poolAmountOut`. * * The pool implicitly swaps `(1- weightTokenIn) * tokenAmountIn` to the other * underlying tokens. Thus a swap fee is charged against the input tokens. * * @param tokenIn Token to send the pool * @param poolAmountOut Exact amount of pool tokens to mint * @param maxAmountIn Maximum amount of `tokenIn` to pay * @return tokenAmountIn - Amount of `tokenIn` paid */ function joinswapPoolAmountOut( address tokenIn, uint256 poolAmountOut, uint256 maxAmountIn ) external override _lock_ _public_ returns (uint256/* tokenAmountIn */) { (Record memory inRecord, uint256 realInBalance) = _getInputToken(tokenIn); uint256 tokenAmountIn = calcSingleInGivenPoolOut( inRecord.balance, inRecord.denorm, _totalSupply, _totalWeight, poolAmountOut, _swapFee ); require(tokenAmountIn != 0, "ERR_MATH_APPROX"); require(tokenAmountIn <= maxAmountIn, "ERR_LIMIT_IN"); require( tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), "ERR_MAX_IN_RATIO" ); _updateInputToken(tokenIn, inRecord, badd(realInBalance, tokenAmountIn)); emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn); _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOut); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); return tokenAmountIn; } /** * @dev Burns `poolAmountIn` pool tokens in exchange for the amounts of each * underlying token's balance proportional to the ratio of tokens burned to * total pool supply. The amount of each token transferred to the caller must * be greater than or equal to the associated minimum output amount from the * `minAmountsOut` array. * * @param poolAmountIn Exact amount of pool tokens to burn * @param minAmountsOut Minimum amount of each token to receive, in the same * order as the pool's _tokens list. */ function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external override _lock_ { require(minAmountsOut.length == _tokens.length, "ERR_ARR_LEN"); uint256 poolTotal = totalSupply(); uint256 exitFee = bmul(poolAmountIn, EXIT_FEE); uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee); uint256 ratio = bdiv(pAiAfterExitFee, poolTotal); require(ratio != 0, "ERR_MATH_APPROX"); _pullPoolShare(msg.sender, poolAmountIn); _pushPoolShare(_exitFeeRecipient, exitFee); _burnPoolShare(pAiAfterExitFee); for (uint256 i = 0; i < minAmountsOut.length; i++) { address t = _tokens[i]; Record memory record = _records[t]; if (record.ready) { uint256 tokenAmountOut = bmul(ratio, record.balance); require(tokenAmountOut != 0, "ERR_MATH_APPROX"); require(tokenAmountOut >= minAmountsOut[i], "ERR_LIMIT_OUT"); _records[t].balance = bsub(record.balance, tokenAmountOut); emit LOG_EXIT(msg.sender, t, tokenAmountOut); _pushUnderlying(t, msg.sender, tokenAmountOut); } else { // If the token is not initialized, it can not exit the pool. require(minAmountsOut[i] == 0, "ERR_OUT_NOT_READY"); } } } /** * @dev Burns `poolAmountIn` pool tokens in exchange for at least `minAmountOut` * of `tokenOut`. Returns the number of tokens sent to the caller. * * The pool implicitly burns the tokens for all underlying tokens and swaps them * to the desired output token. A swap fee is charged against the output tokens. * * @param tokenOut Token to receive * @param poolAmountIn Exact amount of pool tokens to burn * @param minAmountOut Minimum amount of `tokenOut` to receive * @return tokenAmountOut - Amount of `tokenOut` received */ function exitswapPoolAmountIn( address tokenOut, uint256 poolAmountIn, uint256 minAmountOut ) external override _lock_ returns (uint256/* tokenAmountOut */) { Record memory outRecord = _getOutputToken(tokenOut); uint256 tokenAmountOut = calcSingleOutGivenPoolIn( outRecord.balance, outRecord.denorm, _totalSupply, _totalWeight, poolAmountIn, _swapFee ); require(tokenAmountOut >= minAmountOut, "ERR_LIMIT_OUT"); require( tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), "ERR_MAX_OUT_RATIO" ); _pushUnderlying(tokenOut, msg.sender, tokenAmountOut); _records[tokenOut].balance = bsub(outRecord.balance, tokenAmountOut); _decreaseDenorm(outRecord, tokenOut); uint256 exitFee = bmul(poolAmountIn, EXIT_FEE); emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut); _pullPoolShare(msg.sender, poolAmountIn); _burnPoolShare(bsub(poolAmountIn, exitFee)); _pushPoolShare(_exitFeeRecipient, exitFee); return tokenAmountOut; } /** * @dev Burn up to `maxPoolAmountIn` for exactly `tokenAmountOut` of `tokenOut`. * Returns the number of pool tokens burned. * * The pool implicitly burns the tokens for all underlying tokens and swaps them * to the desired output token. A swap fee is charged against the output tokens. * * @param tokenOut Token to receive * @param tokenAmountOut Exact amount of `tokenOut` to receive * @param maxPoolAmountIn Maximum amount of pool tokens to burn * @return poolAmountIn - Amount of pool tokens burned */ function exitswapExternAmountOut( address tokenOut, uint256 tokenAmountOut, uint256 maxPoolAmountIn ) external override _lock_ returns (uint256/* poolAmountIn */) { Record memory outRecord = _getOutputToken(tokenOut); require( tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), "ERR_MAX_OUT_RATIO" ); uint256 poolAmountIn = calcPoolInGivenSingleOut( outRecord.balance, outRecord.denorm, _totalSupply, _totalWeight, tokenAmountOut, _swapFee ); require(poolAmountIn != 0, "ERR_MATH_APPROX"); require(poolAmountIn <= maxPoolAmountIn, "ERR_LIMIT_IN"); _pushUnderlying(tokenOut, msg.sender, tokenAmountOut); _records[tokenOut].balance = bsub(outRecord.balance, tokenAmountOut); _decreaseDenorm(outRecord, tokenOut); uint256 exitFee = bmul(poolAmountIn, EXIT_FEE); emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut); _pullPoolShare(msg.sender, poolAmountIn); _burnPoolShare(bsub(poolAmountIn, exitFee)); _pushPoolShare(_exitFeeRecipient, exitFee); return poolAmountIn; } /* ========== Other ========== */ /** * @dev Absorb any tokens that have been sent to the pool. * If the token is not bound, it will be sent to the unbound * token handler. */ function gulp(address token) external override _lock_ { Record storage record = _records[token]; uint256 balance = IERC20(token).balanceOf(address(this)); if (record.bound) { if (!record.ready) { uint256 minimumBalance = _minimumBalances[token]; if (balance >= minimumBalance) { _minimumBalances[token] = 0; record.ready = true; emit LOG_TOKEN_READY(token); uint256 additionalBalance = bsub(balance, minimumBalance); uint256 balRatio = bdiv(additionalBalance, minimumBalance); uint96 newDenorm = uint96(badd(MIN_WEIGHT, bmul(MIN_WEIGHT, balRatio))); if (newDenorm > 2 * MIN_WEIGHT) newDenorm = uint96(2 * MIN_WEIGHT); record.denorm = newDenorm; record.lastDenormUpdate = uint40(now); _totalWeight = badd(_totalWeight, newDenorm); emit LOG_DENORM_UPDATED(token, record.denorm); } } _records[token].balance = balance; } else { _pushUnderlying(token, address(_unbindHandler), balance); _unbindHandler.handleUnbindToken(token, balance); } } /* ========== Token Swaps ========== */ /** * @dev Execute a token swap with a specified amount of input * tokens and a minimum amount of output tokens. * * Note: Will revert if `tokenOut` is uninitialized. * * @param tokenIn Token to swap in * @param tokenAmountIn Exact amount of `tokenIn` to swap in * @param tokenOut Token to swap out * @param minAmountOut Minimum amount of `tokenOut` to receive * @param maxPrice Maximum ratio of input to output tokens * @return (tokenAmountOut, spotPriceAfter) */ function swapExactAmountIn( address tokenIn, uint256 tokenAmountIn, address tokenOut, uint256 minAmountOut, uint256 maxPrice ) external override _lock_ _public_ returns (uint256/* tokenAmountOut */, uint256/* spotPriceAfter */) { (Record memory inRecord, uint256 realInBalance) = _getInputToken(tokenIn); Record memory outRecord = _getOutputToken(tokenOut); require( tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), "ERR_MAX_IN_RATIO" ); uint256 spotPriceBefore = calcSpotPrice( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee ); require(spotPriceBefore <= maxPrice, "ERR_BAD_LIMIT_PRICE"); uint256 tokenAmountOut = calcOutGivenIn( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, tokenAmountIn, _swapFee ); require(tokenAmountOut >= minAmountOut, "ERR_LIMIT_OUT"); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); _pushUnderlying(tokenOut, msg.sender, tokenAmountOut); // Update the in-memory record for the spotPriceAfter calculation, // then update the storage record with the local balance. outRecord.balance = bsub(outRecord.balance, tokenAmountOut); _records[tokenOut].balance = outRecord.balance; // If needed, update the output token's weight. _decreaseDenorm(outRecord, tokenOut); realInBalance = badd(realInBalance, tokenAmountIn); _updateInputToken(tokenIn, inRecord, realInBalance); if (inRecord.ready) { inRecord.balance = realInBalance; } uint256 spotPriceAfter = calcSpotPrice( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee ); require(spotPriceAfter >= spotPriceBefore, "ERR_MATH_APPROX_2"); require(spotPriceAfter <= maxPrice, "ERR_LIMIT_PRICE"); require( spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), "ERR_MATH_APPROX" ); emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut); return (tokenAmountOut, spotPriceAfter); } /** * @dev Trades at most `maxAmountIn` of `tokenIn` for exactly `tokenAmountOut` * of `tokenOut`. * * Returns the actual input amount and the new spot price after the swap, * which can not exceed `maxPrice`. * * @param tokenIn Token to swap in * @param maxAmountIn Maximum amount of `tokenIn` to pay * @param tokenOut Token to swap out * @param tokenAmountOut Exact amount of `tokenOut` to receive * @param maxPrice Maximum ratio of input to output tokens * @return (tokenAmountIn, spotPriceAfter) */ function swapExactAmountOut( address tokenIn, uint256 maxAmountIn, address tokenOut, uint256 tokenAmountOut, uint256 maxPrice ) external override _lock_ _public_ returns (uint256 /* tokenAmountIn */, uint256 /* spotPriceAfter */) { (Record memory inRecord, uint256 realInBalance) = _getInputToken(tokenIn); Record memory outRecord = _getOutputToken(tokenOut); require( tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), "ERR_MAX_OUT_RATIO" ); uint256 spotPriceBefore = calcSpotPrice( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee ); require(spotPriceBefore <= maxPrice, "ERR_BAD_LIMIT_PRICE"); uint256 tokenAmountIn = calcInGivenOut( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, tokenAmountOut, _swapFee ); require(tokenAmountIn <= maxAmountIn, "ERR_LIMIT_IN"); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); _pushUnderlying(tokenOut, msg.sender, tokenAmountOut); // Update the in-memory record for the spotPriceAfter calculation, // then update the storage record with the local balance. outRecord.balance = bsub(outRecord.balance, tokenAmountOut); _records[tokenOut].balance = outRecord.balance; // If needed, update the output token's weight. _decreaseDenorm(outRecord, tokenOut); // Update the balance and (if necessary) weight of the input token. realInBalance = badd(realInBalance, tokenAmountIn); _updateInputToken(tokenIn, inRecord, realInBalance); if (inRecord.ready) { inRecord.balance = realInBalance; } uint256 spotPriceAfter = calcSpotPrice( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee ); require(spotPriceAfter >= spotPriceBefore, "ERR_MATH_APPROX"); require(spotPriceAfter <= maxPrice, "ERR_LIMIT_PRICE"); require( spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), "ERR_MATH_APPROX" ); emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut); return (tokenAmountIn, spotPriceAfter); } /* ========== Config Queries ========== */ /** * @dev Check if swapping tokens and joining the pool is allowed. */ function isPublicSwap() external view override returns (bool) { return _publicSwap; } function getSwapFee() external view override _viewlock_ returns (uint256/* swapFee */) { return _swapFee; } function getExitFee() external view override _viewlock_ returns (uint256/* exitFee */) { return EXIT_FEE; } /** * @dev Returns the controller address. */ function getController() external view override returns (address) { return _controller; } /** * @dev Returns the exit fee recipient address. */ function getExitFeeRecipient() external view override returns (address) { return _exitFeeRecipient; } /* ========== Token Queries ========== */ /** * @dev Check if a token is bound to the pool. */ function isBound(address t) external view override returns (bool) { return _records[t].bound; } /** * @dev Get the number of tokens bound to the pool. */ function getNumTokens() external view override returns (uint256) { return _tokens.length; } /** * @dev Get all bound tokens. */ function getCurrentTokens() external view override _viewlock_ returns (address[] memory tokens) { tokens = _tokens; } /** * @dev Returns the list of tokens which have a desired weight above 0. * Tokens with a desired weight of 0 are set to be phased out of the pool. */ function getCurrentDesiredTokens() external view override _viewlock_ returns (address[] memory tokens) { address[] memory tempTokens = _tokens; tokens = new address[](tempTokens.length); uint256 usedIndex = 0; for (uint256 i = 0; i < tokens.length; i++) { address token = tempTokens[i]; if (_records[token].desiredDenorm > 0) { tokens[usedIndex++] = token; } } assembly { mstore(tokens, usedIndex) } } /** * @dev Returns the denormalized weight of a bound token. */ function getDenormalizedWeight(address token) external view override _viewlock_ returns (uint256/* denorm */) { require(_records[token].bound, "ERR_NOT_BOUND"); return _records[token].denorm; } /** * @dev Returns the record for a token bound to the pool. */ function getTokenRecord(address token) external view override _viewlock_ returns (Record memory record) { record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); } /** * @dev Get the total denormalized weight of the pool. */ function getTotalDenormalizedWeight() external view override _viewlock_ returns (uint256) { return _totalWeight; } /** * @dev Returns the stored balance of a bound token. */ function getBalance(address token) external view override _viewlock_ returns (uint256) { Record storage record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); return record.balance; } /** * @dev Get the minimum balance of an uninitialized token. * Note: Throws if the token is initialized. */ function getMinimumBalance(address token) external view override _viewlock_ returns (uint256) { Record memory record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); require(!record.ready, "ERR_READY"); return _minimumBalances[token]; } /** * @dev Returns the balance of a token which is used in price * calculations. If the token is initialized, this is the * stored balance; if not, this is the minimum balance. */ function getUsedBalance(address token) external view override _viewlock_ returns (uint256) { Record memory record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); if (!record.ready) { return _minimumBalances[token]; } return record.balance; } /* ========== Price Queries ========== */ /** * @dev Returns the spot price for `tokenOut` in terms of `tokenIn`. */ function getSpotPrice(address tokenIn, address tokenOut) external view override _viewlock_ returns (uint256) { (Record memory inRecord,) = _getInputToken(tokenIn); Record memory outRecord = _getOutputToken(tokenOut); return calcSpotPrice( inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee ); } /* ========== Pool Share Internal Functions ========== */ function _pullPoolShare(address from, uint256 amount) internal { _pull(from, amount); } function _pushPoolShare(address to, uint256 amount) internal { _push(to, amount); } function _mintPoolShare(uint256 amount) internal { _mint(amount); } function _burnPoolShare(uint256 amount) internal { _burn(amount); } /* ========== Underlying Token Internal Functions ========== */ // 'Underlying' token-manipulation functions make external calls but are NOT locked // You must `_lock_` or otherwise ensure reentry-safety function _pullUnderlying( address erc20, address from, uint256 amount ) internal { (bool success, bytes memory data) = erc20.call( abi.encodeWithSelector( IERC20.transferFrom.selector, from, address(this), amount ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "ERR_ERC20_FALSE" ); } function _pushUnderlying( address erc20, address to, uint256 amount ) internal { (bool success, bytes memory data) = erc20.call( abi.encodeWithSelector( IERC20.transfer.selector, to, amount ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "ERR_ERC20_FALSE" ); } /* ========== Token Management Internal Functions ========== */ /** * @dev Bind a token by address without actually depositing a balance. * The token will be unable to be swapped out until it reaches the minimum balance. * Note: Token must not already be bound. * Note: `minimumBalance` should represent an amount of the token which is worth * the portion of the current pool value represented by the minimum weight. * @param token Address of the token to bind * @param minimumBalance minimum balance to reach before the token can be swapped out * @param desiredDenorm Desired weight for the token. */ function _bind( address token, uint256 minimumBalance, uint96 desiredDenorm ) internal { require(!_records[token].bound, "ERR_IS_BOUND"); require(desiredDenorm >= MIN_WEIGHT, "ERR_MIN_WEIGHT"); require(desiredDenorm <= MAX_WEIGHT, "ERR_MAX_WEIGHT"); require(minimumBalance >= MIN_BALANCE, "ERR_MIN_BALANCE"); _records[token] = Record({ bound: true, ready: false, lastDenormUpdate: uint40(now), denorm: 0, desiredDenorm: desiredDenorm, index: uint8(_tokens.length), balance: 0 }); _tokens.push(token); _minimumBalances[token] = minimumBalance; emit LOG_TOKEN_ADDED(token, desiredDenorm, minimumBalance); } /** * @dev Remove a token from the pool. * Replaces the address in the tokens array with the last address, * then removes it from the array. * Note: This should only be called after the total weight has been adjusted. * Note: Must be called in a function with: * - _lock_ modifier to prevent reentrance * - requirement that the token is bound */ function _unbind(address token) internal { Record memory record = _records[token]; uint256 tokenBalance = record.balance; // Swap the token-to-unbind with the last token, // then delete the last token uint256 index = record.index; uint256 last = _tokens.length - 1; // Only swap the token with the last token if it is not // already at the end of the array. if (index != last) { _tokens[index] = _tokens[last]; _records[_tokens[index]].index = uint8(index); } _tokens.pop(); _records[token] = Record({ bound: false, ready: false, lastDenormUpdate: 0, denorm: 0, desiredDenorm: 0, index: 0, balance: 0 }); // transfer any remaining tokens out _pushUnderlying(token, address(_unbindHandler), tokenBalance); _unbindHandler.handleUnbindToken(token, tokenBalance); emit LOG_TOKEN_REMOVED(token); } function _setDesiredDenorm(address token, uint96 desiredDenorm) internal { Record storage record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); // If the desired weight is 0, this will trigger a gradual unbinding of the token. // Therefore the weight only needs to be above the minimum weight if it isn't 0. require( desiredDenorm >= MIN_WEIGHT || desiredDenorm == 0, "ERR_MIN_WEIGHT" ); require(desiredDenorm <= MAX_WEIGHT, "ERR_MAX_WEIGHT"); record.desiredDenorm = desiredDenorm; emit LOG_DESIRED_DENORM_SET(token, desiredDenorm); } function _increaseDenorm(Record memory record, address token) internal { // If the weight does not need to increase or the token is not // initialized, don't do anything. if ( record.denorm >= record.desiredDenorm || !record.ready || now - record.lastDenormUpdate < WEIGHT_UPDATE_DELAY ) return; uint96 oldWeight = record.denorm; uint96 denorm = record.desiredDenorm; uint256 maxDiff = bmul(oldWeight, WEIGHT_CHANGE_PCT); uint256 diff = bsub(denorm, oldWeight); if (diff > maxDiff) { denorm = uint96(badd(oldWeight, maxDiff)); diff = maxDiff; } // If new total weight exceeds the maximum, do not update uint256 newTotalWeight = badd(_totalWeight, diff); if (newTotalWeight > MAX_TOTAL_WEIGHT) return; _totalWeight = newTotalWeight; // Update the in-memory denorm value for spot-price computations. record.denorm = denorm; // Update the storage record _records[token].denorm = denorm; _records[token].lastDenormUpdate = uint40(now); emit LOG_DENORM_UPDATED(token, denorm); } function _decreaseDenorm(Record memory record, address token) internal { // If the weight does not need to decrease, don't do anything. if ( record.denorm <= record.desiredDenorm || !record.ready || now - record.lastDenormUpdate < WEIGHT_UPDATE_DELAY ) return; uint96 oldWeight = record.denorm; uint96 denorm = record.desiredDenorm; uint256 maxDiff = bmul(oldWeight, WEIGHT_CHANGE_PCT); uint256 diff = bsub(oldWeight, denorm); if (diff > maxDiff) { denorm = uint96(bsub(oldWeight, maxDiff)); diff = maxDiff; } if (denorm <= MIN_WEIGHT) { denorm = 0; _totalWeight = bsub(_totalWeight, denorm); // Because this is removing the token from the pool, the // in-memory denorm value is irrelevant, as it is only used // to calculate the new spot price, but the spot price calc // will throw if it is passed 0 for the denorm. _unbind(token); } else { _totalWeight = bsub(_totalWeight, diff); // Update the in-memory denorm value for spot-price computations. record.denorm = denorm; // Update the stored denorm value _records[token].denorm = denorm; _records[token].lastDenormUpdate = uint40(now); emit LOG_DENORM_UPDATED(token, denorm); } } /** * @dev Handles weight changes and initialization of an * input token. * * If the token is not initialized and the new balance is * still below the minimum, this will not do anything. * * If the token is not initialized but the new balance will * bring the token above the minimum balance, this will * mark the token as initialized, remove the minimum * balance and set the weight to the minimum weight plus * 1%. * * * @param token Address of the input token * @param record Token record with minimums applied to the balance * and weight if the token was uninitialized. */ function _updateInputToken( address token, Record memory record, uint256 realBalance ) internal { if (!record.ready) { // Check if the minimum balance has been reached if (realBalance >= record.balance) { // Remove the minimum balance record _minimumBalances[token] = 0; // Mark the token as initialized _records[token].ready = true; record.ready = true; emit LOG_TOKEN_READY(token); // Set the initial denorm value to the minimum weight times one plus // the ratio of the increase in balance over the minimum to the minimum // balance. // weight = (1 + ((bal - min_bal) / min_bal)) * min_weight uint256 additionalBalance = bsub(realBalance, record.balance); uint256 balRatio = bdiv(additionalBalance, record.balance); record.denorm = uint96(badd(MIN_WEIGHT, bmul(MIN_WEIGHT, balRatio))); if (record.denorm > 2 * MIN_WEIGHT) record.denorm = uint96(2 * MIN_WEIGHT); _records[token].denorm = record.denorm; _records[token].lastDenormUpdate = uint40(now); _totalWeight = badd(_totalWeight, record.denorm); emit LOG_DENORM_UPDATED(token, record.denorm); } else { uint256 realToMinRatio = bdiv( bsub(record.balance, realBalance), record.balance ); uint256 weightPremium = bmul(MIN_WEIGHT / 10, realToMinRatio); record.denorm = uint96(badd(MIN_WEIGHT, weightPremium)); } // If the token is still not ready, do not adjust the weight. } else { // If the token is already initialized, update the weight (if any adjustment // is needed). _increaseDenorm(record, token); } // Regardless of whether the token is initialized, store the actual new balance. _records[token].balance = realBalance; } /* ========== Token Query Internal Functions ========== */ /** * @dev Get the record for a token which is being swapped in. * The token must be bound to the pool. If the token is not * initialized (meaning it does not have the minimum balance) * this function will return the actual balance of the token * which the pool holds, but set the record's balance and weight * to the token's minimum balance and the pool's minimum weight. * This allows the token swap to be priced correctly even if the * pool does not own any of the tokens. */ function _getInputToken(address token) internal view returns (Record memory record, uint256 realBalance) { record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); realBalance = record.balance; // If the input token is not initialized, we use the minimum // initial weight and minimum initial balance instead of the // real values for price and output calculations. if (!record.ready) { record.balance = _minimumBalances[token]; uint256 realToMinRatio = bdiv( bsub(record.balance, realBalance), record.balance ); uint256 weightPremium = bmul(MIN_WEIGHT / 10, realToMinRatio); record.denorm = uint96(badd(MIN_WEIGHT, weightPremium)); } } function _getOutputToken(address token) internal view returns (Record memory record) { record = _records[token]; require(record.bound, "ERR_NOT_BOUND"); // Tokens which have not reached their minimum balance can not be // swapped out. require(record.ready, "ERR_OUT_NOT_READY"); } } interface TokenUnbindHandler { /** * @dev Receive `amount` of `token` from the pool. */ function handleUnbindToken(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /************************************************************************************************ Originally from https://github.com/balancer-labs/balancer-core/blob/master/contracts/BConst.sol This source code has been modified from the original, which was copied from the github repository at commit hash f4ed5d65362a8d6cec21662fb6eae233b0babc1f. Subject to the GPL-3.0 license *************************************************************************************************/ contract BConst { uint256 public constant VERSION_NUMBER = 1; /* --- Weight Updates --- */ // Minimum time passed between each weight update for a token. uint256 internal constant WEIGHT_UPDATE_DELAY = 30 minutes; // Minimum time between each change to a token's minimum balance. uint256 internal constant MIN_BAL_UPDATE_DELAY = 6 hours; // Maximum percent by which a weight can adjust at a time // relative to the current weight. // The number of iterations needed to move from weight A to weight B is the floor of: // (A > B): (ln(A) - ln(B)) / ln(1.01) // (B > A): (ln(A) - ln(B)) / ln(0.99) uint256 internal constant WEIGHT_CHANGE_PCT = BONE/100; uint256 internal constant BONE = 10**18; uint256 internal constant MIN_BOUND_TOKENS = 2; uint256 internal constant MAX_BOUND_TOKENS = 10; // Minimum swap fee. uint256 internal constant MIN_FEE = BONE / 10**6; // Maximum swap or exit fee. uint256 internal constant MAX_FEE = BONE / 10; // Actual exit fee. uint256 internal constant EXIT_FEE = 5e15; // Default total of all desired weights. Can differ by up to BONE. uint256 internal constant DEFAULT_TOTAL_WEIGHT = BONE * 25; // Minimum weight for any token (1/100). uint256 internal constant MIN_WEIGHT = BONE / 4; uint256 internal constant MAX_WEIGHT = BONE * 25; // Maximum total weight. uint256 internal constant MAX_TOTAL_WEIGHT = 27e18; // Minimum balance for a token (only applied at initialization) uint256 internal constant MIN_BALANCE = BONE / 10**12; // Initial pool tokens uint256 internal constant INIT_POOL_SUPPLY = BONE * 100; uint256 internal constant MIN_BPOW_BASE = 1 wei; uint256 internal constant MAX_BPOW_BASE = (2 * BONE) - 1 wei; uint256 internal constant BPOW_PRECISION = BONE / 10**10; // Maximum ratio of input tokens to balance for swaps. uint256 internal constant MAX_IN_RATIO = BONE / 2; // Maximum ratio of output tokens to balance for swaps. uint256 internal constant MAX_OUT_RATIO = (BONE / 3) + 1 wei; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; import "./BNum.sol"; /************************************************************************************************ Originally from https://github.com/balancer-labs/balancer-core/blob/master/contracts/BMath.sol This source code has been modified from the original, which was copied from the github repository at commit hash f4ed5d65362a8d6cec21662fb6eae233b0babc1f. Subject to the GPL-3.0 license *************************************************************************************************/ contract BMath is BConst, BNum { /********************************************************************************************** // calcSpotPrice // // sP = spotPrice // // bI = tokenBalanceIn ( bI / wI ) 1 // // bO = tokenBalanceOut sP = ----------- * ---------- // // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) // // wO = tokenWeightOut // // sF = swapFee // **********************************************************************************************/ function calcSpotPrice( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 swapFee ) internal pure returns (uint256 spotPrice) { uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn); uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut); uint256 ratio = bdiv(numer, denom); uint256 scale = bdiv(BONE, bsub(BONE, swapFee)); return (spotPrice = bmul(ratio, scale)); } /********************************************************************************************** // calcOutGivenIn // // aO = tokenAmountOut // // bO = tokenBalanceOut // // bI = tokenBalanceIn / / bI \ (wI / wO) \ // // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | // // wI = tokenWeightIn \ \ ( bI + ( aI * ( 1 - sF )) / / // // wO = tokenWeightOut // // sF = swapFee // **********************************************************************************************/ function calcOutGivenIn( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 tokenAmountIn, uint256 swapFee ) internal pure returns (uint256 tokenAmountOut) { uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut); uint256 adjustedIn = bsub(BONE, swapFee); adjustedIn = bmul(tokenAmountIn, adjustedIn); uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn)); uint256 foo = bpow(y, weightRatio); uint256 bar = bsub(BONE, foo); tokenAmountOut = bmul(tokenBalanceOut, bar); return tokenAmountOut; } /********************************************************************************************** // calcInGivenOut // // aI = tokenAmountIn // // bO = tokenBalanceOut / / bO \ (wO / wI) \ // // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | // // aO = tokenAmountOut aI = \ \ ( bO - aO ) / / // // wI = tokenWeightIn -------------------------------------------- // // wO = tokenWeightOut ( 1 - sF ) // // sF = swapFee // **********************************************************************************************/ function calcInGivenOut( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 tokenAmountOut, uint256 swapFee ) internal pure returns (uint256 tokenAmountIn) { uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn); uint256 diff = bsub(tokenBalanceOut, tokenAmountOut); uint256 y = bdiv(tokenBalanceOut, diff); uint256 foo = bpow(y, weightRatio); foo = bsub(foo, BONE); tokenAmountIn = bsub(BONE, swapFee); tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn); return tokenAmountIn; } /********************************************************************************************** // calcPoolOutGivenSingleIn // // pAo = poolAmountOut / \ // // tAi = tokenAmountIn /// / // wI \ \\ \ wI \ // // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \ -- \ // // tW = totalWeight pAo=|| \ \ \\ tW / // | ^ tW | * pS - pS // // tBi = tokenBalanceIn \\ ------------------------------------- / / // // pS = poolSupply \\ tBi / / // // sF = swapFee \ / // **********************************************************************************************/ function calcPoolOutGivenSingleIn( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 poolSupply, uint256 totalWeight, uint256 tokenAmountIn, uint256 swapFee ) internal pure returns (uint256 poolAmountOut) { // Charge the trading fee for the proportion of tokenAi /// which is implicitly traded to the other pool tokens. // That proportion is (1- weightTokenIn) // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee); uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight); uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee); uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz)); uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee); uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn); // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply; uint256 poolRatio = bpow(tokenInRatio, normalizedWeight); uint256 newPoolSupply = bmul(poolRatio, poolSupply); poolAmountOut = bsub(newPoolSupply, poolSupply); return poolAmountOut; } /********************************************************************************************** // calcSingleInGivenPoolOut // // tAi = tokenAmountIn //(pS + pAo)\ / 1 \\ // // pS = poolSupply || --------- | ^ | --------- || * bI - bI // // pAo = poolAmountOut \\ pS / \(wI / tW)// // // bI = balanceIn tAi = -------------------------------------------- // // wI = weightIn / wI \ // // tW = totalWeight | 1 - ---- | * sF // // sF = swapFee \ tW / // **********************************************************************************************/ function calcSingleInGivenPoolOut( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 poolSupply, uint256 totalWeight, uint256 poolAmountOut, uint256 swapFee ) internal pure returns (uint256 tokenAmountIn) { uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight); uint256 newPoolSupply = badd(poolSupply, poolAmountOut); uint256 poolRatio = bdiv(newPoolSupply, poolSupply); //uint newBalTi = poolRatio^(1/weightTi) * balTi; uint256 boo = bdiv(BONE, normalizedWeight); uint256 tokenInRatio = bpow(poolRatio, boo); uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn); uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn); // Do reverse order of fees charged in joinswap_ExternAmountIn, this way // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ``` //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ; uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee); tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar)); return tokenAmountIn; } /********************************************************************************************** // calcSingleOutGivenPoolIn // // tAo = tokenAmountOut / / \\ // // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \ / 1 \ \\ // // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || // // ps = poolSupply \ \\ pS / \(wO / tW)/ // // // wI = tokenWeightIn tAo = \ \ // // // tW = totalWeight / / wO \ \ // // sF = swapFee * | 1 - | 1 - ---- | * sF | // // eF = exitFee \ \ tW / / // **********************************************************************************************/ function calcSingleOutGivenPoolIn( uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 poolSupply, uint256 totalWeight, uint256 poolAmountIn, uint256 swapFee ) internal pure returns (uint256 tokenAmountOut) { uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight); // charge exit fee on the pool token side // pAiAfterExitFee = pAi*(1-exitFee) uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE)); uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee); uint256 poolRatio = bdiv(newPoolSupply, poolSupply); // newBalTo = poolRatio^(1/weightTo) * balTo; uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight)); uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut); uint256 tokenAmountOutBeforeSwapFee = bsub( tokenBalanceOut, newTokenBalanceOut ); // charge swap fee on the output token side //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee) uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee); tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz)); return tokenAmountOut; } /********************************************************************************************** // calcPoolInGivenSingleOut // // pAi = poolAmountIn // / tAo \\ / wO \ \ // // bO = tokenBalanceOut // | bO - -------------------------- |\ | ---- | \ // // tAo = tokenAmountOut pS - || \ 1 - ((1 - (tO / tW)) * sF)/ | ^ \ tW / * pS | // // ps = poolSupply \\ -----------------------------------/ / // // wO = tokenWeightOut pAi = \\ bO / / // // tW = totalWeight ------------------------------------------------------------- // // sF = swapFee ( 1 - eF ) // // eF = exitFee // **********************************************************************************************/ function calcPoolInGivenSingleOut( uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 poolSupply, uint256 totalWeight, uint256 tokenAmountOut, uint256 swapFee ) internal pure returns (uint256 poolAmountIn) { // charge swap fee on the output token side uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight); //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ; uint256 zoo = bsub(BONE, normalizedWeight); uint256 zar = bmul(zoo, swapFee); uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar)); uint256 newTokenBalanceOut = bsub( tokenBalanceOut, tokenAmountOutBeforeSwapFee ); uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut); //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply; uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight); uint256 newPoolSupply = bmul(poolRatio, poolSupply); uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply); // charge exit fee on the pool token side // pAi = pAiAfterExitFee/(1-exitFee) poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE)); return poolAmountIn; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; import "./BConst.sol"; /************************************************************************************************ Originally from https://github.com/balancer-labs/balancer-core/blob/master/contracts/BNum.sol This source code has been modified from the original, which was copied from the github repository at commit hash f4ed5d65362a8d6cec21662fb6eae233b0babc1f. Subject to the GPL-3.0 license *************************************************************************************************/ contract BNum is BConst { function btoi(uint256 a) internal pure returns (uint256) { return a / BONE; } function bfloor(uint256 a) internal pure returns (uint256) { return btoi(a) * BONE; } function badd(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "ERR_ADD_OVERFLOW"); return c; } function bsub(uint256 a, uint256 b) internal pure returns (uint256) { (uint256 c, bool flag) = bsubSign(a, b); require(!flag, "ERR_SUB_UNDERFLOW"); return c; } function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) { if (a >= b) { return (a - b, false); } else { return (b - a, true); } } function bmul(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c0 = a * b; require(a == 0 || c0 / a == b, "ERR_MUL_OVERFLOW"); uint256 c1 = c0 + (BONE / 2); require(c1 >= c0, "ERR_MUL_OVERFLOW"); uint256 c2 = c1 / BONE; return c2; } function bdiv(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "ERR_DIV_ZERO"); uint256 c0 = a * BONE; require(a == 0 || c0 / a == BONE, "ERR_DIV_INTERNAL"); // bmul overflow uint256 c1 = c0 + (b / 2); require(c1 >= c0, "ERR_DIV_INTERNAL"); // badd require uint256 c2 = c1 / b; return c2; } // DSMath.wpow function bpowi(uint256 a, uint256 n) internal pure returns (uint256) { uint256 z = n % 2 != 0 ? a : BONE; for (n /= 2; n != 0; n /= 2) { a = bmul(a, a); if (n % 2 != 0) { z = bmul(z, a); } } return z; } // Compute b^(e.w) by splitting it into (b^e)*(b^0.w). // Use `bpowi` for `b^e` and `bpowK` for k iterations // of approximation of b^0.w function bpow(uint256 base, uint256 exp) internal pure returns (uint256) { require(base >= MIN_BPOW_BASE, "ERR_BPOW_BASE_TOO_LOW"); require(base <= MAX_BPOW_BASE, "ERR_BPOW_BASE_TOO_HIGH"); uint256 whole = bfloor(exp); uint256 remain = bsub(exp, whole); uint256 wholePow = bpowi(base, btoi(whole)); if (remain == 0) { return wholePow; } uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION); return bmul(wholePow, partialResult); } function bpowApprox( uint256 base, uint256 exp, uint256 precision ) internal pure returns (uint256) { // term 0: uint256 a = exp; (uint256 x, bool xneg) = bsubSign(base, BONE); uint256 term = BONE; uint256 sum = term; bool negative = false; // term(k) = numer / denom // = (product(a - i - 1, i=1-->k) * x^k) / (k!) // each iteration, multiply previous term by (a-(k-1)) * x / k // continue until term is less than precision for (uint256 i = 1; term >= precision; i++) { uint256 bigK = i * BONE; (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE)); term = bmul(term, bmul(c, x)); term = bdiv(term, bigK); if (term == 0) break; if (xneg) negative = !negative; if (cneg) negative = !negative; if (negative) { sum = bsub(sum, term); } else { sum = badd(sum, term); } } return sum; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; import "./BNum.sol"; /************************************************************************************************ Originally from https://github.com/balancer-labs/balancer-core/blob/master/contracts/BToken.sol This source code has been modified from the original, which was copied from the github repository at commit hash f4ed5d65362a8d6cec21662fb6eae233b0babc1f. Subject to the GPL-3.0 license *************************************************************************************************/ // Highly opinionated token implementation interface IERC20 { event Approval(address indexed src, address indexed dst, uint256 amt); event Transfer(address indexed src, address indexed dst, uint256 amt); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address whom) external view returns (uint256); function allowance(address src, address dst) external view returns (uint256); function approve(address dst, uint256 amt) external returns (bool); function transfer(address dst, uint256 amt) external returns (bool); function transferFrom( address src, address dst, uint256 amt ) external returns (bool); } contract BTokenBase is BNum { mapping(address => uint256) internal _balance; mapping(address => mapping(address => uint256)) internal _allowance; uint256 internal _totalSupply; event Approval(address indexed src, address indexed dst, uint256 amt); event Transfer(address indexed src, address indexed dst, uint256 amt); function _mint(uint256 amt) internal { _balance[address(this)] = badd(_balance[address(this)], amt); _totalSupply = badd(_totalSupply, amt); emit Transfer(address(0), address(this), amt); } function _burn(uint256 amt) internal { require(_balance[address(this)] >= amt, "ERR_INSUFFICIENT_BAL"); _balance[address(this)] = bsub(_balance[address(this)], amt); _totalSupply = bsub(_totalSupply, amt); emit Transfer(address(this), address(0), amt); } function _move( address src, address dst, uint256 amt ) internal { require(_balance[src] >= amt, "ERR_INSUFFICIENT_BAL"); _balance[src] = bsub(_balance[src], amt); _balance[dst] = badd(_balance[dst], amt); emit Transfer(src, dst, amt); } function _push(address to, uint256 amt) internal { _move(address(this), to, amt); } function _pull(address from, uint256 amt) internal { _move(from, address(this), amt); } } contract BToken is BTokenBase, IERC20 { uint8 private constant DECIMALS = 18; string private _name; string private _symbol; function _initializeToken(string memory name, string memory symbol) internal { require( bytes(_name).length == 0 && bytes(name).length != 0 && bytes(symbol).length != 0, "ERR_BTOKEN_INITIALIZED" ); _name = name; _symbol = symbol; } function name() external override view returns (string memory) { return _name; } function symbol() external override view returns (string memory) { return _symbol; } function decimals() external override view returns (uint8) { return DECIMALS; } function allowance(address src, address dst) external override view returns (uint256) { return _allowance[src][dst]; } function balanceOf(address whom) external override view returns (uint256) { return _balance[whom]; } function totalSupply() public override view returns (uint256) { return _totalSupply; } function approve(address dst, uint256 amt) external override returns (bool) { _allowance[msg.sender][dst] = amt; emit Approval(msg.sender, dst, amt); return true; } function increaseApproval(address dst, uint256 amt) external returns (bool) { _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt); emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function decreaseApproval(address dst, uint256 amt) external returns (bool) { uint256 oldValue = _allowance[msg.sender][dst]; if (amt > oldValue) { _allowance[msg.sender][dst] = 0; } else { _allowance[msg.sender][dst] = bsub(oldValue, amt); } emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function transfer(address dst, uint256 amt) external override returns (bool) { _move(msg.sender, dst, amt); return true; } function transferFrom( address src, address dst, uint256 amt ) external override returns (bool) { require( msg.sender == src || amt <= _allowance[src][msg.sender], "ERR_BTOKEN_BAD_CALLER" ); _move(src, dst, amt); if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) { _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt); emit Approval(msg.sender, dst, _allowance[src][msg.sender]); } return true; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; interface IIndexPool { /** * @dev Token record data structure * @param bound is token bound to pool * @param ready has token been initialized * @param lastDenormUpdate timestamp of last denorm change * @param denorm denormalized weight * @param desiredDenorm desired denormalized weight (used for incremental changes) * @param index index of address in tokens array * @param balance token balance */ struct Record { bool bound; bool ready; uint40 lastDenormUpdate; uint96 denorm; uint96 desiredDenorm; uint8 index; uint256 balance; } /* ========== EVENTS ========== */ /** @dev Emitted when tokens are swapped. */ event LOG_SWAP( address indexed caller, address indexed tokenIn, address indexed tokenOut, uint256 tokenAmountIn, uint256 tokenAmountOut ); /** @dev Emitted when underlying tokens are deposited for pool tokens. */ event LOG_JOIN( address indexed caller, address indexed tokenIn, uint256 tokenAmountIn ); /** @dev Emitted when pool tokens are burned for underlying. */ event LOG_EXIT( address indexed caller, address indexed tokenOut, uint256 tokenAmountOut ); /** @dev Emitted when a token's weight updates. */ event LOG_DENORM_UPDATED(address indexed token, uint256 newDenorm); /** @dev Emitted when a token's desired weight is set. */ event LOG_DESIRED_DENORM_SET(address indexed token, uint256 desiredDenorm); /** @dev Emitted when a token is unbound from the pool. */ event LOG_TOKEN_REMOVED(address token); /** @dev Emitted when a token is unbound from the pool. */ event LOG_TOKEN_ADDED( address indexed token, uint256 desiredDenorm, uint256 minimumBalance ); /** @dev Emitted when a token's minimum balance is updated. */ event LOG_MINIMUM_BALANCE_UPDATED(address token, uint256 minimumBalance); /** @dev Emitted when a token reaches its minimum balance. */ event LOG_TOKEN_READY(address indexed token); /** @dev Emitted when public trades are enabled or disabled. */ event LOG_PUBLIC_SWAP_TOGGLED(bool isPublic); /** @dev Emitted when the swap fee is updated. */ event LOG_SWAP_FEE_UPDATED(uint256 swapFee); /** @dev Emitted when exit fee recipient is updated. */ event LOG_EXIT_FEE_RECIPIENT_UPDATED(address exitFeeRecipient); /** @dev Emitted when controller is updated. */ event LOG_CONTROLLER_UPDATED(address exitFeeRecipient); function configure( address controller, string calldata name, string calldata symbol ) external; function initialize( address[] calldata tokens, uint256[] calldata balances, uint96[] calldata denorms, address tokenProvider, address unbindHandler, address exitFeeRecipient ) external; function setSwapFee(uint256 swapFee) external; function setController(address controller) external; function delegateCompLikeToken(address token, address delegatee) external; function setExitFeeRecipient(address) external; function setPublicSwap(bool enabled) external; function reweighTokens( address[] calldata tokens, uint96[] calldata desiredDenorms ) external; function reindexTokens( address[] calldata tokens, uint96[] calldata desiredDenorms, uint256[] calldata minimumBalances ) external; function setMinimumBalance(address token, uint256 minimumBalance) external; function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external; function joinswapExternAmountIn( address tokenIn, uint256 tokenAmountIn, uint256 minPoolAmountOut ) external returns (uint256/* poolAmountOut */); function joinswapPoolAmountOut( address tokenIn, uint256 poolAmountOut, uint256 maxAmountIn ) external returns (uint256/* tokenAmountIn */); function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external; function exitswapPoolAmountIn( address tokenOut, uint256 poolAmountIn, uint256 minAmountOut ) external returns (uint256/* tokenAmountOut */); function exitswapExternAmountOut( address tokenOut, uint256 tokenAmountOut, uint256 maxPoolAmountIn ) external returns (uint256/* poolAmountIn */); function gulp(address token) external; function swapExactAmountIn( address tokenIn, uint256 tokenAmountIn, address tokenOut, uint256 minAmountOut, uint256 maxPrice ) external returns (uint256/* tokenAmountOut */, uint256/* spotPriceAfter */); function swapExactAmountOut( address tokenIn, uint256 maxAmountIn, address tokenOut, uint256 tokenAmountOut, uint256 maxPrice ) external returns (uint256 /* tokenAmountIn */, uint256 /* spotPriceAfter */); function isPublicSwap() external view returns (bool); function getSwapFee() external view returns (uint256/* swapFee */); function getExitFee() external view returns (uint256/* exitFee */); function getController() external view returns (address); function getExitFeeRecipient() external view returns (address); function isBound(address t) external view returns (bool); function getNumTokens() external view returns (uint256); function getCurrentTokens() external view returns (address[] memory tokens); function getCurrentDesiredTokens() external view returns (address[] memory tokens); function getDenormalizedWeight(address token) external view returns (uint256/* denorm */); function getTokenRecord(address token) external view returns (Record memory record); function getTotalDenormalizedWeight() external view returns (uint256); function getBalance(address token) external view returns (uint256); function getMinimumBalance(address token) external view returns (uint256); function getUsedBalance(address token) external view returns (uint256); function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface ICompLikeToken { function delegate(address delegatee) external; }
{ "metadata": { "useLiteralContent": false }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"amt","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"LOG_CONTROLLER_UPDATED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"newDenorm","type":"uint256"}],"name":"LOG_DENORM_UPDATED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"desiredDenorm","type":"uint256"}],"name":"LOG_DESIRED_DENORM_SET","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_EXIT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"LOG_EXIT_FEE_RECIPIENT_UPDATED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"name":"LOG_JOIN","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"minimumBalance","type":"uint256"}],"name":"LOG_MINIMUM_BALANCE_UPDATED","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPublic","type":"bool"}],"name":"LOG_PUBLIC_SWAP_TOGGLED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_SWAP","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"LOG_SWAP_FEE_UPDATED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"desiredDenorm","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minimumBalance","type":"uint256"}],"name":"LOG_TOKEN_ADDED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"LOG_TOKEN_READY","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"LOG_TOKEN_REMOVED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"amt","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"VERSION_NUMBER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"whom","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegateCompLikeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPoolAmountIn","type":"uint256"}],"name":"exitswapExternAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"exitswapPoolAmountIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentDesiredTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getMinimumBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getSpotPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSwapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenRecord","outputs":[{"components":[{"internalType":"bool","name":"bound","type":"bool"},{"internalType":"bool","name":"ready","type":"bool"},{"internalType":"uint40","name":"lastDenormUpdate","type":"uint40"},{"internalType":"uint96","name":"denorm","type":"uint96"},{"internalType":"uint96","name":"desiredDenorm","type":"uint96"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint256","name":"balance","type":"uint256"}],"internalType":"struct IIndexPool.Record","name":"record","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getUsedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"gulp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint96[]","name":"denorms","type":"uint96[]"},{"internalType":"address","name":"tokenProvider","type":"address"},{"internalType":"address","name":"unbindHandler","type":"address"},{"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"}],"name":"isBound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"}],"name":"joinPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"minPoolAmountOut","type":"uint256"}],"name":"joinswapExternAmountIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"}],"name":"joinswapPoolAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint96[]","name":"desiredDenorms","type":"uint96[]"},{"internalType":"uint256[]","name":"minimumBalances","type":"uint256[]"}],"name":"reindexTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint96[]","name":"desiredDenorms","type":"uint96[]"}],"name":"reweighTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"setExitFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"minimumBalance","type":"uint256"}],"name":"setMinimumBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setPublicSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615c7580620000216000396000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c80637c5e9ea411610167578063b02f0b73116100ce578063dd62ed3e11610087578063dd62ed3e14610595578063ecb0116a146105a8578063f8b2cb4f146105b0578063f8b5db09146105c3578063f9f97c98146105d6578063fde924f7146105e957610295565b8063b02f0b7314610544578063c3f4681014610557578063cc77828d1461056a578063cd2ed8fb14610572578063d4cadf681461057a578063d73dd6231461058257610295565b806392eefe9b1161012057806392eefe9b146104e8578063936c3477146104fb578063948d8ce61461050357806395d89b4114610516578063a49c44d71461051e578063a9059cbb1461053157610295565b80637c5e9ea41461047e5780638025e3031461049f5780638201aa3f146104a7578063865bcccb146104ba5780638c28cbe8146104c257806391bfa2bf146104d557610295565b8063313ce5671161020b5780635d5e8ce7116101c45780635d5e8ce7146103ff5780635db342771461041257806364c7d6611461042557806366188463146104455780636d06dfa01461045857806370a082311461046b57610295565b8063313ce5671461038b57806334e19907146103a057806346ab38f1146103b357806349b59552146103c65780634aa4e0b5146103d95780634f69c0d4146103ec57610295565b806318160ddd1161025d57806318160ddd1461032057806319f0f8491461032857806323b872dd1461033d5780632b110c74146103505780632f37b624146103635780633018205f1461037657610295565b806302c967481461029a578063039209af146102c357806306fdde03146102d8578063095ea7b3146102ed57806315e84af91461030d575b600080fd5b6102ad6102a83660046150c7565b6105f1565b6040516102ba9190615b5a565b60405180910390f35b6102cb6107cd565b6040516102ba919061540d565b6102e0610934565b6040516102ba9190615465565b6103006102fb36600461504e565b6109ca565b6040516102ba919061545a565b6102ad61031b366004614f5a565b610a23565b6102ad610aaa565b61033b610336366004614fce565b610ab0565b005b61030061034b366004614f8e565b610bab565b61033b61035e3660046150fa565b610cdc565b610300610371366004614f3f565b61114b565b61037e61116d565b6040516102ba91906153bc565b610393611181565b6040516102ba9190615b71565b61033b6103ae3660046152ff565b611186565b6102ad6103c13660046150c7565b61122e565b61033b6103d43660046152c7565b6113ac565b6102ad6103e7366004614f3f565b611422565b61033b6103fa36600461532f565b61152f565b61033b61040d3660046151c8565b611728565b6102ad6104203660046150c7565b611804565b610438610433366004614f3f565b6119ac565b6040516102ba9190615aef565b61030061045336600461504e565b611a83565b6102ad6104663660046150c7565b611b4c565b6102ad610479366004614f3f565b611cd6565b61049161048c366004615078565b611cf1565b6040516102ba929190615b63565b6102ad611fe8565b6104916104b5366004615078565b611fed565b61037e6122c0565b61033b6104d0366004614f3f565b6122cf565b6102ad6104e3366004614f3f565b6125b8565b61033b6104f6366004614f3f565b6126d1565b6102ad612776565b6102ad610511366004614f3f565b6127a3565b6102e061282d565b61033b61052c36600461504e565b61288e565b61030061053f36600461504e565b612a00565b61033b61055236600461532f565b612a16565b61033b610565366004615231565b612ce1565b6102cb61307a565b6102ad6130ff565b6102ad613105565b61030061059036600461504e565b613132565b6102ad6105a3366004614f5a565b6131a6565b6102ad6131d1565b6102ad6105be366004614f3f565b613203565b61033b6105d1366004614f5a565b61326c565b61033b6105e4366004614f3f565b6132fd565b61030061339d565b60055460009060ff16156106205760405162461bcd60e51b81526004016106179061573c565b60405180910390fd5b6005805460ff19166001179055610635614dd7565b61063e856133ad565b90506106638160c001516003670de0b6b3a76400008161065a57fe5b04600101613482565b8411156106825760405162461bcd60e51b815260040161061790615761565b60006106a98260c0015183606001516001600160601b0316600254600a54896007546134fb565b9050806106c85760405162461bcd60e51b815260040161061790615567565b838111156106e85760405162461bcd60e51b8152600401610617906156e6565b6106f38633876135c5565b6107018260c00151866136b4565b6001600160a01b03871660009081526009602052604090206001015561072782876136ed565b600061073a826611c37937e08000613482565b9050866001600160a01b0316336001600160a01b03167fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8860405161077f9190615b5a565b60405180910390a3610791338361387f565b6107a361079e83836136b4565b613889565b600c546107b9906001600160a01b031682613895565b506005805460ff1916905595945050505050565b60055460609060ff16156107f35760405162461bcd60e51b81526004016106179061573c565b6060600880548060200260200160405190810160405280929190818152602001828054801561084b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161082d575b50505050509050805167ffffffffffffffff8111801561086a57600080fd5b50604051908082528060200260200182016040528015610894578160200160208202803683370190505b5091506000805b835181101561092d5760008382815181106108b257fe5b6020908102919091018101516001600160a01b03811660009081526009909252604090912054909150600160981b90046001600160601b031615610924578085848060010195508151811061090357fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b5060010161089b565b5082525090565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109c05780601f10610995576101008083540402835291602001916109c0565b820191906000526020600020905b8154815290600101906020018083116109a357829003601f168201915b5050505050905090565b3360008181526001602090815260408083206001600160a01b03871680855292528083208590555191929091600080516020615c2083398151915290610a11908690615b5a565b60405180910390a35060015b92915050565b60055460009060ff1615610a495760405162461bcd60e51b81526004016106179061573c565b610a51614dd7565b610a5a8461389f565b509050610a65614dd7565b610a6e846133ad565b9050610aa18260c0015183606001516001600160601b03168360c0015184606001516001600160601b03166007546139ed565b95945050505050565b60025490565b60055461010090046001600160a01b031615610ade5760405162461bcd60e51b8152600401610617906158f6565b6001600160a01b038516610b045760405162461bcd60e51b8152600401610617906159f1565b60058054610100600160a81b0319166101006001600160a01b038816021790556032670de0b6b3a764000004600755604080516020601f8601819004810282018101909252848152610ba491869086908190840183828082843760009201919091525050604080516020601f88018190048102820181019092528681529250869150859081908401838280828437600092019190915250613a5292505050565b5050505050565b6000336001600160a01b0385161480610be757506001600160a01b03841660009081526001602090815260408083203384529091529020548211155b610c035760405162461bcd60e51b8152600401610617906156b7565b610c0e848484613ac9565b336001600160a01b03851614801590610c4c57506001600160a01b038416600090815260016020908152604080832033845290915290205460001914155b15610cd2576001600160a01b0384166000908152600160209081526040808320338452909152902054610c7f90836136b4565b6001600160a01b038581166000908152600160209081526040808320338085529252918290208490559051918616929091600080516020615c2083398151915291610cc991615b5a565b60405180910390a35b5060019392505050565b60055461010090046001600160a01b03163314610d0b5760405162461bcd60e51b815260040161061790615498565b60085415610d2b5760405162461bcd60e51b815260040161061790615664565b876002811015610d4d5760405162461bcd60e51b815260040161061790615a44565b600a811115610d6e5760405162461bcd60e51b8152600401610617906154ea565b8681148015610d7c57508481145b610d985760405162461bcd60e51b815260040161061790615885565b6000805b828110156110745760008c8c83818110610db257fe5b9050602002016020810190610dc79190614f3f565b90506000898984818110610dd757fe5b9050602002016020810190610dec9190615379565b905060008c8c85818110610dfc57fe5b9050602002013590506004670de0b6b3a764000081610e1757fe5b04826001600160601b03161015610e405760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b0383161115610e725760405162461bcd60e51b815260040161061790615590565b620f4240811015610e955760405162461bcd60e51b81526004016106179061560d565b6040518060e001604052806001151581526020016001151581526020014264ffffffffff168152602001836001600160601b03168152602001836001600160601b031681526020018560ff1681526020018281525060096000856001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548164ffffffffff021916908364ffffffffff16021790555060608201518160000160076101000a8154816001600160601b0302191690836001600160601b0316021790555060808201518160000160136101000a8154816001600160601b0302191690836001600160601b0316021790555060a082015181600001601f6101000a81548160ff021916908360ff16021790555060c082015181600101559050506008839080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555061105c85836001600160601b0316613bb2565b9450611069838a83613bde565b505050600101610d9c565b50680176b344f2a78c000081111561109e5760405162461bcd60e51b8152600401610617906155b8565b600a8190556006805460ff60a01b1916600160a01b1790556040517f40fc85fbff9305015298ba6fcee88b7e442a64cc803ddb889327680bbd62270a906110e79060019061545a565b60405180910390a161110168056bc75e2d63100000613c09565b6111148568056bc75e2d63100000613895565b5050600680546001600160a01b039384166001600160a01b031991821617909155600c805492909316911617905550505050505050565b6001600160a01b03811660009081526009602052604090205460ff165b919050565b60055461010090046001600160a01b031690565b601290565b60055461010090046001600160a01b031633146111b55760405162461bcd60e51b815260040161061790615498565b64e8d4a5100081108015906111d2575067016345785d8a00008111155b6111ee5760405162461bcd60e51b815260040161061790615a1b565b60078190556040517fccfe595973efc7c1f6c29e31974d380470b9431d7770290185b7129419c7e63e90611223908390615b5a565b60405180910390a150565b60055460009060ff16156112545760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055611269614dd7565b611272856133ad565b9050600061129b8260c0015183606001516001600160601b0316600254600a5489600754613c12565b9050838110156112bd5760405162461bcd60e51b8152600401610617906155e6565b6112d78260c001516003670de0b6b3a76400008161065a57fe5b8111156112f65760405162461bcd60e51b815260040161061790615761565b6113018633836135c5565b61130f8260c00151826136b4565b6001600160a01b03871660009081526009602052604090206001015561133582876136ed565b6000611348866611c37937e08000613482565b9050866001600160a01b0316336001600160a01b03167fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8460405161138d9190615b5a565b60405180910390a361139f338761387f565b6107a361079e87836136b4565b60055461010090046001600160a01b031633146113db5760405162461bcd60e51b815260040161061790615498565b6006805460ff60a01b1916600160a01b831515021790556040517f40fc85fbff9305015298ba6fcee88b7e442a64cc803ddb889327680bbd62270a9061122390839061545a565b60055460009060ff16156114485760405162461bcd60e51b81526004016106179061573c565b611450614dd7565b506001600160a01b038216600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526114fc5760405162461bcd60e51b81526004016106179061578c565b80602001516115255750506001600160a01b0381166000908152600b6020526040902054611168565b60c0015192915050565b60055460ff16156115525760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff166115885760405162461bcd60e51b8152600401610617906157de565b6000611592610aaa565b905060006115a08583613ce6565b9050806115bf5760405162461bcd60e51b815260040161061790615567565b60085483146115e05760405162461bcd60e51b815260040161061790615885565b60005b83811015611703576000600882815481106115fa57fe5b6000918252602090912001546001600160a01b03169050611619614dd7565b60006116248361389f565b915091506000611638868460c00151613482565b9050806116575760405162461bcd60e51b815260040161061790615567565b88888681811061166357fe5b905060200201358111156116895760405162461bcd60e51b8152600401610617906156e6565b61169d84846116988585613bb2565b613d7a565b836001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a836040516116e09190615b5a565b60405180910390a36116f3843383613bde565b5050600190920191506115e39050565b5061170d85613c09565b6117173386613895565b50506005805460ff19169055505050565b60055460ff161561174b5760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b031633146117885760405162461bcd60e51b815260040161061790615498565b8083146117a75760405162461bcd60e51b815260040161061790615885565b60005b83811015611717576117fc8585838181106117c157fe5b90506020020160208101906117d69190614f3f565b8484848181106117e257fe5b90506020020160208101906117f79190615379565b613f82565b6001016117aa565b60055460009060ff161561182a5760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff166118605760405162461bcd60e51b8152600401610617906157de565b611868614dd7565b60006118738661389f565b9150915084600014156118985760405162461bcd60e51b815260040161061790615a9c565b6118b88260c001516002670de0b6b3a7640000816118b257fe5b04613482565b8511156118d75760405162461bcd60e51b815260040161061790615512565b60006118fe8360c0015184606001516001600160601b0316600254600a548a60075461409f565b9050848110156119205760405162461bcd60e51b8152600401610617906155e6565b61192f8784611698858a613bb2565b866001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a886040516119729190615b5a565b60405180910390a361198381613c09565b61198d3382613895565b611998873388613bde565b6005805460ff191690559695505050505050565b6119b4614dd7565b60055460ff16156119d75760405162461bcd60e51b81526004016106179061573c565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526111685760405162461bcd60e51b81526004016106179061578c565b3360009081526001602090815260408083206001600160a01b038616845290915281205480831115611ad8573360009081526001602090815260408083206001600160a01b0388168452909152812055611b07565b611ae281846136b4565b3360009081526001602090815260408083206001600160a01b03891684529091529020555b3360008181526001602090815260408083206001600160a01b038916808552925291829020549151909291600080516020615c2083398151915291610cc99190615b5a565b60055460009060ff1615611b725760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff16611ba85760405162461bcd60e51b8152600401610617906157de565b611bb0614dd7565b6000611bbb8661389f565b915091506000611be68360c0015184606001516001600160601b0316600254600a548a60075461413b565b905080611c055760405162461bcd60e51b815260040161061790615567565b84811115611c255760405162461bcd60e51b8152600401610617906156e6565b611c3f8360c001516002670de0b6b3a7640000816118b257fe5b811115611c5e5760405162461bcd60e51b815260040161061790615512565b611c6d87846116988585613bb2565b866001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a83604051611cb09190615b5a565b60405180910390a3611cc186613c09565b611ccb3387613895565b611998873383613bde565b6001600160a01b031660009081526020819052604090205490565b600554600090819060ff1615611d195760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff16611d4f5760405162461bcd60e51b8152600401610617906157de565b611d57614dd7565b6000611d628961389f565b91509150611d6e614dd7565b611d77886133ad565b9050611d938160c001516003670de0b6b3a76400008161065a57fe5b871115611db25760405162461bcd60e51b815260040161061790615761565b6000611de58460c0015185606001516001600160601b03168460c0015185606001516001600160601b03166007546139ed565b905086811115611e075760405162461bcd60e51b815260040161061790615806565b6000611e3b8560c0015186606001516001600160601b03168560c0015186606001516001600160601b03168d6007546141d5565b90508a811115611e5d5760405162461bcd60e51b8152600401610617906156e6565b611e688c3383613bde565b611e738a338b6135c5565b611e818360c001518a6136b4565b60c084018190526001600160a01b038b16600090815260096020526040902060010155611eae838b6136ed565b611eb88482613bb2565b9350611ec58c8686613d7a565b846020015115611ed75760c085018490525b6000611f0a8660c0015187606001516001600160601b03168660c0015187606001516001600160601b03166007546139ed565b905082811015611f2c5760405162461bcd60e51b815260040161061790615567565b88811115611f4c5760405162461bcd60e51b8152600401610617906158cd565b611f56828b613ce6565b831115611f755760405162461bcd60e51b815260040161061790615567565b8a6001600160a01b03168d6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378858e604051611fc4929190615b63565b60405180910390a46005805460ff19169055909c909b509950505050505050505050565b600181565b600554600090819060ff16156120155760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff1661204b5760405162461bcd60e51b8152600401610617906157de565b612053614dd7565b600061205e8961389f565b9150915061206a614dd7565b612073886133ad565b905061208f8360c001516002670de0b6b3a7640000816118b257fe5b8911156120ae5760405162461bcd60e51b815260040161061790615512565b60006120e18460c0015185606001516001600160601b03168460c0015185606001516001600160601b03166007546139ed565b9050868111156121035760405162461bcd60e51b815260040161061790615806565b60006121378560c0015186606001516001600160601b03168560c0015186606001516001600160601b03168f600754614258565b9050888110156121595760405162461bcd60e51b8152600401610617906155e6565b6121648c338d613bde565b61216f8a33836135c5565b61217d8360c00151826136b4565b60c084018190526001600160a01b038b166000908152600960205260409020600101556121aa838b6136ed565b6121b4848c613bb2565b93506121c18c8686613d7a565b8460200151156121d35760c085018490525b60006122068660c0015187606001516001600160601b03168660c0015187606001516001600160601b03166007546139ed565b9050828110156122285760405162461bcd60e51b81526004016106179061553c565b888111156122485760405162461bcd60e51b8152600401610617906158cd565b6122528c83613ce6565b8311156122715760405162461bcd60e51b815260040161061790615567565b8a6001600160a01b03168d6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d433788f86604051611fc4929190615b63565b600c546001600160a01b031690565b60055460ff16156122f25760405162461bcd60e51b81526004016106179061573c565b6005805460ff191660011790556001600160a01b03811660008181526009602052604080822090516370a0823160e01b81529092906370a082319061233b9030906004016153bc565b60206040518083038186803b15801561235357600080fd5b505afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190615317565b825490915060ff161561252c578154610100900460ff16612509576001600160a01b0383166000908152600b6020526040902054808210612507576001600160a01b0384166000818152600b6020526040808220829055855461ff001916610100178655517ff7bb8e57ffdfd9a31e7580ee84f68757f44fb4a8a913f44520d22f2da1c955e59190a2600061242083836136b4565b9050600061242e8284613ce6565b9050600061244d6703782dace9d900006124488185613482565b613bb2565b90506706f05b59d3b200006001600160601b038216111561247357506706f05b59d3b200005b8554600160381b600160981b031916600160381b6001600160601b0383169081029190911766ffffffffff00001916620100004264ffffffffff1602178755600a546124be91613bb2565b600a5585546040516001600160a01b03891691600080516020615c00833981519152916124fb91600160381b90046001600160601b031690615b7f565b60405180910390a25050505b505b6001600160a01b03831660009081526009602052604090206001018190556125a9565b6006546125449084906001600160a01b0316836135c5565b6006546040516360b8257960e11b81526001600160a01b039091169063c1704af29061257690869085906004016153f4565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b505050505b50506005805460ff1916905550565b60055460009060ff16156125de5760405162461bcd60e51b81526004016106179061573c565b6125e6614dd7565b506001600160a01b038216600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526126925760405162461bcd60e51b81526004016106179061578c565b8060200151156126b45760405162461bcd60e51b8152600401610617906158aa565b50506001600160a01b03166000908152600b602052604090205490565b60055461010090046001600160a01b031633146127005760405162461bcd60e51b815260040161061790615498565b6001600160a01b0381166127265760405162461bcd60e51b8152600401610617906159f1565b60058054610100600160a81b0319166101006001600160a01b038416021790556040517f93a5d7f74a690ad8848fb740519ac14bd303a47c6a1bbb2578357b8db0995a2d906112239083906153bc565b60055460009060ff161561279c5760405162461bcd60e51b81526004016106179061573c565b50600a5490565b60055460009060ff16156127c95760405162461bcd60e51b81526004016106179061573c565b6001600160a01b03821660009081526009602052604090205460ff166128015760405162461bcd60e51b81526004016106179061578c565b506001600160a01b0316600090815260096020526040902054600160381b90046001600160601b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109c05780601f10610995576101008083540402835291602001916109c0565b60055460ff16156128b15760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b031633146128ee5760405162461bcd60e51b815260040161061790615498565b6001600160a01b0382166000908152600960205260409020805460ff166129275760405162461bcd60e51b81526004016106179061578c565b8054610100900460ff161561294e5760405162461bcd60e51b8152600401610617906158aa565b80546154606201000090910464ffffffffff16420310156129815760405162461bcd60e51b815260040161061790615ac1565b805466ffffffffff00001916620100004264ffffffffff16021781556001600160a01b0383166000908152600b602052604090819020839055517e0c7a55677231b335e6dea005fa240ac2aeafbd62f188372a7d66892b722c52906129e990859085906153f4565b60405180910390a150506005805460ff1916905550565b6000612a0d338484613ac9565b50600192915050565b60055460ff1615612a395760405162461bcd60e51b81526004016106179061573c565b6005805460ff191660011790556008548114612a675760405162461bcd60e51b815260040161061790615885565b6000612a71610aaa565b90506000612a86856611c37937e08000613482565b90506000612a9486836136b4565b90506000612aa28285613ce6565b905080612ac15760405162461bcd60e51b815260040161061790615567565b612acb338861387f565b600c54612ae1906001600160a01b031684613895565b612aea82613889565b60005b85811015612ccd57600060088281548110612b0457fe5b6000918252602090912001546001600160a01b03169050612b23614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158352610100820481161580159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c0830152612c91576000612bc7858360c00151613482565b905080612be65760405162461bcd60e51b815260040161061790615567565b898985818110612bf257fe5b90506020020135811015612c185760405162461bcd60e51b8152600401610617906155e6565b612c268260c00151826136b4565b6001600160a01b0384166000818152600960205260409081902060010192909255905133907fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed90612c78908590615b5a565b60405180910390a3612c8b8333836135c5565b50612cc3565b888884818110612c9d57fe5b90506020020135600014612cc35760405162461bcd60e51b8152600401610617906157b3565b5050600101612aed565b50506005805460ff19169055505050505050565b60055460ff1615612d045760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b03163314612d415760405162461bcd60e51b815260040161061790615498565b8285148015612d4f57508085145b612d6b5760405162461bcd60e51b815260040161061790615885565b60085460608167ffffffffffffffff81118015612d8757600080fd5b50604051908082528060200260200182016040528015612db1578160200160208202803683370190505b50905060608767ffffffffffffffff81118015612dcd57600080fd5b50604051908082528060200260200182016040528015612e0757816020015b612df4614dd7565b815260200190600190039081612dec5790505b50905060005b88811015612f4257600960008b8b84818110612e2557fe5b9050602002016020810190612e3a9190614f3f565b6001600160a01b031681526020808201929092526040908101600020815160e081018352815460ff808216151583526101008204811615159583019590955264ffffffffff62010000820416938201939093526001600160601b03600160381b840481166060830152600160981b8404166080820152600160f81b90920490921660a082015260019091015460c08201528251839083908110612ed957fe5b6020026020010181905250818181518110612ef057fe5b60200260200101516000015115612f3a57600183838381518110612f1057fe5b602002602001015160a0015160ff1681518110612f2957fe5b911515602092830291909101909101525b600101612e0d565b5060005b83811015612f9857828181518110612f5a57fe5b6020026020010151612f9057612f9060088281548110612f7657fe5b60009182526020822001546001600160a01b031690613f82565b600101612f46565b5060005b888110156130645760008a8a83818110612fb257fe5b9050602002016020810190612fc79190614f3f565b90506000898984818110612fd757fe5b9050602002016020810190612fec9190615379565b90506703782dace9d900006001600160601b038216101561301257506703782dace9d900005b83838151811061301e57fe5b6020026020010151600001516130505761304b8289898681811061303e57fe5b90506020020135836142d9565b61305a565b61305a8282613f82565b5050600101612f9c565b50506005805460ff191690555050505050505050565b60055460609060ff16156130a05760405162461bcd60e51b81526004016106179061573c565b60088054806020026020016040519081016040528092919081815260200182805480156109c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130d8575050505050905090565b60085490565b60055460009060ff161561312b5760405162461bcd60e51b81526004016106179061573c565b5060075490565b3360009081526001602090815260408083206001600160a01b03861684529091528120546131609083613bb2565b3360008181526001602090815260408083206001600160a01b03891680855292529182902084905590519092600080516020615c2083398151915291610a119190615b5a565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009060ff16156131f75760405162461bcd60e51b81526004016106179061573c565b506611c37937e0800090565b60055460009060ff16156132295760405162461bcd60e51b81526004016106179061573c565b6001600160a01b0382166000908152600960205260409020805460ff166132625760405162461bcd60e51b81526004016106179061578c565b6001015492915050565b60055461010090046001600160a01b0316331461329b5760405162461bcd60e51b815260040161061790615498565b6040516317066a5760e21b81526001600160a01b03831690635c19a95c906132c79084906004016153bc565b600060405180830381600087803b1580156132e157600080fd5b505af11580156132f5573d6000803e3d6000fd5b505050505050565b60055461010090046001600160a01b0316331461332c5760405162461bcd60e51b815260040161061790615498565b6001600160a01b0381166133525760405162461bcd60e51b8152600401610617906159f1565b600c80546001600160a01b0319166001600160a01b0383161790556040517fc79e675f96e92542a27382e2c3d22ffc5e7862d51251311f06ca685db3f11ff7906112239083906153bc565b600654600160a01b900460ff1690565b6133b5614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526134615760405162461bcd60e51b81526004016106179061578c565b80602001516111685760405162461bcd60e51b8152600401610617906157b3565b600082820283158061349c57508284828161349957fe5b04145b6134b85760405162461bcd60e51b81526004016106179061585b565b6706f05b59d3b200008101818110156134e35760405162461bcd60e51b81526004016106179061585b565b6000670de0b6b3a7640000825b049695505050505050565b6000806135088786613ce6565b9050600061351e670de0b6b3a7640000836136b4565b9050600061352c8286613482565b9050600061354b87613546670de0b6b3a7640000856136b4565b613ce6565b905060006135598c836136b4565b90506000613567828e613ce6565b9050600061357582886145b8565b90506000613583828e613482565b905060006135918e836136b4565b90506135b081613546670de0b6b3a76400006611c37937e080006136b4565b99505050505050505050509695505050505050565b60006060846001600160a01b031663a9059cbb60e01b85856040516024016135ee9291906153f4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161362c91906153a0565b6000604051808303816000865af19150503d8060008114613669576040519150601f19603f3d011682016040523d82523d6000602084013e61366e565b606091505b509150915081801561369857508051158061369857508080602001905181019061369891906152e3565b610ba45760405162461bcd60e51b815260040161061790615973565b60008060006136c3858561466b565b9150915080156136e55760405162461bcd60e51b81526004016106179061599c565b509392505050565b81608001516001600160601b031682606001516001600160601b031611158061371857508160200151155b806137315750610708826040015164ffffffffff164203105b1561373b5761387b565b6060820151608083015160006137646001600160601b0384166064670de0b6b3a76400006118b2565b90506000613784846001600160601b0316846001600160601b03166136b4565b9050818111156137a7576137a1846001600160601b0316836136b4565b92508190505b6703782dace9d900006001600160601b038416116137e157600a54600093506137d090846136b4565b600a556137dc85614690565b6132f5565b6137ed600a54826136b4565b600a556001600160601b038316606087018190526001600160a01b038616600081815260096020526040908190208054600160381b600160981b031916600160381b9094029390931766ffffffffff00001916620100004264ffffffffff1602179092559051600080516020615c008339815191529061386e908690615b7f565b60405180910390a2505050505b5050565b61387b82826149d2565b613892816149dd565b50565b61387b8282614a86565b6138a7614dd7565b506001600160a01b0381166000908152600960209081526040808320815160e081018352815460ff80821615158084526101008304821615159684019690965264ffffffffff62010000830416948301949094526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490921660a08301526001015460c082015291906139545760405162461bcd60e51b81526004016106179061578c565b5060c081015160208201516139e8576001600160a01b0383166000908152600b602052604081205460c0840181905261399b9061399190846136b4565b8460c00151613ce6565b905060006139bf600a6004670de0b6b3a76400005b04816139b857fe5b0483613482565b90506139d76004670de0b6b3a76400005b0482613bb2565b6001600160601b0316606085015250505b915091565b6000806139fa8787613ce6565b90506000613a088686613ce6565b90506000613a168383613ce6565b90506000613a38670de0b6b3a7640000613546670de0b6b3a7640000896136b4565b9050613a448282613482565b9a9950505050505050505050565b60035460026000196101006001841615020190911604158015613a755750815115155b8015613a815750805115155b613a9d5760405162461bcd60e51b81526004016106179061570c565b8151613ab0906003906020850190614e13565b508051613ac4906004906020840190614e13565b505050565b6001600160a01b038316600090815260208190526040902054811115613b015760405162461bcd60e51b815260040161061790615636565b6001600160a01b038316600090815260208190526040902054613b2490826136b4565b6001600160a01b038085166000908152602081905260408082209390935590841681522054613b539082613bb2565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613ba5908590615b5a565b60405180910390a3505050565b600082820183811015613bd75760405162461bcd60e51b8152600401610617906159c7565b9392505050565b60006060846001600160a01b03166323b872dd60e01b8530866040516024016135ee939291906153d0565b61389281614a91565b600080613c1f8786613ce6565b90506000613c4585613c40670de0b6b3a76400006611c37937e080006136b4565b613482565b90506000613c5388836136b4565b90506000613c61828a613ce6565b90506000613c8082613c7b670de0b6b3a764000088613ce6565b6145b8565b90506000613c8e828e613482565b90506000613c9c8e836136b4565b90506000613cbb613cb5670de0b6b3a76400008a6136b4565b8b613482565b9050613cd382613c40670de0b6b3a7640000846136b4565b9f9e505050505050505050505050505050565b600081613d055760405162461bcd60e51b81526004016106179061591e565b670de0b6b3a76400008302831580613d2d5750670de0b6b3a7640000848281613d2a57fe5b04145b613d495760405162461bcd60e51b81526004016106179061568d565b60028304810181811015613d6f5760405162461bcd60e51b81526004016106179061568d565b60008482816134f057fe5b8160200151613f55578160c001518110613efe576001600160a01b0383166000818152600b6020908152604080832083905560098252808320805461ff001916610100179055600191860191909152517ff7bb8e57ffdfd9a31e7580ee84f68757f44fb4a8a913f44520d22f2da1c955e59190a26000613dfe828460c001516136b4565b90506000613e10828560c00151613ce6565b9050613e286703782dace9d900006124488184613482565b6001600160601b0316606085018190526706f05b59d3b200001015613e56576706f05b59d3b2000060608501525b6060840180516001600160a01b03871660009081526009602052604090208054600160381b600160981b031916600160381b6001600160601b03938416021766ffffffffff00001916620100004264ffffffffff1602179055600a549151613ebf929116613bb2565b600a5560608401516040516001600160a01b03871691600080516020615c0083398151915291613eef9190615b7f565b60405180910390a25050613f50565b6000613f116139918460c00151846136b4565b90506000613f2a600a6004670de0b6b3a76400006139b0565b9050613f3f6004670de0b6b3a76400006139d0565b6001600160601b0316606085015250505b613f5f565b613f5f8284614b00565b6001600160a01b0390921660009081526009602052604090206001019190915550565b6001600160a01b0382166000908152600960205260409020805460ff16613fbb5760405162461bcd60e51b81526004016106179061578c565b6703782dace9d900006001600160601b038316101580613fe257506001600160601b038216155b613ffe5760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b03831611156140305760405162461bcd60e51b815260040161061790615590565b80546bffffffffffffffffffffffff60981b1916600160981b6001600160601b038416021781556040516001600160a01b038416907fc7ea88f3376e27ce6ebc2025310023327f743a8377d438258c36b166dd8b298390614092908590615b7f565b60405180910390a2505050565b6000806140ac8786613ce6565b905060006140cb6140c5670de0b6b3a7640000846136b4565b85613482565b905060006140e586613c40670de0b6b3a7640000856136b4565b905060006140f38b83613bb2565b90506000614101828d613ce6565b9050600061410f82876145b8565b9050600061411d828d613482565b9050614129818d6136b4565b9e9d5050505050505050505050505050565b6000806141488786613ce6565b905060006141568786613bb2565b905060006141648289613ce6565b9050600061417a670de0b6b3a764000085613ce6565b9050600061418883836145b8565b90506000614196828e613482565b905060006141a4828f6136b4565b905060006141bd613cb5670de0b6b3a76400008a6136b4565b9050613cd382613546670de0b6b3a7640000846136b4565b6000806141e28588613ce6565b905060006141f087866136b4565b905060006141fe8883613ce6565b9050600061420c82856145b8565b905061422081670de0b6b3a76400006136b4565b9050614234670de0b6b3a7640000876136b4565b94506142496142438c83613482565b86613ce6565b9b9a5050505050505050505050565b6000806142658786613ce6565b9050600061427b670de0b6b3a7640000856136b4565b90506142878582613482565b905060006142998a6135468c85613bb2565b905060006142a782856145b8565b905060006142bd670de0b6b3a7640000836136b4565b90506142c98a82613482565b9c9b505050505050505050505050565b6001600160a01b03831660009081526009602052604090205460ff16156143125760405162461bcd60e51b8152600401610617906154c4565b6703782dace9d900006001600160601b03821610156143435760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b03821611156143755760405162461bcd60e51b815260040161061790615590565b620f42408210156143985760405162461bcd60e51b81526004016106179061560d565b6040518060e001604052806001151581526020016000151581526020014264ffffffffff16815260200160006001600160601b03168152602001826001600160601b0316815260200160088054905060ff168152602001600081525060096000856001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548164ffffffffff021916908364ffffffffff16021790555060608201518160000160076101000a8154816001600160601b0302191690836001600160601b0316021790555060808201518160000160136101000a8154816001600160601b0302191690836001600160601b0316021790555060a082015181600001601f6101000a81548160ff021916908360ff16021790555060c082015181600101559050506008839080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600b6000856001600160a01b03166001600160a01b0316815260200190815260200160002081905550826001600160a01b03167fb2daf560899f6307b318aecfb57eb2812c488da4a4c1cad2019b482fa63294ed8284604051614092929190615b93565b600060018310156145db5760405162461bcd60e51b815260040161061790615944565b671bc16d674ec7ffff8311156146035760405162461bcd60e51b815260040161061790615a6c565b600061460e83614c79565b9050600061461c84836136b4565b905060006146328661462d85614c94565b614ca2565b905081614643579250610a1d915050565b600061465487846305f5e100614cf9565b90506146608282613482565b979650505050505050565b6000808284106146815750508082036000614689565b505081810360015b9250929050565b614698614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff808216151583526101008204811615159483019490945264ffffffffff62010000820416948201949094526001600160601b03600160381b850481166060830152600160981b8504166080820152600160f81b90930490911660a0830181905260019091015460c08301819052600854909190600019018082146147f6576008818154811061474c57fe5b600091825260209091200154600880546001600160a01b03909216918490811061477257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160096000600885815481106147b257fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020805460ff92909216600160f81b026001600160f81b039092169190911790555b600880548061480157fe5b60008281526020808220600019908401810180546001600160a01b03191690559092019092556040805160e081018252838152808301848152818301858152606083018681526080840187815260a0850188815260c086018981526001600160a01b038f81168b52600990995296909820945185549451935192519151985160ff199095169015151761ff001916610100931515939093029290921766ffffffffff000019166201000064ffffffffff9092169190910217600160381b600160981b031916600160381b6001600160601b0392831602176bffffffffffffffffffffffff60981b1916600160981b9190961602949094176001600160f81b0316600160f81b60ff90951694909402939093178355516001929092019190915560065461493091879116856135c5565b6006546040516360b8257960e11b81526001600160a01b039091169063c1704af29061496290889087906004016153f4565b600060405180830381600087803b15801561497c57600080fd5b505af1158015614990573d6000803e3d6000fd5b505050507f12a8262eb28ee8a8c11e6cf411b3af6ce5bea42abb36e051bf0a65ae602d52ec856040516149c391906153bc565b60405180910390a15050505050565b61387b823083613ac9565b30600090815260208190526040902054811115614a0c5760405162461bcd60e51b815260040161061790615636565b30600090815260208190526040902054614a2690826136b4565b30600090815260208190526040902055600254614a4390826136b4565b60025560405160009030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90614a7b908590615b5a565b60405180910390a350565b61387b308383613ac9565b30600090815260208190526040902054614aab9082613bb2565b30600090815260208190526040902055600254614ac89082613bb2565b60025560405130906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90614a7b908590615b5a565b81608001516001600160601b031682606001516001600160601b0316101580614b2b57508160200151155b80614b445750610708826040015164ffffffffff164203105b15614b4e5761387b565b606082015160808301516000614b776001600160601b0384166064670de0b6b3a76400006118b2565b90506000614b97836001600160601b0316856001600160601b03166136b4565b905081811115614bba57614bb4846001600160601b031683613bb2565b92508190505b6000614bc8600a5483613bb2565b9050680176b344f2a78c0000811115614be557505050505061387b565b600a8190556001600160601b038416606088018190526001600160a01b038716600081815260096020526040908190208054600160381b600160981b031916600160381b9094029390931766ffffffffff00001916620100004264ffffffffff1602179092559051600080516020615c0083398151915290614c68908790615b7f565b60405180910390a250505050505050565b6000670de0b6b3a7640000614c8d83614c94565b0292915050565b670de0b6b3a7640000900490565b60008060028306614cbb57670de0b6b3a7640000614cbd565b835b90506002830492505b8215613bd757614cd68485613482565b93506002830615614cee57614ceb8185613482565b90505b600283049250614cc6565b6000828180614d1087670de0b6b3a764000061466b565b9092509050670de0b6b3a764000080600060015b888410614dc8576000670de0b6b3a764000082029050600080614d588a614d5385670de0b6b3a76400006136b4565b61466b565b91509150614d6a87613c40848c613482565b9650614d768784613ce6565b965086614d8557505050614dc8565b8715614d8f579315935b8015614d99579315935b8415614db057614da986886136b4565b9550614dbd565b614dba8688613bb2565b95505b505050600101614d24565b50909998505050505050505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614e5457805160ff1916838001178555614e81565b82800160010185558215614e81579182015b82811115614e81578251825591602001919060010190614e66565b50614e8d929150614e91565b5090565b5b80821115614e8d5760008155600101614e92565b80356001600160a01b0381168114610a1d57600080fd5b60008083601f840112614ece578182fd5b50813567ffffffffffffffff811115614ee5578182fd5b602083019150836020808302850101111561468957600080fd5b60008083601f840112614f10578182fd5b50813567ffffffffffffffff811115614f27578182fd5b60208301915083602082850101111561468957600080fd5b600060208284031215614f50578081fd5b613bd78383614ea6565b60008060408385031215614f6c578081fd5b614f768484614ea6565b9150614f858460208501614ea6565b90509250929050565b600080600060608486031215614fa2578081fd5b8335614fad81615bdc565b92506020840135614fbd81615bdc565b929592945050506040919091013590565b600080600080600060608688031215614fe5578081fd5b8535614ff081615bdc565b9450602086013567ffffffffffffffff8082111561500c578283fd5b61501889838a01614eff565b90965094506040880135915080821115615030578283fd5b5061503d88828901614eff565b969995985093965092949392505050565b60008060408385031215615060578182fd5b61506a8484614ea6565b946020939093013593505050565b600080600080600060a0868803121561508f578081fd5b6150998787614ea6565b9450602086013593506150af8760408801614ea6565b94979396509394606081013594506080013592915050565b6000806000606084860312156150db578283fd5b6150e58585614ea6565b95602085013595506040909401359392505050565b600080600080600080600080600060c08a8c031215615117578384fd5b893567ffffffffffffffff8082111561512e578586fd5b61513a8d838e01614ebd565b909b50995060208c0135915080821115615152578586fd5b61515e8d838e01614ebd565b909950975060408c0135915080821115615176578586fd5b506151838c828d01614ebd565b90965094505060608a013561519781615bdc565b925060808a01356151a781615bdc565b915060a08a01356151b781615bdc565b809150509295985092959850929598565b600080600080604085870312156151dd578384fd5b843567ffffffffffffffff808211156151f4578586fd5b61520088838901614ebd565b90965094506020870135915080821115615218578384fd5b5061522587828801614ebd565b95989497509550505050565b60008060008060008060608789031215615249578384fd5b863567ffffffffffffffff80821115615260578586fd5b61526c8a838b01614ebd565b90985096506020890135915080821115615284578586fd5b6152908a838b01614ebd565b909650945060408901359150808211156152a8578384fd5b506152b589828a01614ebd565b979a9699509497509295939492505050565b6000602082840312156152d8578081fd5b8135613bd781615bf1565b6000602082840312156152f4578081fd5b8151613bd781615bf1565b600060208284031215615310578081fd5b5035919050565b600060208284031215615328578081fd5b5051919050565b600080600060408486031215615343578081fd5b83359250602084013567ffffffffffffffff811115615360578182fd5b61536c86828701614ebd565b9497909650939450505050565b60006020828403121561538a578081fd5b81356001600160601b0381168114613bd7578182fd5b600082516153b2818460208701615bac565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561544e5783516001600160a01b031683529284019291840191600101615429565b50909695505050505050565b901515815260200190565b6000602082528251806020840152615484816040850160208701615bac565b601f01601f19169190910160400192915050565b60208082526012908201527122a9292fa727aa2fa1a7a72a2927a62622a960711b604082015260600190565b6020808252600c908201526b11549497d254d7d093d5539160a21b604082015260600190565b6020808252600e908201526d4552525f4d41585f544f4b454e5360901b604082015260600190565b60208082526010908201526f4552525f4d41585f494e5f524154494f60801b604082015260600190565b60208082526011908201527022a9292fa6a0aa242fa0a8282927ac2f9960791b604082015260600190565b6020808252600f908201526e08aa4a4be9a82a890be82a0a0a49eb608b1b604082015260600190565b6020808252600e908201526d11549497d3505617d5d15251d21560921b604082015260600190565b60208082526014908201527311549497d3505617d513d5105317d5d15251d21560621b604082015260600190565b6020808252600d908201526c11549497d31253525517d3d555609a1b604082015260600190565b6020808252600f908201526e4552525f4d494e5f42414c414e434560881b604082015260600190565b60208082526014908201527311549497d25394d551919250d251539517d0905360621b604082015260600190565b6020808252600f908201526e11549497d253925512505312569151608a1b604082015260600190565b60208082526010908201526f11549497d1125597d25395115493905360821b604082015260600190565b60208082526015908201527422a9292fa12a27a5a2a72fa120a22fa1a0a62622a960591b604082015260600190565b6020808252600c908201526b22a9292fa624a6a4aa2fa4a760a11b604082015260600190565b60208082526016908201527511549497d09513d2d15397d25392551250531256915160521b604082015260600190565b6020808252600b908201526a4552525f5245454e54525960a81b604082015260600190565b6020808252601190820152704552525f4d41585f4f55545f524154494f60781b604082015260600190565b6020808252600d908201526c11549497d393d517d093d55391609a1b604082015260600190565b6020808252601190820152704552525f4f55545f4e4f545f524541445960781b604082015260600190565b6020808252600e908201526d4552525f4e4f545f5055424c494360901b604082015260600190565b6020808252601390820152724552525f4241445f4c494d49545f505249434560681b604082015260600190565b6020808252600e908201526d11549497d3525397d5d15251d21560921b604082015260600190565b60208082526010908201526f4552525f4d554c5f4f564552464c4f5760801b604082015260600190565b6020808252600b908201526a22a9292fa0a9292fa622a760a91b604082015260600190565b6020808252600990820152684552525f524541445960b81b604082015260600190565b6020808252600f908201526e4552525f4c494d49545f505249434560881b604082015260600190565b6020808252600e908201526d11549497d0d3d3919251d554915160921b604082015260600190565b6020808252600c908201526b4552525f4449565f5a45524f60a01b604082015260600190565b6020808252601590820152744552525f42504f575f424153455f544f4f5f4c4f5760581b604082015260600190565b6020808252600f908201526e4552525f45524332305f46414c534560881b604082015260600190565b6020808252601190820152704552525f5355425f554e444552464c4f5760781b604082015260600190565b60208082526010908201526f4552525f4144445f4f564552464c4f5760801b604082015260600190565b60208082526010908201526f4552525f4e554c4c5f4144445245535360801b604082015260600190565b6020808252600f908201526e4552525f494e56414c49445f46454560881b604082015260600190565b6020808252600e908201526d4552525f4d494e5f544f4b454e5360901b604082015260600190565b60208082526016908201527508aa4a4be84a09eaebe8482a68abea89e9ebe90928e960531b604082015260600190565b6020808252600b908201526a22a9292fad22a927afa4a760a91b604082015260600190565b6020808252601490820152734d494e5f42414c5f5550444154455f44454c415960601b604082015260600190565b600060e08201905082511515825260208301511515602083015264ffffffffff604084015116604083015260608301516001600160601b038082166060850152806080860151166080850152505060ff60a08401511660a083015260c083015160c083015292915050565b90815260200190565b918252602082015260400190565b60ff91909116815260200190565b6001600160601b0391909116815260200190565b6001600160601b03929092168252602082015260400190565b60005b83811015615bc7578181015183820152602001615baf565b83811115615bd6576000848401525b50505050565b6001600160a01b038116811461389257600080fd5b801515811461389257600080fdfe21b12aed5d425f5675450ffeeae01039085e5323974c3099e1828155d9b51e778c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a2646970667358221220e82b157d45f4e522ea20b9bb4c0f872a13392a53a155ce16660632cb1b4c4bf464736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102955760003560e01c80637c5e9ea411610167578063b02f0b73116100ce578063dd62ed3e11610087578063dd62ed3e14610595578063ecb0116a146105a8578063f8b2cb4f146105b0578063f8b5db09146105c3578063f9f97c98146105d6578063fde924f7146105e957610295565b8063b02f0b7314610544578063c3f4681014610557578063cc77828d1461056a578063cd2ed8fb14610572578063d4cadf681461057a578063d73dd6231461058257610295565b806392eefe9b1161012057806392eefe9b146104e8578063936c3477146104fb578063948d8ce61461050357806395d89b4114610516578063a49c44d71461051e578063a9059cbb1461053157610295565b80637c5e9ea41461047e5780638025e3031461049f5780638201aa3f146104a7578063865bcccb146104ba5780638c28cbe8146104c257806391bfa2bf146104d557610295565b8063313ce5671161020b5780635d5e8ce7116101c45780635d5e8ce7146103ff5780635db342771461041257806364c7d6611461042557806366188463146104455780636d06dfa01461045857806370a082311461046b57610295565b8063313ce5671461038b57806334e19907146103a057806346ab38f1146103b357806349b59552146103c65780634aa4e0b5146103d95780634f69c0d4146103ec57610295565b806318160ddd1161025d57806318160ddd1461032057806319f0f8491461032857806323b872dd1461033d5780632b110c74146103505780632f37b624146103635780633018205f1461037657610295565b806302c967481461029a578063039209af146102c357806306fdde03146102d8578063095ea7b3146102ed57806315e84af91461030d575b600080fd5b6102ad6102a83660046150c7565b6105f1565b6040516102ba9190615b5a565b60405180910390f35b6102cb6107cd565b6040516102ba919061540d565b6102e0610934565b6040516102ba9190615465565b6103006102fb36600461504e565b6109ca565b6040516102ba919061545a565b6102ad61031b366004614f5a565b610a23565b6102ad610aaa565b61033b610336366004614fce565b610ab0565b005b61030061034b366004614f8e565b610bab565b61033b61035e3660046150fa565b610cdc565b610300610371366004614f3f565b61114b565b61037e61116d565b6040516102ba91906153bc565b610393611181565b6040516102ba9190615b71565b61033b6103ae3660046152ff565b611186565b6102ad6103c13660046150c7565b61122e565b61033b6103d43660046152c7565b6113ac565b6102ad6103e7366004614f3f565b611422565b61033b6103fa36600461532f565b61152f565b61033b61040d3660046151c8565b611728565b6102ad6104203660046150c7565b611804565b610438610433366004614f3f565b6119ac565b6040516102ba9190615aef565b61030061045336600461504e565b611a83565b6102ad6104663660046150c7565b611b4c565b6102ad610479366004614f3f565b611cd6565b61049161048c366004615078565b611cf1565b6040516102ba929190615b63565b6102ad611fe8565b6104916104b5366004615078565b611fed565b61037e6122c0565b61033b6104d0366004614f3f565b6122cf565b6102ad6104e3366004614f3f565b6125b8565b61033b6104f6366004614f3f565b6126d1565b6102ad612776565b6102ad610511366004614f3f565b6127a3565b6102e061282d565b61033b61052c36600461504e565b61288e565b61030061053f36600461504e565b612a00565b61033b61055236600461532f565b612a16565b61033b610565366004615231565b612ce1565b6102cb61307a565b6102ad6130ff565b6102ad613105565b61030061059036600461504e565b613132565b6102ad6105a3366004614f5a565b6131a6565b6102ad6131d1565b6102ad6105be366004614f3f565b613203565b61033b6105d1366004614f5a565b61326c565b61033b6105e4366004614f3f565b6132fd565b61030061339d565b60055460009060ff16156106205760405162461bcd60e51b81526004016106179061573c565b60405180910390fd5b6005805460ff19166001179055610635614dd7565b61063e856133ad565b90506106638160c001516003670de0b6b3a76400008161065a57fe5b04600101613482565b8411156106825760405162461bcd60e51b815260040161061790615761565b60006106a98260c0015183606001516001600160601b0316600254600a54896007546134fb565b9050806106c85760405162461bcd60e51b815260040161061790615567565b838111156106e85760405162461bcd60e51b8152600401610617906156e6565b6106f38633876135c5565b6107018260c00151866136b4565b6001600160a01b03871660009081526009602052604090206001015561072782876136ed565b600061073a826611c37937e08000613482565b9050866001600160a01b0316336001600160a01b03167fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8860405161077f9190615b5a565b60405180910390a3610791338361387f565b6107a361079e83836136b4565b613889565b600c546107b9906001600160a01b031682613895565b506005805460ff1916905595945050505050565b60055460609060ff16156107f35760405162461bcd60e51b81526004016106179061573c565b6060600880548060200260200160405190810160405280929190818152602001828054801561084b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161082d575b50505050509050805167ffffffffffffffff8111801561086a57600080fd5b50604051908082528060200260200182016040528015610894578160200160208202803683370190505b5091506000805b835181101561092d5760008382815181106108b257fe5b6020908102919091018101516001600160a01b03811660009081526009909252604090912054909150600160981b90046001600160601b031615610924578085848060010195508151811061090357fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b5060010161089b565b5082525090565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109c05780601f10610995576101008083540402835291602001916109c0565b820191906000526020600020905b8154815290600101906020018083116109a357829003601f168201915b5050505050905090565b3360008181526001602090815260408083206001600160a01b03871680855292528083208590555191929091600080516020615c2083398151915290610a11908690615b5a565b60405180910390a35060015b92915050565b60055460009060ff1615610a495760405162461bcd60e51b81526004016106179061573c565b610a51614dd7565b610a5a8461389f565b509050610a65614dd7565b610a6e846133ad565b9050610aa18260c0015183606001516001600160601b03168360c0015184606001516001600160601b03166007546139ed565b95945050505050565b60025490565b60055461010090046001600160a01b031615610ade5760405162461bcd60e51b8152600401610617906158f6565b6001600160a01b038516610b045760405162461bcd60e51b8152600401610617906159f1565b60058054610100600160a81b0319166101006001600160a01b038816021790556032670de0b6b3a764000004600755604080516020601f8601819004810282018101909252848152610ba491869086908190840183828082843760009201919091525050604080516020601f88018190048102820181019092528681529250869150859081908401838280828437600092019190915250613a5292505050565b5050505050565b6000336001600160a01b0385161480610be757506001600160a01b03841660009081526001602090815260408083203384529091529020548211155b610c035760405162461bcd60e51b8152600401610617906156b7565b610c0e848484613ac9565b336001600160a01b03851614801590610c4c57506001600160a01b038416600090815260016020908152604080832033845290915290205460001914155b15610cd2576001600160a01b0384166000908152600160209081526040808320338452909152902054610c7f90836136b4565b6001600160a01b038581166000908152600160209081526040808320338085529252918290208490559051918616929091600080516020615c2083398151915291610cc991615b5a565b60405180910390a35b5060019392505050565b60055461010090046001600160a01b03163314610d0b5760405162461bcd60e51b815260040161061790615498565b60085415610d2b5760405162461bcd60e51b815260040161061790615664565b876002811015610d4d5760405162461bcd60e51b815260040161061790615a44565b600a811115610d6e5760405162461bcd60e51b8152600401610617906154ea565b8681148015610d7c57508481145b610d985760405162461bcd60e51b815260040161061790615885565b6000805b828110156110745760008c8c83818110610db257fe5b9050602002016020810190610dc79190614f3f565b90506000898984818110610dd757fe5b9050602002016020810190610dec9190615379565b905060008c8c85818110610dfc57fe5b9050602002013590506004670de0b6b3a764000081610e1757fe5b04826001600160601b03161015610e405760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b0383161115610e725760405162461bcd60e51b815260040161061790615590565b620f4240811015610e955760405162461bcd60e51b81526004016106179061560d565b6040518060e001604052806001151581526020016001151581526020014264ffffffffff168152602001836001600160601b03168152602001836001600160601b031681526020018560ff1681526020018281525060096000856001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548164ffffffffff021916908364ffffffffff16021790555060608201518160000160076101000a8154816001600160601b0302191690836001600160601b0316021790555060808201518160000160136101000a8154816001600160601b0302191690836001600160601b0316021790555060a082015181600001601f6101000a81548160ff021916908360ff16021790555060c082015181600101559050506008839080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555061105c85836001600160601b0316613bb2565b9450611069838a83613bde565b505050600101610d9c565b50680176b344f2a78c000081111561109e5760405162461bcd60e51b8152600401610617906155b8565b600a8190556006805460ff60a01b1916600160a01b1790556040517f40fc85fbff9305015298ba6fcee88b7e442a64cc803ddb889327680bbd62270a906110e79060019061545a565b60405180910390a161110168056bc75e2d63100000613c09565b6111148568056bc75e2d63100000613895565b5050600680546001600160a01b039384166001600160a01b031991821617909155600c805492909316911617905550505050505050565b6001600160a01b03811660009081526009602052604090205460ff165b919050565b60055461010090046001600160a01b031690565b601290565b60055461010090046001600160a01b031633146111b55760405162461bcd60e51b815260040161061790615498565b64e8d4a5100081108015906111d2575067016345785d8a00008111155b6111ee5760405162461bcd60e51b815260040161061790615a1b565b60078190556040517fccfe595973efc7c1f6c29e31974d380470b9431d7770290185b7129419c7e63e90611223908390615b5a565b60405180910390a150565b60055460009060ff16156112545760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055611269614dd7565b611272856133ad565b9050600061129b8260c0015183606001516001600160601b0316600254600a5489600754613c12565b9050838110156112bd5760405162461bcd60e51b8152600401610617906155e6565b6112d78260c001516003670de0b6b3a76400008161065a57fe5b8111156112f65760405162461bcd60e51b815260040161061790615761565b6113018633836135c5565b61130f8260c00151826136b4565b6001600160a01b03871660009081526009602052604090206001015561133582876136ed565b6000611348866611c37937e08000613482565b9050866001600160a01b0316336001600160a01b03167fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8460405161138d9190615b5a565b60405180910390a361139f338761387f565b6107a361079e87836136b4565b60055461010090046001600160a01b031633146113db5760405162461bcd60e51b815260040161061790615498565b6006805460ff60a01b1916600160a01b831515021790556040517f40fc85fbff9305015298ba6fcee88b7e442a64cc803ddb889327680bbd62270a9061122390839061545a565b60055460009060ff16156114485760405162461bcd60e51b81526004016106179061573c565b611450614dd7565b506001600160a01b038216600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526114fc5760405162461bcd60e51b81526004016106179061578c565b80602001516115255750506001600160a01b0381166000908152600b6020526040902054611168565b60c0015192915050565b60055460ff16156115525760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff166115885760405162461bcd60e51b8152600401610617906157de565b6000611592610aaa565b905060006115a08583613ce6565b9050806115bf5760405162461bcd60e51b815260040161061790615567565b60085483146115e05760405162461bcd60e51b815260040161061790615885565b60005b83811015611703576000600882815481106115fa57fe5b6000918252602090912001546001600160a01b03169050611619614dd7565b60006116248361389f565b915091506000611638868460c00151613482565b9050806116575760405162461bcd60e51b815260040161061790615567565b88888681811061166357fe5b905060200201358111156116895760405162461bcd60e51b8152600401610617906156e6565b61169d84846116988585613bb2565b613d7a565b836001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a836040516116e09190615b5a565b60405180910390a36116f3843383613bde565b5050600190920191506115e39050565b5061170d85613c09565b6117173386613895565b50506005805460ff19169055505050565b60055460ff161561174b5760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b031633146117885760405162461bcd60e51b815260040161061790615498565b8083146117a75760405162461bcd60e51b815260040161061790615885565b60005b83811015611717576117fc8585838181106117c157fe5b90506020020160208101906117d69190614f3f565b8484848181106117e257fe5b90506020020160208101906117f79190615379565b613f82565b6001016117aa565b60055460009060ff161561182a5760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff166118605760405162461bcd60e51b8152600401610617906157de565b611868614dd7565b60006118738661389f565b9150915084600014156118985760405162461bcd60e51b815260040161061790615a9c565b6118b88260c001516002670de0b6b3a7640000816118b257fe5b04613482565b8511156118d75760405162461bcd60e51b815260040161061790615512565b60006118fe8360c0015184606001516001600160601b0316600254600a548a60075461409f565b9050848110156119205760405162461bcd60e51b8152600401610617906155e6565b61192f8784611698858a613bb2565b866001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a886040516119729190615b5a565b60405180910390a361198381613c09565b61198d3382613895565b611998873388613bde565b6005805460ff191690559695505050505050565b6119b4614dd7565b60055460ff16156119d75760405162461bcd60e51b81526004016106179061573c565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526111685760405162461bcd60e51b81526004016106179061578c565b3360009081526001602090815260408083206001600160a01b038616845290915281205480831115611ad8573360009081526001602090815260408083206001600160a01b0388168452909152812055611b07565b611ae281846136b4565b3360009081526001602090815260408083206001600160a01b03891684529091529020555b3360008181526001602090815260408083206001600160a01b038916808552925291829020549151909291600080516020615c2083398151915291610cc99190615b5a565b60055460009060ff1615611b725760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff16611ba85760405162461bcd60e51b8152600401610617906157de565b611bb0614dd7565b6000611bbb8661389f565b915091506000611be68360c0015184606001516001600160601b0316600254600a548a60075461413b565b905080611c055760405162461bcd60e51b815260040161061790615567565b84811115611c255760405162461bcd60e51b8152600401610617906156e6565b611c3f8360c001516002670de0b6b3a7640000816118b257fe5b811115611c5e5760405162461bcd60e51b815260040161061790615512565b611c6d87846116988585613bb2565b866001600160a01b0316336001600160a01b03167f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a83604051611cb09190615b5a565b60405180910390a3611cc186613c09565b611ccb3387613895565b611998873383613bde565b6001600160a01b031660009081526020819052604090205490565b600554600090819060ff1615611d195760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff16611d4f5760405162461bcd60e51b8152600401610617906157de565b611d57614dd7565b6000611d628961389f565b91509150611d6e614dd7565b611d77886133ad565b9050611d938160c001516003670de0b6b3a76400008161065a57fe5b871115611db25760405162461bcd60e51b815260040161061790615761565b6000611de58460c0015185606001516001600160601b03168460c0015185606001516001600160601b03166007546139ed565b905086811115611e075760405162461bcd60e51b815260040161061790615806565b6000611e3b8560c0015186606001516001600160601b03168560c0015186606001516001600160601b03168d6007546141d5565b90508a811115611e5d5760405162461bcd60e51b8152600401610617906156e6565b611e688c3383613bde565b611e738a338b6135c5565b611e818360c001518a6136b4565b60c084018190526001600160a01b038b16600090815260096020526040902060010155611eae838b6136ed565b611eb88482613bb2565b9350611ec58c8686613d7a565b846020015115611ed75760c085018490525b6000611f0a8660c0015187606001516001600160601b03168660c0015187606001516001600160601b03166007546139ed565b905082811015611f2c5760405162461bcd60e51b815260040161061790615567565b88811115611f4c5760405162461bcd60e51b8152600401610617906158cd565b611f56828b613ce6565b831115611f755760405162461bcd60e51b815260040161061790615567565b8a6001600160a01b03168d6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378858e604051611fc4929190615b63565b60405180910390a46005805460ff19169055909c909b509950505050505050505050565b600181565b600554600090819060ff16156120155760405162461bcd60e51b81526004016106179061573c565b6005805460ff19166001179055600654600160a01b900460ff1661204b5760405162461bcd60e51b8152600401610617906157de565b612053614dd7565b600061205e8961389f565b9150915061206a614dd7565b612073886133ad565b905061208f8360c001516002670de0b6b3a7640000816118b257fe5b8911156120ae5760405162461bcd60e51b815260040161061790615512565b60006120e18460c0015185606001516001600160601b03168460c0015185606001516001600160601b03166007546139ed565b9050868111156121035760405162461bcd60e51b815260040161061790615806565b60006121378560c0015186606001516001600160601b03168560c0015186606001516001600160601b03168f600754614258565b9050888110156121595760405162461bcd60e51b8152600401610617906155e6565b6121648c338d613bde565b61216f8a33836135c5565b61217d8360c00151826136b4565b60c084018190526001600160a01b038b166000908152600960205260409020600101556121aa838b6136ed565b6121b4848c613bb2565b93506121c18c8686613d7a565b8460200151156121d35760c085018490525b60006122068660c0015187606001516001600160601b03168660c0015187606001516001600160601b03166007546139ed565b9050828110156122285760405162461bcd60e51b81526004016106179061553c565b888111156122485760405162461bcd60e51b8152600401610617906158cd565b6122528c83613ce6565b8311156122715760405162461bcd60e51b815260040161061790615567565b8a6001600160a01b03168d6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d433788f86604051611fc4929190615b63565b600c546001600160a01b031690565b60055460ff16156122f25760405162461bcd60e51b81526004016106179061573c565b6005805460ff191660011790556001600160a01b03811660008181526009602052604080822090516370a0823160e01b81529092906370a082319061233b9030906004016153bc565b60206040518083038186803b15801561235357600080fd5b505afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190615317565b825490915060ff161561252c578154610100900460ff16612509576001600160a01b0383166000908152600b6020526040902054808210612507576001600160a01b0384166000818152600b6020526040808220829055855461ff001916610100178655517ff7bb8e57ffdfd9a31e7580ee84f68757f44fb4a8a913f44520d22f2da1c955e59190a2600061242083836136b4565b9050600061242e8284613ce6565b9050600061244d6703782dace9d900006124488185613482565b613bb2565b90506706f05b59d3b200006001600160601b038216111561247357506706f05b59d3b200005b8554600160381b600160981b031916600160381b6001600160601b0383169081029190911766ffffffffff00001916620100004264ffffffffff1602178755600a546124be91613bb2565b600a5585546040516001600160a01b03891691600080516020615c00833981519152916124fb91600160381b90046001600160601b031690615b7f565b60405180910390a25050505b505b6001600160a01b03831660009081526009602052604090206001018190556125a9565b6006546125449084906001600160a01b0316836135c5565b6006546040516360b8257960e11b81526001600160a01b039091169063c1704af29061257690869085906004016153f4565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b505050505b50506005805460ff1916905550565b60055460009060ff16156125de5760405162461bcd60e51b81526004016106179061573c565b6125e6614dd7565b506001600160a01b038216600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526126925760405162461bcd60e51b81526004016106179061578c565b8060200151156126b45760405162461bcd60e51b8152600401610617906158aa565b50506001600160a01b03166000908152600b602052604090205490565b60055461010090046001600160a01b031633146127005760405162461bcd60e51b815260040161061790615498565b6001600160a01b0381166127265760405162461bcd60e51b8152600401610617906159f1565b60058054610100600160a81b0319166101006001600160a01b038416021790556040517f93a5d7f74a690ad8848fb740519ac14bd303a47c6a1bbb2578357b8db0995a2d906112239083906153bc565b60055460009060ff161561279c5760405162461bcd60e51b81526004016106179061573c565b50600a5490565b60055460009060ff16156127c95760405162461bcd60e51b81526004016106179061573c565b6001600160a01b03821660009081526009602052604090205460ff166128015760405162461bcd60e51b81526004016106179061578c565b506001600160a01b0316600090815260096020526040902054600160381b90046001600160601b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109c05780601f10610995576101008083540402835291602001916109c0565b60055460ff16156128b15760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b031633146128ee5760405162461bcd60e51b815260040161061790615498565b6001600160a01b0382166000908152600960205260409020805460ff166129275760405162461bcd60e51b81526004016106179061578c565b8054610100900460ff161561294e5760405162461bcd60e51b8152600401610617906158aa565b80546154606201000090910464ffffffffff16420310156129815760405162461bcd60e51b815260040161061790615ac1565b805466ffffffffff00001916620100004264ffffffffff16021781556001600160a01b0383166000908152600b602052604090819020839055517e0c7a55677231b335e6dea005fa240ac2aeafbd62f188372a7d66892b722c52906129e990859085906153f4565b60405180910390a150506005805460ff1916905550565b6000612a0d338484613ac9565b50600192915050565b60055460ff1615612a395760405162461bcd60e51b81526004016106179061573c565b6005805460ff191660011790556008548114612a675760405162461bcd60e51b815260040161061790615885565b6000612a71610aaa565b90506000612a86856611c37937e08000613482565b90506000612a9486836136b4565b90506000612aa28285613ce6565b905080612ac15760405162461bcd60e51b815260040161061790615567565b612acb338861387f565b600c54612ae1906001600160a01b031684613895565b612aea82613889565b60005b85811015612ccd57600060088281548110612b0457fe5b6000918252602090912001546001600160a01b03169050612b23614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158352610100820481161580159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c0830152612c91576000612bc7858360c00151613482565b905080612be65760405162461bcd60e51b815260040161061790615567565b898985818110612bf257fe5b90506020020135811015612c185760405162461bcd60e51b8152600401610617906155e6565b612c268260c00151826136b4565b6001600160a01b0384166000818152600960205260409081902060010192909255905133907fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed90612c78908590615b5a565b60405180910390a3612c8b8333836135c5565b50612cc3565b888884818110612c9d57fe5b90506020020135600014612cc35760405162461bcd60e51b8152600401610617906157b3565b5050600101612aed565b50506005805460ff19169055505050505050565b60055460ff1615612d045760405162461bcd60e51b81526004016106179061573c565b60058054600160ff19909116179081905561010090046001600160a01b03163314612d415760405162461bcd60e51b815260040161061790615498565b8285148015612d4f57508085145b612d6b5760405162461bcd60e51b815260040161061790615885565b60085460608167ffffffffffffffff81118015612d8757600080fd5b50604051908082528060200260200182016040528015612db1578160200160208202803683370190505b50905060608767ffffffffffffffff81118015612dcd57600080fd5b50604051908082528060200260200182016040528015612e0757816020015b612df4614dd7565b815260200190600190039081612dec5790505b50905060005b88811015612f4257600960008b8b84818110612e2557fe5b9050602002016020810190612e3a9190614f3f565b6001600160a01b031681526020808201929092526040908101600020815160e081018352815460ff808216151583526101008204811615159583019590955264ffffffffff62010000820416938201939093526001600160601b03600160381b840481166060830152600160981b8404166080820152600160f81b90920490921660a082015260019091015460c08201528251839083908110612ed957fe5b6020026020010181905250818181518110612ef057fe5b60200260200101516000015115612f3a57600183838381518110612f1057fe5b602002602001015160a0015160ff1681518110612f2957fe5b911515602092830291909101909101525b600101612e0d565b5060005b83811015612f9857828181518110612f5a57fe5b6020026020010151612f9057612f9060088281548110612f7657fe5b60009182526020822001546001600160a01b031690613f82565b600101612f46565b5060005b888110156130645760008a8a83818110612fb257fe5b9050602002016020810190612fc79190614f3f565b90506000898984818110612fd757fe5b9050602002016020810190612fec9190615379565b90506703782dace9d900006001600160601b038216101561301257506703782dace9d900005b83838151811061301e57fe5b6020026020010151600001516130505761304b8289898681811061303e57fe5b90506020020135836142d9565b61305a565b61305a8282613f82565b5050600101612f9c565b50506005805460ff191690555050505050505050565b60055460609060ff16156130a05760405162461bcd60e51b81526004016106179061573c565b60088054806020026020016040519081016040528092919081815260200182805480156109c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130d8575050505050905090565b60085490565b60055460009060ff161561312b5760405162461bcd60e51b81526004016106179061573c565b5060075490565b3360009081526001602090815260408083206001600160a01b03861684529091528120546131609083613bb2565b3360008181526001602090815260408083206001600160a01b03891680855292529182902084905590519092600080516020615c2083398151915291610a119190615b5a565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009060ff16156131f75760405162461bcd60e51b81526004016106179061573c565b506611c37937e0800090565b60055460009060ff16156132295760405162461bcd60e51b81526004016106179061573c565b6001600160a01b0382166000908152600960205260409020805460ff166132625760405162461bcd60e51b81526004016106179061578c565b6001015492915050565b60055461010090046001600160a01b0316331461329b5760405162461bcd60e51b815260040161061790615498565b6040516317066a5760e21b81526001600160a01b03831690635c19a95c906132c79084906004016153bc565b600060405180830381600087803b1580156132e157600080fd5b505af11580156132f5573d6000803e3d6000fd5b505050505050565b60055461010090046001600160a01b0316331461332c5760405162461bcd60e51b815260040161061790615498565b6001600160a01b0381166133525760405162461bcd60e51b8152600401610617906159f1565b600c80546001600160a01b0319166001600160a01b0383161790556040517fc79e675f96e92542a27382e2c3d22ffc5e7862d51251311f06ca685db3f11ff7906112239083906153bc565b600654600160a01b900460ff1690565b6133b5614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff80821615158084526101008304821615159584019590955264ffffffffff62010000830416958301959095526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490931660a08401526001015460c08301526134615760405162461bcd60e51b81526004016106179061578c565b80602001516111685760405162461bcd60e51b8152600401610617906157b3565b600082820283158061349c57508284828161349957fe5b04145b6134b85760405162461bcd60e51b81526004016106179061585b565b6706f05b59d3b200008101818110156134e35760405162461bcd60e51b81526004016106179061585b565b6000670de0b6b3a7640000825b049695505050505050565b6000806135088786613ce6565b9050600061351e670de0b6b3a7640000836136b4565b9050600061352c8286613482565b9050600061354b87613546670de0b6b3a7640000856136b4565b613ce6565b905060006135598c836136b4565b90506000613567828e613ce6565b9050600061357582886145b8565b90506000613583828e613482565b905060006135918e836136b4565b90506135b081613546670de0b6b3a76400006611c37937e080006136b4565b99505050505050505050509695505050505050565b60006060846001600160a01b031663a9059cbb60e01b85856040516024016135ee9291906153f4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161362c91906153a0565b6000604051808303816000865af19150503d8060008114613669576040519150601f19603f3d011682016040523d82523d6000602084013e61366e565b606091505b509150915081801561369857508051158061369857508080602001905181019061369891906152e3565b610ba45760405162461bcd60e51b815260040161061790615973565b60008060006136c3858561466b565b9150915080156136e55760405162461bcd60e51b81526004016106179061599c565b509392505050565b81608001516001600160601b031682606001516001600160601b031611158061371857508160200151155b806137315750610708826040015164ffffffffff164203105b1561373b5761387b565b6060820151608083015160006137646001600160601b0384166064670de0b6b3a76400006118b2565b90506000613784846001600160601b0316846001600160601b03166136b4565b9050818111156137a7576137a1846001600160601b0316836136b4565b92508190505b6703782dace9d900006001600160601b038416116137e157600a54600093506137d090846136b4565b600a556137dc85614690565b6132f5565b6137ed600a54826136b4565b600a556001600160601b038316606087018190526001600160a01b038616600081815260096020526040908190208054600160381b600160981b031916600160381b9094029390931766ffffffffff00001916620100004264ffffffffff1602179092559051600080516020615c008339815191529061386e908690615b7f565b60405180910390a2505050505b5050565b61387b82826149d2565b613892816149dd565b50565b61387b8282614a86565b6138a7614dd7565b506001600160a01b0381166000908152600960209081526040808320815160e081018352815460ff80821615158084526101008304821615159684019690965264ffffffffff62010000830416948301949094526001600160601b03600160381b820481166060840152600160981b8204166080830152600160f81b900490921660a08301526001015460c082015291906139545760405162461bcd60e51b81526004016106179061578c565b5060c081015160208201516139e8576001600160a01b0383166000908152600b602052604081205460c0840181905261399b9061399190846136b4565b8460c00151613ce6565b905060006139bf600a6004670de0b6b3a76400005b04816139b857fe5b0483613482565b90506139d76004670de0b6b3a76400005b0482613bb2565b6001600160601b0316606085015250505b915091565b6000806139fa8787613ce6565b90506000613a088686613ce6565b90506000613a168383613ce6565b90506000613a38670de0b6b3a7640000613546670de0b6b3a7640000896136b4565b9050613a448282613482565b9a9950505050505050505050565b60035460026000196101006001841615020190911604158015613a755750815115155b8015613a815750805115155b613a9d5760405162461bcd60e51b81526004016106179061570c565b8151613ab0906003906020850190614e13565b508051613ac4906004906020840190614e13565b505050565b6001600160a01b038316600090815260208190526040902054811115613b015760405162461bcd60e51b815260040161061790615636565b6001600160a01b038316600090815260208190526040902054613b2490826136b4565b6001600160a01b038085166000908152602081905260408082209390935590841681522054613b539082613bb2565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613ba5908590615b5a565b60405180910390a3505050565b600082820183811015613bd75760405162461bcd60e51b8152600401610617906159c7565b9392505050565b60006060846001600160a01b03166323b872dd60e01b8530866040516024016135ee939291906153d0565b61389281614a91565b600080613c1f8786613ce6565b90506000613c4585613c40670de0b6b3a76400006611c37937e080006136b4565b613482565b90506000613c5388836136b4565b90506000613c61828a613ce6565b90506000613c8082613c7b670de0b6b3a764000088613ce6565b6145b8565b90506000613c8e828e613482565b90506000613c9c8e836136b4565b90506000613cbb613cb5670de0b6b3a76400008a6136b4565b8b613482565b9050613cd382613c40670de0b6b3a7640000846136b4565b9f9e505050505050505050505050505050565b600081613d055760405162461bcd60e51b81526004016106179061591e565b670de0b6b3a76400008302831580613d2d5750670de0b6b3a7640000848281613d2a57fe5b04145b613d495760405162461bcd60e51b81526004016106179061568d565b60028304810181811015613d6f5760405162461bcd60e51b81526004016106179061568d565b60008482816134f057fe5b8160200151613f55578160c001518110613efe576001600160a01b0383166000818152600b6020908152604080832083905560098252808320805461ff001916610100179055600191860191909152517ff7bb8e57ffdfd9a31e7580ee84f68757f44fb4a8a913f44520d22f2da1c955e59190a26000613dfe828460c001516136b4565b90506000613e10828560c00151613ce6565b9050613e286703782dace9d900006124488184613482565b6001600160601b0316606085018190526706f05b59d3b200001015613e56576706f05b59d3b2000060608501525b6060840180516001600160a01b03871660009081526009602052604090208054600160381b600160981b031916600160381b6001600160601b03938416021766ffffffffff00001916620100004264ffffffffff1602179055600a549151613ebf929116613bb2565b600a5560608401516040516001600160a01b03871691600080516020615c0083398151915291613eef9190615b7f565b60405180910390a25050613f50565b6000613f116139918460c00151846136b4565b90506000613f2a600a6004670de0b6b3a76400006139b0565b9050613f3f6004670de0b6b3a76400006139d0565b6001600160601b0316606085015250505b613f5f565b613f5f8284614b00565b6001600160a01b0390921660009081526009602052604090206001019190915550565b6001600160a01b0382166000908152600960205260409020805460ff16613fbb5760405162461bcd60e51b81526004016106179061578c565b6703782dace9d900006001600160601b038316101580613fe257506001600160601b038216155b613ffe5760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b03831611156140305760405162461bcd60e51b815260040161061790615590565b80546bffffffffffffffffffffffff60981b1916600160981b6001600160601b038416021781556040516001600160a01b038416907fc7ea88f3376e27ce6ebc2025310023327f743a8377d438258c36b166dd8b298390614092908590615b7f565b60405180910390a2505050565b6000806140ac8786613ce6565b905060006140cb6140c5670de0b6b3a7640000846136b4565b85613482565b905060006140e586613c40670de0b6b3a7640000856136b4565b905060006140f38b83613bb2565b90506000614101828d613ce6565b9050600061410f82876145b8565b9050600061411d828d613482565b9050614129818d6136b4565b9e9d5050505050505050505050505050565b6000806141488786613ce6565b905060006141568786613bb2565b905060006141648289613ce6565b9050600061417a670de0b6b3a764000085613ce6565b9050600061418883836145b8565b90506000614196828e613482565b905060006141a4828f6136b4565b905060006141bd613cb5670de0b6b3a76400008a6136b4565b9050613cd382613546670de0b6b3a7640000846136b4565b6000806141e28588613ce6565b905060006141f087866136b4565b905060006141fe8883613ce6565b9050600061420c82856145b8565b905061422081670de0b6b3a76400006136b4565b9050614234670de0b6b3a7640000876136b4565b94506142496142438c83613482565b86613ce6565b9b9a5050505050505050505050565b6000806142658786613ce6565b9050600061427b670de0b6b3a7640000856136b4565b90506142878582613482565b905060006142998a6135468c85613bb2565b905060006142a782856145b8565b905060006142bd670de0b6b3a7640000836136b4565b90506142c98a82613482565b9c9b505050505050505050505050565b6001600160a01b03831660009081526009602052604090205460ff16156143125760405162461bcd60e51b8152600401610617906154c4565b6703782dace9d900006001600160601b03821610156143435760405162461bcd60e51b815260040161061790615833565b68015af1d78b58c400006001600160601b03821611156143755760405162461bcd60e51b815260040161061790615590565b620f42408210156143985760405162461bcd60e51b81526004016106179061560d565b6040518060e001604052806001151581526020016000151581526020014264ffffffffff16815260200160006001600160601b03168152602001826001600160601b0316815260200160088054905060ff168152602001600081525060096000856001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548164ffffffffff021916908364ffffffffff16021790555060608201518160000160076101000a8154816001600160601b0302191690836001600160601b0316021790555060808201518160000160136101000a8154816001600160601b0302191690836001600160601b0316021790555060a082015181600001601f6101000a81548160ff021916908360ff16021790555060c082015181600101559050506008839080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600b6000856001600160a01b03166001600160a01b0316815260200190815260200160002081905550826001600160a01b03167fb2daf560899f6307b318aecfb57eb2812c488da4a4c1cad2019b482fa63294ed8284604051614092929190615b93565b600060018310156145db5760405162461bcd60e51b815260040161061790615944565b671bc16d674ec7ffff8311156146035760405162461bcd60e51b815260040161061790615a6c565b600061460e83614c79565b9050600061461c84836136b4565b905060006146328661462d85614c94565b614ca2565b905081614643579250610a1d915050565b600061465487846305f5e100614cf9565b90506146608282613482565b979650505050505050565b6000808284106146815750508082036000614689565b505081810360015b9250929050565b614698614dd7565b506001600160a01b038116600090815260096020908152604091829020825160e081018452815460ff808216151583526101008204811615159483019490945264ffffffffff62010000820416948201949094526001600160601b03600160381b850481166060830152600160981b8504166080820152600160f81b90930490911660a0830181905260019091015460c08301819052600854909190600019018082146147f6576008818154811061474c57fe5b600091825260209091200154600880546001600160a01b03909216918490811061477257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160096000600885815481106147b257fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020805460ff92909216600160f81b026001600160f81b039092169190911790555b600880548061480157fe5b60008281526020808220600019908401810180546001600160a01b03191690559092019092556040805160e081018252838152808301848152818301858152606083018681526080840187815260a0850188815260c086018981526001600160a01b038f81168b52600990995296909820945185549451935192519151985160ff199095169015151761ff001916610100931515939093029290921766ffffffffff000019166201000064ffffffffff9092169190910217600160381b600160981b031916600160381b6001600160601b0392831602176bffffffffffffffffffffffff60981b1916600160981b9190961602949094176001600160f81b0316600160f81b60ff90951694909402939093178355516001929092019190915560065461493091879116856135c5565b6006546040516360b8257960e11b81526001600160a01b039091169063c1704af29061496290889087906004016153f4565b600060405180830381600087803b15801561497c57600080fd5b505af1158015614990573d6000803e3d6000fd5b505050507f12a8262eb28ee8a8c11e6cf411b3af6ce5bea42abb36e051bf0a65ae602d52ec856040516149c391906153bc565b60405180910390a15050505050565b61387b823083613ac9565b30600090815260208190526040902054811115614a0c5760405162461bcd60e51b815260040161061790615636565b30600090815260208190526040902054614a2690826136b4565b30600090815260208190526040902055600254614a4390826136b4565b60025560405160009030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90614a7b908590615b5a565b60405180910390a350565b61387b308383613ac9565b30600090815260208190526040902054614aab9082613bb2565b30600090815260208190526040902055600254614ac89082613bb2565b60025560405130906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90614a7b908590615b5a565b81608001516001600160601b031682606001516001600160601b0316101580614b2b57508160200151155b80614b445750610708826040015164ffffffffff164203105b15614b4e5761387b565b606082015160808301516000614b776001600160601b0384166064670de0b6b3a76400006118b2565b90506000614b97836001600160601b0316856001600160601b03166136b4565b905081811115614bba57614bb4846001600160601b031683613bb2565b92508190505b6000614bc8600a5483613bb2565b9050680176b344f2a78c0000811115614be557505050505061387b565b600a8190556001600160601b038416606088018190526001600160a01b038716600081815260096020526040908190208054600160381b600160981b031916600160381b9094029390931766ffffffffff00001916620100004264ffffffffff1602179092559051600080516020615c0083398151915290614c68908790615b7f565b60405180910390a250505050505050565b6000670de0b6b3a7640000614c8d83614c94565b0292915050565b670de0b6b3a7640000900490565b60008060028306614cbb57670de0b6b3a7640000614cbd565b835b90506002830492505b8215613bd757614cd68485613482565b93506002830615614cee57614ceb8185613482565b90505b600283049250614cc6565b6000828180614d1087670de0b6b3a764000061466b565b9092509050670de0b6b3a764000080600060015b888410614dc8576000670de0b6b3a764000082029050600080614d588a614d5385670de0b6b3a76400006136b4565b61466b565b91509150614d6a87613c40848c613482565b9650614d768784613ce6565b965086614d8557505050614dc8565b8715614d8f579315935b8015614d99579315935b8415614db057614da986886136b4565b9550614dbd565b614dba8688613bb2565b95505b505050600101614d24565b50909998505050505050505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614e5457805160ff1916838001178555614e81565b82800160010185558215614e81579182015b82811115614e81578251825591602001919060010190614e66565b50614e8d929150614e91565b5090565b5b80821115614e8d5760008155600101614e92565b80356001600160a01b0381168114610a1d57600080fd5b60008083601f840112614ece578182fd5b50813567ffffffffffffffff811115614ee5578182fd5b602083019150836020808302850101111561468957600080fd5b60008083601f840112614f10578182fd5b50813567ffffffffffffffff811115614f27578182fd5b60208301915083602082850101111561468957600080fd5b600060208284031215614f50578081fd5b613bd78383614ea6565b60008060408385031215614f6c578081fd5b614f768484614ea6565b9150614f858460208501614ea6565b90509250929050565b600080600060608486031215614fa2578081fd5b8335614fad81615bdc565b92506020840135614fbd81615bdc565b929592945050506040919091013590565b600080600080600060608688031215614fe5578081fd5b8535614ff081615bdc565b9450602086013567ffffffffffffffff8082111561500c578283fd5b61501889838a01614eff565b90965094506040880135915080821115615030578283fd5b5061503d88828901614eff565b969995985093965092949392505050565b60008060408385031215615060578182fd5b61506a8484614ea6565b946020939093013593505050565b600080600080600060a0868803121561508f578081fd5b6150998787614ea6565b9450602086013593506150af8760408801614ea6565b94979396509394606081013594506080013592915050565b6000806000606084860312156150db578283fd5b6150e58585614ea6565b95602085013595506040909401359392505050565b600080600080600080600080600060c08a8c031215615117578384fd5b893567ffffffffffffffff8082111561512e578586fd5b61513a8d838e01614ebd565b909b50995060208c0135915080821115615152578586fd5b61515e8d838e01614ebd565b909950975060408c0135915080821115615176578586fd5b506151838c828d01614ebd565b90965094505060608a013561519781615bdc565b925060808a01356151a781615bdc565b915060a08a01356151b781615bdc565b809150509295985092959850929598565b600080600080604085870312156151dd578384fd5b843567ffffffffffffffff808211156151f4578586fd5b61520088838901614ebd565b90965094506020870135915080821115615218578384fd5b5061522587828801614ebd565b95989497509550505050565b60008060008060008060608789031215615249578384fd5b863567ffffffffffffffff80821115615260578586fd5b61526c8a838b01614ebd565b90985096506020890135915080821115615284578586fd5b6152908a838b01614ebd565b909650945060408901359150808211156152a8578384fd5b506152b589828a01614ebd565b979a9699509497509295939492505050565b6000602082840312156152d8578081fd5b8135613bd781615bf1565b6000602082840312156152f4578081fd5b8151613bd781615bf1565b600060208284031215615310578081fd5b5035919050565b600060208284031215615328578081fd5b5051919050565b600080600060408486031215615343578081fd5b83359250602084013567ffffffffffffffff811115615360578182fd5b61536c86828701614ebd565b9497909650939450505050565b60006020828403121561538a578081fd5b81356001600160601b0381168114613bd7578182fd5b600082516153b2818460208701615bac565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561544e5783516001600160a01b031683529284019291840191600101615429565b50909695505050505050565b901515815260200190565b6000602082528251806020840152615484816040850160208701615bac565b601f01601f19169190910160400192915050565b60208082526012908201527122a9292fa727aa2fa1a7a72a2927a62622a960711b604082015260600190565b6020808252600c908201526b11549497d254d7d093d5539160a21b604082015260600190565b6020808252600e908201526d4552525f4d41585f544f4b454e5360901b604082015260600190565b60208082526010908201526f4552525f4d41585f494e5f524154494f60801b604082015260600190565b60208082526011908201527022a9292fa6a0aa242fa0a8282927ac2f9960791b604082015260600190565b6020808252600f908201526e08aa4a4be9a82a890be82a0a0a49eb608b1b604082015260600190565b6020808252600e908201526d11549497d3505617d5d15251d21560921b604082015260600190565b60208082526014908201527311549497d3505617d513d5105317d5d15251d21560621b604082015260600190565b6020808252600d908201526c11549497d31253525517d3d555609a1b604082015260600190565b6020808252600f908201526e4552525f4d494e5f42414c414e434560881b604082015260600190565b60208082526014908201527311549497d25394d551919250d251539517d0905360621b604082015260600190565b6020808252600f908201526e11549497d253925512505312569151608a1b604082015260600190565b60208082526010908201526f11549497d1125597d25395115493905360821b604082015260600190565b60208082526015908201527422a9292fa12a27a5a2a72fa120a22fa1a0a62622a960591b604082015260600190565b6020808252600c908201526b22a9292fa624a6a4aa2fa4a760a11b604082015260600190565b60208082526016908201527511549497d09513d2d15397d25392551250531256915160521b604082015260600190565b6020808252600b908201526a4552525f5245454e54525960a81b604082015260600190565b6020808252601190820152704552525f4d41585f4f55545f524154494f60781b604082015260600190565b6020808252600d908201526c11549497d393d517d093d55391609a1b604082015260600190565b6020808252601190820152704552525f4f55545f4e4f545f524541445960781b604082015260600190565b6020808252600e908201526d4552525f4e4f545f5055424c494360901b604082015260600190565b6020808252601390820152724552525f4241445f4c494d49545f505249434560681b604082015260600190565b6020808252600e908201526d11549497d3525397d5d15251d21560921b604082015260600190565b60208082526010908201526f4552525f4d554c5f4f564552464c4f5760801b604082015260600190565b6020808252600b908201526a22a9292fa0a9292fa622a760a91b604082015260600190565b6020808252600990820152684552525f524541445960b81b604082015260600190565b6020808252600f908201526e4552525f4c494d49545f505249434560881b604082015260600190565b6020808252600e908201526d11549497d0d3d3919251d554915160921b604082015260600190565b6020808252600c908201526b4552525f4449565f5a45524f60a01b604082015260600190565b6020808252601590820152744552525f42504f575f424153455f544f4f5f4c4f5760581b604082015260600190565b6020808252600f908201526e4552525f45524332305f46414c534560881b604082015260600190565b6020808252601190820152704552525f5355425f554e444552464c4f5760781b604082015260600190565b60208082526010908201526f4552525f4144445f4f564552464c4f5760801b604082015260600190565b60208082526010908201526f4552525f4e554c4c5f4144445245535360801b604082015260600190565b6020808252600f908201526e4552525f494e56414c49445f46454560881b604082015260600190565b6020808252600e908201526d4552525f4d494e5f544f4b454e5360901b604082015260600190565b60208082526016908201527508aa4a4be84a09eaebe8482a68abea89e9ebe90928e960531b604082015260600190565b6020808252600b908201526a22a9292fad22a927afa4a760a91b604082015260600190565b6020808252601490820152734d494e5f42414c5f5550444154455f44454c415960601b604082015260600190565b600060e08201905082511515825260208301511515602083015264ffffffffff604084015116604083015260608301516001600160601b038082166060850152806080860151166080850152505060ff60a08401511660a083015260c083015160c083015292915050565b90815260200190565b918252602082015260400190565b60ff91909116815260200190565b6001600160601b0391909116815260200190565b6001600160601b03929092168252602082015260400190565b60005b83811015615bc7578181015183820152602001615baf565b83811115615bd6576000848401525b50505050565b6001600160a01b038116811461389257600080fd5b801515811461389257600080fdfe21b12aed5d425f5675450ffeeae01039085e5323974c3099e1828155d9b51e778c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a2646970667358221220e82b157d45f4e522ea20b9bb4c0f872a13392a53a155ce16660632cb1b4c4bf464736f6c634300060c0033
Deployed Bytecode Sourcemap
804:41516:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18741:1125;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28216:475;;;:::i;:::-;;;;;;;:::i;3098:104:3:-;;;:::i;:::-;;;;;;;:::i;3777:178::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;30764:412:4:-;;;;;;:::i;:::-;;:::i;3681:92:3:-;;;:::i;2554:358:4:-;;;;;;:::i;:::-;;:::i;:::-;;4696:495:3;;;;;;:::i;:::-;;:::i;3484:1584:4:-;;;;;;:::i;:::-;;:::i;27588:101::-;;;;;;:::i;:::-;;:::i;27210:95::-;;;:::i;:::-;;;;;;;:::i;3318:103:3:-;;;:::i;:::-;;;;;;;:::i;5164:208:4:-;;;;;;:::i;:::-;;:::i;17123:1070::-;;;;;;:::i;:::-;;:::i;6364:140::-;;;;;;:::i;:::-;;:::i;30353:280::-;;;;;;:::i;:::-;;:::i;10850:931::-;;;;;;:::i;:::-;;:::i;6993:325::-;;;;;;:::i;:::-;;:::i;12289:1000::-;;;;;;:::i;:::-;;:::i;29068:205::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4200:356:3:-;;;;;;:::i;:::-;;:::i;13771:991:4:-;;;;;;:::i;:::-;;:::i;3571:106:3:-;;;;;;:::i;:::-;;:::i;24454:2244:4:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;565:42:0:-;;;:::i;21735:2172:4:-;;;;;;:::i;:::-;;:::i;27371:107::-;;;:::i;20063:1122::-;;;;;;:::i;:::-;;:::i;29891:264::-;;;;;;:::i;:::-;;:::i;5426:210::-;;;;;;:::i;:::-;;:::i;29346:142::-;;;:::i;28767:225::-;;;;;;:::i;:::-;;:::i;3206:108:3:-;;;:::i;9748:508:4:-;;;;;;:::i;:::-;;:::i;4560:132:3:-;;;;;;:::i;:::-;;:::i;15306:1249:4:-;;;;;;:::i;:::-;;:::i;7755:1731::-;;;;;;:::i;:::-;;:::i;27904:145::-;;;:::i;27759:97::-;;;:::i;26922:113::-;;;:::i;3959:237:3:-;;;;;;:::i;:::-;;:::i;3425:142::-;;;;;;:::i;:::-;;:::i;27039:113:4:-;;;:::i;29559:208::-;;;;;;:::i;:::-;;:::i;5748:159::-;;;;;;:::i;:::-;;:::i;5969:254::-;;;;;;:::i;:::-;;:::i;26827:91::-;;;:::i;18741:1125::-;935:6;;18907:7;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;;;;;;;;;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;18942:23:::1;;:::i;:::-;18968:25;18984:8;18968:15;:25::i;:::-;18942:51;;19032:38;19037:9;:17;;;2556:1:0;1260:6;2549:8;;;;;;2561:5;2548:18;19032:4:4;:38::i;:::-;19014:14;:56;;18999:104;;;;-1:-1:-1::0;;;18999:104:4::1;;;;;;;:::i;:::-;19110:20;19133:157;19165:9;:17;;;19190:9;:16;;;-1:-1:-1::0;;;;;19133:157:4::1;19214:12;;19234;;19254:14;19276:8;;19133:24;:157::i;:::-;19110:180:::0;-1:-1:-1;19305:17:4;19297:45:::1;;;;-1:-1:-1::0;;;19297:45:4::1;;;;;;;:::i;:::-;19372:15;19356:12;:31;;19348:56;;;;-1:-1:-1::0;;;19348:56:4::1;;;;;;;:::i;:::-;19411:53;19427:8;19437:10;19449:14;19411:15;:53::i;:::-;19499:39;19504:9;:17;;;19523:14;19499:4;:39::i;:::-;-1:-1:-1::0;;;;;19470:18:4;::::1;;::::0;;;:8:::1;:18;::::0;;;;:26:::1;;:68:::0;19544:36:::1;19560:9:::0;19479:8;19544:15:::1;:36::i;:::-;19587:15;19605:28;19610:12;1587:4:0;19605::4;:28::i;:::-;19587:46;;19666:8;-1:-1:-1::0;;;;;19645:46:4::1;19654:10;-1:-1:-1::0;;;;;19645:46:4::1;;19676:14;19645:46;;;;;;:::i;:::-;;;;;;;;19698:40;19713:10;19725:12;19698:14;:40::i;:::-;19744:43;19759:27;19764:12;19778:7;19759:4;:27::i;:::-;19744:14;:43::i;:::-;19808:17;::::0;19793:42:::1;::::0;-1:-1:-1;;;;;19808:17:4::1;19827:7:::0;19793:14:::1;:42::i;:::-;-1:-1:-1::0;989:6:4;:14;;-1:-1:-1;;989:14:4;;;19849:12;18741:1125;-1:-1:-1;;;;;18741:1125:4:o;28216:475::-;1049:6;;28314:23;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;28347:27:::1;28377:7;28347:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;28347:37:4::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;28413:10;:17;28399:32;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;28399:32:4::1;;28390:41;;28437:17;28469:9:::0;28464:180:::1;28488:6;:13;28484:1;:17;28464:180;;;28516:13;28532:10;28543:1;28532:13;;;;;;;;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;28557:15:4;::::1;28589:1;28557:15:::0;;;:8:::1;:15:::0;;;;;;;:29;28532:13;;-1:-1:-1;;;;28557:29:4;::::1;-1:-1:-1::0;;;;;28557:29:4::1;:33:::0;28553:85:::1;;28624:5;28602:6;28609:11;;;;;;28602:19;;;;;;;;;;;;;:27;-1:-1:-1::0;;;;;28602:27:4::1;;;-1:-1:-1::0;;;;;28602:27:4::1;;;::::0;::::1;28553:85;-1:-1:-1::0;28503:3:4::1;;28464:180;;;-1:-1:-1::0;28660:25:4;;-1:-1:-1;28667:6:4;28216:475::o;3098:104:3:-;3192:5;3185:12;;;;;;;;-1:-1:-1;;3185:12:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3162:13;;3185:12;;3192:5;;3185:12;;3192:5;3185:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3098:104;:::o;3777:178::-;3870:10;3847:4;3859:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;3859:27:3;;;;;;;;;;:33;;;3903:30;3847:4;;3859:27;;-1:-1:-1;;;;;;;;;;;3903:30:3;;;3889:3;;3903:30;:::i;:::-;;;;;;;;-1:-1:-1;3946:4:3;3777:178;;;;;:::o;30764:412:4:-;1049:6;;30884:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;30902:22:::1;;:::i;:::-;30929:23;30944:7;30929:14;:23::i;:::-;30901:51;;;30958:23;;:::i;:::-;30984:25;31000:8;30984:15;:25::i;:::-;30958:51;;31028:143;31051:8;:16;;;31077:8;:15;;;-1:-1:-1::0;;;;;31028:143:4::1;31102:9;:17;;;31129:9;:16;;;-1:-1:-1::0;;;;;31028:143:4::1;31155:8;;31028:13;:143::i;:::-;31015:156:::0;30764:412;-1:-1:-1;;;;;30764:412:4:o;3681:92:3:-;3756:12;;3681:92;:::o;2554:358:4:-;2687:11;;;;;-1:-1:-1;;;;;2687:11:4;:25;2679:52;;;;-1:-1:-1;;;2679:52:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;2745:24:4;;2737:53;;;;-1:-1:-1;;;2737:53:4;;;;;;;:::i;:::-;2796:11;:24;;-1:-1:-1;;;;;;2796:24:4;;-1:-1:-1;;;;;2796:24:4;;;;;;2869:2;1260:6:0;2862:9:4;2851:8;:20;2877:30;;;;;;;;;;;;;;;;;;;;;;;;2894:4;;;;;;2877:30;;2894:4;;;;2877:30;;;;;;;;;-1:-1:-1;;2877:30:4;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2900:6:4;;-1:-1:-1;2900:6:4;;;;2877:30;;2900:6;;;;2877:30;;;;;;;;;-1:-1:-1;2877:16:4;;-1:-1:-1;;;2877:30:4:i;:::-;2554:358;;;;;:::o;4696:495:3:-;4800:4;4827:10;-1:-1:-1;;;;;4827:17:3;;;;:55;;-1:-1:-1;;;;;;4855:15:3;;;;;;:10;:15;;;;;;;;4871:10;4855:27;;;;;;;;4848:34;;;4827:55;4812:107;;;;-1:-1:-1;;;4812:107:3;;;;;;;:::i;:::-;4925:20;4931:3;4936;4941;4925:5;:20::i;:::-;4955:10;-1:-1:-1;;;;;4955:17:3;;;;;;:63;;-1:-1:-1;;;;;;4976:15:3;;;;;;:10;:15;;;;;;;;4992:10;4976:27;;;;;;;;-1:-1:-1;;4976:42:3;;4955:63;4951:219;;;-1:-1:-1;;;;;5063:15:3;;;;;;:10;:15;;;;;;;;5079:10;5063:27;;;;;;;;5058:38;;5092:3;5058:4;:38::i;:::-;-1:-1:-1;;;;;5028:15:3;;;;;;;:10;:15;;;;;;;;5044:10;5028:27;;;;;;;;;:68;;;5109:54;;;;;;5044:10;;-1:-1:-1;;;;;;;;;;;5109:54:3;;;;:::i;:::-;;;;;;;;4951:219;-1:-1:-1;5182:4:3;4696:495;;;;;:::o;3484:1584:4:-;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;3743:7:::1;:14:::0;:19;3735:47:::1;;;;-1:-1:-1::0;;;3735:47:4::1;;;;;;;:::i;:::-;3802:6:::0;1316:1:0::1;3829:23:4::0;::::1;;3821:50;;;;-1:-1:-1::0;;;3821:50:4::1;;;;;;;:::i;:::-;1366:2:0;3885:3:4;:23;;3877:50;;;;-1:-1:-1::0;;;3877:50:4::1;;;;;;;:::i;:::-;3941:22:::0;;::::1;:47:::0;::::1;;;-1:-1:-1::0;3967:21:4;;::::1;3941:47;3933:71;;;;-1:-1:-1::0;;;3933:71:4::1;;;;;;;:::i;:::-;4010:19;4044:9:::0;4039:670:::1;4063:3;4059:1;:7;4039:670;;;4081:13;4097:6;;4104:1;4097:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;4081:25;;4114:13;4130:7;;4138:1;4130:10;;;;;;;;;;;;;;;;;;;;:::i;:::-;4114:26;;4148:15;4166:8;;4175:1;4166:11;;;;;;;;;;;;;4148:29;;1816:1:0;1260:6;1809:8;;;;;;4193:6:4;-1:-1:-1::0;;;;;4193:20:4::1;;;4185:47;;;;-1:-1:-1::0;;;4185:47:4::1;;;;;;;:::i;:::-;1860:9:0::0;-1:-1:-1;;;;;4248:20:4;::::1;;;4240:47;;;;-1:-1:-1::0;;;4240:47:4::1;;;;;;;:::i;:::-;2060:13:0::0;4303:22:4;::::1;;4295:50;;;;-1:-1:-1::0;;;4295:50:4::1;;;;;;;:::i;:::-;4371:203;;;;;;;;4395:4;4371:203;;;;;;4416:4;4371:203;;;;;;4455:3;4371:203;;;;;;4477:6;-1:-1:-1::0;;;;;4371:203:4::1;;;;;4508:6;-1:-1:-1::0;;;;;4371:203:4::1;;;;;4537:1;4371:203;;;;;;4558:7;4371:203;;::::0;4353:8:::1;:15;4362:5;-1:-1:-1::0;;;;;4353:15:4::1;-1:-1:-1::0;;;;;4353:15:4::1;;;;;;;;;;;;:221;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4353:221:4::1;;;;;-1:-1:-1::0;;;;;4353:221:4::1;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4353:221:4::1;;;;;-1:-1:-1::0;;;;;4353:221:4::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4582:7;4595:5;4582:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4582:19:4::1;;;;;-1:-1:-1::0;;;;;4582:19:4::1;;;;;;4623:25;4628:11;4641:6;-1:-1:-1::0;;;;;4623:25:4::1;:4;:25::i;:::-;4609:39;;4656:46;4672:5;4679:13;4694:7;4656:15;:46::i;:::-;-1:-1:-1::0;;;4068:3:4::1;;4039:670;;;;1945:5:0;4722:11:4;:31;;4714:64;;;;-1:-1:-1::0;;;4714:64:4::1;;;;;;;:::i;:::-;4784:12;:26:::0;;;4816:11:::1;:18:::0;;-1:-1:-1;;;;4816:18:4::1;-1:-1:-1::0;;;4816:18:4::1;::::0;;4845:29:::1;::::0;::::1;::::0;::::1;::::0;4830:4:::1;::::0;4845:29:::1;:::i;:::-;;;;;;;;4880:32;2147:10:0::0;4880:14:4::1;:32::i;:::-;4918:47;4933:13:::0;2147:10:0;4918:14:4::1;:47::i;:::-;-1:-1:-1::0;;4971:14:4::1;:50:::0;;-1:-1:-1;;;;;4971:50:4;;::::1;-1:-1:-1::0;;;;;;4971:50:4;;::::1;;::::0;;;5027:17:::1;:36:::0;;;;;::::1;::::0;::::1;;::::0;;-1:-1:-1;;;;;;;3484:1584:4:o;27588:101::-;-1:-1:-1;;;;;27667:11:4;;27648:4;27667:11;;;:8;:11;;;;;:17;;;27588:101;;;;:::o;27210:95::-;27289:11;;;;;-1:-1:-1;;;;;27289:11:4;;27210:95::o;3318:103:3:-;2764:2;3318:103;:::o;5164:208:4:-;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;1432:12:0;5243:18:4;::::1;::::0;::::1;::::0;:40:::1;;-1:-1:-1::0;1515:9:0;5265:18:4;::::1;;5243:40;5235:68;;;;-1:-1:-1::0;;;5235:68:4::1;;;;;;;:::i;:::-;5309:8;:18:::0;;;5338:29:::1;::::0;::::1;::::0;::::1;::::0;5320:7;;5338:29:::1;:::i;:::-;;;;;;;;5164:208:::0;:::o;17123:1070::-;935:6;;17281:7;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;17318:23:::1;;:::i;:::-;17344:25;17360:8;17344:15;:25::i;:::-;17318:51;;17376:22;17401:155;17433:9;:17;;;17458:9;:16;;;-1:-1:-1::0;;;;;17401:155:4::1;17482:12;;17502;;17522;17542:8;;17401:24;:155::i;:::-;17376:180;;17589:12;17571:14;:30;;17563:56;;;;-1:-1:-1::0;;;17563:56:4::1;;;;;;;:::i;:::-;17659:38;17664:9;:17;;;2556:1:0;1260:6;2549:8;;;;17659:38:4;17641:14;:56;;17626:104;;;;-1:-1:-1::0;;;17626:104:4::1;;;;;;;:::i;:::-;17737:53;17753:8;17763:10;17775:14;17737:15;:53::i;:::-;17825:39;17830:9;:17;;;17849:14;17825:4;:39::i;:::-;-1:-1:-1::0;;;;;17796:18:4;::::1;;::::0;;;:8:::1;:18;::::0;;;;:26:::1;;:68:::0;17870:36:::1;17886:9:::0;17805:8;17870:15:::1;:36::i;:::-;17912:15;17930:28;17935:12;1587:4:0;17930::4;:28::i;:::-;17912:46;;17991:8;-1:-1:-1::0;;;;;17970:46:4::1;17979:10;-1:-1:-1::0;;;;;17970:46:4::1;;18001:14;17970:46;;;;;;:::i;:::-;;;;;;;;18023:40;18038:10;18050:12;18023:14;:40::i;:::-;18069:43;18084:27;18089:12;18103:7;18084:4;:27::i;6364:140::-:0;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;6435:11:::1;:21:::0;;-1:-1:-1;;;;6435:21:4::1;-1:-1:-1::0;;;6435:21:4;::::1;;;;::::0;;6467:32:::1;::::0;::::1;::::0;::::1;::::0;6435:21;;6467:32:::1;:::i;30353:280::-:0;1049:6;;30435:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;30450:20:::1;;:::i;:::-;-1:-1:-1::0;;;;;;30473:15:4;::::1;;::::0;;;:8:::1;:15;::::0;;;;;;;;30450:38;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;;::::0;;;::::1;::::0;::::1;::::0;::::1;;;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;;;;;;;-1:-1:-1;;;;;;;;30450:38:4;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;30450:38:4;::::1;;::::0;;;;-1:-1:-1;;;30450:38:4;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;30494::::1;;;;-1:-1:-1::0;;;30494:38:4::1;;;;;;;:::i;:::-;30543:6;:12;;;30538:64;;-1:-1:-1::0;;;;;;;30572:23:4;::::1;;::::0;;;:16:::1;:23;::::0;;;;;30565:30:::1;;30538:64;30614:14;;::::0;;30353:280;-1:-1:-1;;30353:280:4:o;10850:931::-;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;1216:11:::1;::::0;-1:-1:-1;;;1216:11:4;::::1;963:13:::0;1216:11:::1;1208:38;;;;-1:-1:-1::0;;;1208:38:4::1;;;;;;;:::i;:::-;10982:17:::2;11002:13;:11;:13::i;:::-;10982:33;;11021:13;11037:30;11042:13;11057:9;11037:4;:30::i;:::-;11021:46:::0;-1:-1:-1;11081:10:4;11073:38:::2;;;;-1:-1:-1::0;;;11073:38:4::2;;;;;;;:::i;:::-;11148:7;:14:::0;11125:37;::::2;11117:61;;;;-1:-1:-1::0;;;11117:61:4::2;;;;;;;:::i;:::-;11190:9;11185:510;11205:23:::0;;::::2;11185:510;;;11243:9;11255:7;11263:1;11255:10;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;11255:10:4::2;::::0;-1:-1:-1;11274:20:4::2;;:::i;:::-;11296:19;11319:17;11334:1;11319:14;:17::i;:::-;11273:63;;;;11344:21;11368:27;11373:5;11380:6;:14;;;11368:4;:27::i;:::-;11344:51:::0;-1:-1:-1;11411:18:4;11403:46:::2;;;;-1:-1:-1::0;;;11403:46:4::2;;;;;;;:::i;:::-;11482:12;;11495:1;11482:15;;;;;;;;;;;;;11465:13;:32;;11457:57;;;;-1:-1:-1::0;;;11457:57:4::2;;;;;;;:::i;:::-;11522:62;11540:1;11543:6;11551:32;11556:11;11569:13;11551:4;:32::i;:::-;11522:17;:62::i;:::-;11618:1;-1:-1:-1::0;;;;;11597:38:4::2;11606:10;-1:-1:-1::0;;;;;11597:38:4::2;;11621:13;11597:38;;;;;;:::i;:::-;;;;;;;;11643:45;11659:1;11662:10;11674:13;11643:15;:45::i;:::-;-1:-1:-1::0;;11230:3:4::2;::::0;;::::2;::::0;-1:-1:-1;11185:510:4::2;::::0;-1:-1:-1;11185:510:4::2;;;11700:29;11715:13;11700:14;:29::i;:::-;11735:41;11750:10;11762:13;11735:14;:41::i;:::-;-1:-1:-1::0;;989:6:4;:14;;-1:-1:-1;;989:14:4;;;-1:-1:-1;;;10850:931:4:o;6993:325::-;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;972:4;-1:-1:-1;;963:13:4;;;;;;;;;1134:11;::::1;-1:-1:-1::0;;;;;1134:11:4::1;1120:10;:25;1112:56;;;;-1:-1:-1::0;;;1112:56:4::1;;;;;;;:::i;:::-;7156:38:::0;;::::2;7148:62;;;;-1:-1:-1::0;;;7148:62:4::2;;;;;;;:::i;:::-;7221:9;7216:97;7236:17:::0;;::::2;7216:97;;;7266:47;7284:6;;7291:1;7284:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;7295:14;;7310:1;7295:17;;;;;;;;;;;;;;;;;;;;:::i;:::-;7266;:47::i;:::-;7255:3;;7216:97;;12289:1000:::0;935:6;;12466:7;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;1216:11:::1;::::0;-1:-1:-1;;;1216:11:4;::::1;963:13:::0;1216:11:::1;1208:38;;;;-1:-1:-1::0;;;1208:38:4::1;;;;;;;:::i;:::-;12503:22:::2;;:::i;:::-;12527:21;12552:23;12567:7;12552:14;:23::i;:::-;12502:73;;;;12590:13;12607:1;12590:18;;12582:42;;;;-1:-1:-1::0;;;12582:42:4::2;;;;;;;:::i;:::-;12663:36;12668:8;:16;;;2443:1:0;1260:6;2436:8;;;;;;12663:4:4;:36::i;:::-;12646:13;:53;;12631:100;;;;-1:-1:-1::0;;;12631:100:4::2;;;;;;;:::i;:::-;12738:21;12762:154;12794:8;:16;;;12818:8;:15;;;-1:-1:-1::0;;;;;12762:154:4::2;12841:12;;12861;;12881:13;12902:8;;12762:24;:154::i;:::-;12738:178;;12948:16;12931:13;:33;;12923:59;;;;-1:-1:-1::0;;;12923:59:4::2;;;;;;;:::i;:::-;12989:72;13007:7;13016:8;13026:34;13031:13;13046;13026:4;:34::i;12989:72::-;13094:7;-1:-1:-1::0;;;;;13073:44:4::2;13082:10;-1:-1:-1::0;;;;;13073:44:4::2;;13103:13;13073:44;;;;;;:::i;:::-;;;;;;;;13124:29;13139:13;13124:14;:29::i;:::-;13159:41;13174:10;13186:13;13159:14;:41::i;:::-;13206:51;13222:7;13231:10;13243:13;13206:15;:51::i;:::-;989:6:::0;:14;;-1:-1:-1;;989:14:4;;;13271:13;12289:1000;-1:-1:-1;;;;;;12289:1000:4:o;29068:205::-;29170:20;;:::i;:::-;1049:6;;;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;;29209:15:4;::::1;;::::0;;;:8:::1;:15;::::0;;;;;;;;29200:24;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;;::::0;;;::::1;::::0;::::1;::::0;::::1;;;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;;;;;;;-1:-1:-1;;;;;;;;29200:24:4;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;29200:24:4;::::1;;::::0;;;;-1:-1:-1;;;29200:24:4;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;29230:38:::1;;;;-1:-1:-1::0;;;29230:38:4::1;;;;;;;:::i;4200:356:3:-:0;4312:10;4270:4;4301:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4301:27:3;;;;;;;;;;4338:14;;;4334:136;;;4373:10;4392:1;4362:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4362:27:3;;;;;;;;;:31;4334:136;;;4444:19;4449:8;4459:3;4444:4;:19::i;:::-;4425:10;4414:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4414:27:3;;;;;;;;;:49;4334:136;4489:10;4506:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4480:54:3;;4506:27;;;;;;;;;;4480:54;;;;4489:10;-1:-1:-1;;;;;;;;;;;4480:54:3;;;4506:27;4480:54;:::i;13771:991:4:-;935:6;;13942:7;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;1216:11:::1;::::0;-1:-1:-1;;;1216:11:4;::::1;963:13:::0;1216:11:::1;1208:38;;;;-1:-1:-1::0;;;1208:38:4::1;;;;;;;:::i;:::-;13979:22:::2;;:::i;:::-;14003:21;14028:23;14043:7;14028:14;:23::i;:::-;13978:73;;;;14058:21;14082:154;14114:8;:16;;;14138:8;:15;;;-1:-1:-1::0;;;;;14082:154:4::2;14161:12;;14181;;14201:13;14222:8;;14082:24;:154::i;:::-;14058:178:::0;-1:-1:-1;14251:18:4;14243:46:::2;;;;-1:-1:-1::0;;;14243:46:4::2;;;;;;;:::i;:::-;14320:11;14303:13;:28;;14295:53;;;;-1:-1:-1::0;;;14295:53:4::2;;;;;;;:::i;:::-;14387:36;14392:8;:16;;;2443:1:0;1260:6;2436:8;;;;14387:36:4;14370:13;:53;;14355:100;;;;-1:-1:-1::0;;;14355:100:4::2;;;;;;;:::i;:::-;14462:72;14480:7;14489:8;14499:34;14504:13;14519;14499:4;:34::i;14462:72::-;14567:7;-1:-1:-1::0;;;;;14546:44:4::2;14555:10;-1:-1:-1::0;;;;;14546:44:4::2;;14576:13;14546:44;;;;;;:::i;:::-;;;;;;;;14597:29;14612:13;14597:14;:29::i;:::-;14632:41;14647:10;14659:13;14632:14;:41::i;:::-;14679:51;14695:7;14704:10;14716:13;14679:15;:51::i;3571:106:3:-:0;-1:-1:-1;;;;;3658:14:3;3636:7;3658:14;;;;;;;;;;;;3571:106::o;24454:2244:4:-;935:6;;24667:7;;;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;1216:11:::1;::::0;-1:-1:-1;;;1216:11:4;::::1;963:13:::0;1216:11:::1;1208:38;;;;-1:-1:-1::0;;;1208:38:4::1;;;;;;;:::i;:::-;24735:22:::2;;:::i;:::-;24759:21;24784:23;24799:7;24784:14;:23::i;:::-;24734:73;;;;24813:23;;:::i;:::-;24839:25;24855:8;24839:15;:25::i;:::-;24813:51;;24904:38;24909:9;:17;;;2556:1:0;1260:6;2549:8;;;;24904:38:4;24886:14;:56;;24871:104;;;;-1:-1:-1::0;;;24871:104:4::2;;;;;;;:::i;:::-;24982:23;25008:131;25029:8;:16;;;25053:8;:15;;;-1:-1:-1::0;;;;;25008:131:4::2;25076:9;:17;;;25101:9;:16;;;-1:-1:-1::0;;;;;25008:131:4::2;25125:8;;25008:13;:131::i;:::-;24982:157;;25172:8;25153:15;:27;;25145:59;;;;-1:-1:-1::0;;;25145:59:4::2;;;;;;;:::i;:::-;25211:21;25235:154;25257:8;:16;;;25281:8;:15;;;-1:-1:-1::0;;;;;25235:154:4::2;25304:9;:17;;;25329:9;:16;;;-1:-1:-1::0;;;;;25235:154:4::2;25353:14;25375:8;;25235:14;:154::i;:::-;25211:178;;25421:11;25404:13;:28;;25396:53;;;;-1:-1:-1::0;;;25396:53:4::2;;;;;;;:::i;:::-;25456:51;25472:7;25481:10;25493:13;25456:15;:51::i;:::-;25513:53;25529:8;25539:10;25551:14;25513:15;:53::i;:::-;25726:39;25731:9;:17;;;25750:14;25726:4;:39::i;:::-;25706:17;::::0;::::2;:59:::0;;;-1:-1:-1;;;;;25771:18:4;::::2;;::::0;;;:8:::2;:18;::::0;;;;:26:::2;;:46:::0;25875:36:::2;25706:9:::0;25780:8;25875:15:::2;:36::i;:::-;26006:34;26011:13;26026;26006:4;:34::i;:::-;25990:50;;26046:51;26064:7;26073:8;26083:13;26046:17;:51::i;:::-;26107:8;:14;;;26103:67;;;26131:16;::::0;::::2;:32:::0;;;26103:67:::2;26176:22;26201:131;26222:8;:16;;;26246:8;:15;;;-1:-1:-1::0;;;;;26201:131:4::2;26269:9;:17;;;26294:9;:16;;;-1:-1:-1::0;;;;;26201:131:4::2;26318:8;;26201:13;:131::i;:::-;26176:156;;26365:15;26347:14;:33;;26339:61;;;;-1:-1:-1::0;;;26339:61:4::2;;;;;;;:::i;:::-;26432:8;26414:14;:26;;26406:54;;;;-1:-1:-1::0;;;26406:54:4::2;;;;;;;:::i;:::-;26500:35;26505:13;26520:14;26500:4;:35::i;:::-;26481:15;:54;;26466:100;;;;-1:-1:-1::0;;;26466:100:4::2;;;;;;;:::i;:::-;26608:8;-1:-1:-1::0;;;;;26578:70:4::2;26599:7;-1:-1:-1::0;;;;;26578:70:4::2;26587:10;-1:-1:-1::0;;;;;26578:70:4::2;;26618:13;26633:14;26578:70;;;;;;;:::i;:::-;;;;;;;;989:6:::0;:14;;-1:-1:-1;;989:14:4;;;26663:13;;;;-1:-1:-1;24454:2244:4;-1:-1:-1;;;;;;;;;;24454:2244:4:o;565:42:0:-;606:1;565:42;:::o;21735:2172:4:-;935:6;;21947:7;;;;935:6;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;1216:11:::1;::::0;-1:-1:-1;;;1216:11:4;::::1;963:13:::0;1216:11:::1;1208:38;;;;-1:-1:-1::0;;;1208:38:4::1;;;;;;;:::i;:::-;22014:22:::2;;:::i;:::-;22038:21;22063:23;22078:7;22063:14;:23::i;:::-;22013:73;;;;22092:23;;:::i;:::-;22118:25;22134:8;22118:15;:25::i;:::-;22092:51;;22182:36;22187:8;:16;;;2443:1:0;1260:6;2436:8;;;;22182:36:4;22165:13;:53;;22150:100;;;;-1:-1:-1::0;;;22150:100:4::2;;;;;;;:::i;:::-;22257:23;22283:131;22304:8;:16;;;22328:8;:15;;;-1:-1:-1::0;;;;;22283:131:4::2;22351:9;:17;;;22376:9;:16;;;-1:-1:-1::0;;;;;22283:131:4::2;22400:8;;22283:13;:131::i;:::-;22257:157;;22447:8;22428:15;:27;;22420:59;;;;-1:-1:-1::0;;;22420:59:4::2;;;;;;;:::i;:::-;22486:22;22511:153;22533:8;:16;;;22557:8;:15;;;-1:-1:-1::0;;;;;22511:153:4::2;22580:9;:17;;;22605:9;:16;;;-1:-1:-1::0;;;;;22511:153:4::2;22629:13;22650:8;;22511:14;:153::i;:::-;22486:178;;22697:12;22679:14;:30;;22671:56;;;;-1:-1:-1::0;;;22671:56:4::2;;;;;;;:::i;:::-;22734:51;22750:7;22759:10;22771:13;22734:15;:51::i;:::-;22791:53;22807:8;22817:10;22829:14;22791:15;:53::i;:::-;23004:39;23009:9;:17;;;23028:14;23004:4;:39::i;:::-;22984:17;::::0;::::2;:59:::0;;;-1:-1:-1;;;;;23049:18:4;::::2;;::::0;;;:8:::2;:18;::::0;;;;:26:::2;;:46:::0;23153:36:::2;22984:9:::0;23058:8;23153:15:::2;:36::i;:::-;23212:34;23217:13;23232;23212:4;:34::i;:::-;23196:50;;23252:51;23270:7;23279:8;23289:13;23252:17;:51::i;:::-;23313:8;:14;;;23309:67;;;23337:16;::::0;::::2;:32:::0;;;23309:67:::2;23382:22;23407:131;23428:8;:16;;;23452:8;:15;;;-1:-1:-1::0;;;;;23407:131:4::2;23475:9;:17;;;23500:9;:16;;;-1:-1:-1::0;;;;;23407:131:4::2;23524:8;;23407:13;:131::i;:::-;23382:156;;23571:15;23553:14;:33;;23545:63;;;;-1:-1:-1::0;;;23545:63:4::2;;;;;;;:::i;:::-;23640:8;23622:14;:26;;23614:54;;;;-1:-1:-1::0;;;23614:54:4::2;;;;;;;:::i;:::-;23708:35;23713:13;23728:14;23708:4;:35::i;:::-;23689:15;:54;;23674:100;;;;-1:-1:-1::0;;;23674:100:4::2;;;;;;;:::i;:::-;23816:8;-1:-1:-1::0;;;;;23786:70:4::2;23807:7;-1:-1:-1::0;;;;;23786:70:4::2;23795:10;-1:-1:-1::0;;;;;23786:70:4::2;;23826:13;23841:14;23786:70;;;;;;;:::i;27371:107::-:0;27456:17;;-1:-1:-1;;;;;27456:17:4;27371:107;:::o;20063:1122::-;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;-1:-1:-1;;;;;20147:15:4;::::1;963:6:::0;20147:15;;;:8:::1;:15;::::0;;;;;20186:38;;-1:-1:-1;;;20186:38:4;;20147:15;;;20186:23:::1;::::0;:38:::1;::::0;20218:4:::1;::::0;20186:38:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20234:12:::0;;20168:56;;-1:-1:-1;20234:12:4::1;;20230:951;;;20261:12:::0;;::::1;::::0;::::1;;;20256:745;;-1:-1:-1::0;;;;;20310:23:4;::::1;20285:22;20310:23:::0;;;:16:::1;:23;::::0;;;;;20347:25;;::::1;20343:650;;-1:-1:-1::0;;;;;20386:23:4;::::1;20412:1;20386:23:::0;;;:16:::1;:23;::::0;;;;;:27;;;20425:19;;-1:-1:-1;;20425:19:4::1;;;::::0;;20461:22;::::1;::::0;20412:1;20461:22:::1;20495:25;20523:29;20528:7;20537:14;20523:4;:29::i;:::-;20495:57;;20564:16;20583:39;20588:17;20607:14;20583:4;:39::i;:::-;20564:58:::0;-1:-1:-1;20634:16:4::1;20660:44;1809:8:0::0;20677:26:4::1;1809:8:0::0;20564:58:4;20677:4:::1;:26::i;:::-;20660:4;:44::i;:::-;20634:71:::0;-1:-1:-1;20733:14:4;-1:-1:-1;;;;;20721:26:4;::::1;;20717:66;;;-1:-1:-1::0;20768:14:4;20717:66:::1;20795:25:::0;;-1:-1:-1;;;;;;;;20795:25:4::1;-1:-1:-1::0;;;;;;;;20795:25:4;::::1;::::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;20832:37:4::1;::::0;20865:3:::1;20832:37;;;;::::0;;20901:12:::1;::::0;20896:29:::1;::::0;:4:::1;:29::i;:::-;20881:12;:44:::0;20968:13;;20942:40:::1;::::0;-1:-1:-1;;;;;20942:40:4;::::1;::::0;-1:-1:-1;;;;;;;;;;;20942:40:4;::::1;::::0;-1:-1:-1;;;20968:13:4;::::1;-1:-1:-1::0;;;;;20968:13:4::1;::::0;20942:40:::1;:::i;:::-;;;;;;;;20343:650;;;;20256:745;;-1:-1:-1::0;;;;;21008:15:4;::::1;;::::0;;;:8:::1;:15;::::0;;;;:23:::1;;:33:::0;;;20230:951:::1;;;21093:14;::::0;21062:56:::1;::::0;21078:5;;-1:-1:-1;;;;;21093:14:4::1;21110:7:::0;21062:15:::1;:56::i;:::-;21126:14;::::0;:48:::1;::::0;-1:-1:-1;;;21126:48:4;;-1:-1:-1;;;;;21126:14:4;;::::1;::::0;:32:::1;::::0;:48:::1;::::0;21159:5;;21166:7;;21126:48:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;20230:951;-1:-1:-1::0;;989:6:4;:14;;-1:-1:-1;;989:14:4;;;-1:-1:-1;20063:1122:4:o;29891:264::-;1049:6;;29976:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;29991:20:::1;;:::i;:::-;-1:-1:-1::0;;;;;;30014:15:4;::::1;;::::0;;;:8:::1;:15;::::0;;;;;;;;29991:38;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;;::::0;;;::::1;::::0;::::1;::::0;::::1;;;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;;;;;;;-1:-1:-1;;;;;;;;29991:38:4;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;29991:38:4;::::1;;::::0;;;;-1:-1:-1;;;29991:38:4;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;30035::::1;;;;-1:-1:-1::0;;;30035:38:4::1;;;;;;;:::i;:::-;30088:6;:12;;;30087:13;30079:35;;;;-1:-1:-1::0;;;30079:35:4::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;;30127:23:4::1;;::::0;;;:16:::1;:23;::::0;;;;;;29891:264::o;5426:210::-;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;5511:24:4;::::1;5503:53;;;;-1:-1:-1::0;;;5503:53:4::1;;;;;;;:::i;:::-;5562:11;:24:::0;;-1:-1:-1;;;;;;5562:24:4::1;;-1:-1:-1::0;;;;;5562:24:4;::::1;;;::::0;;5597:34:::1;::::0;::::1;::::0;::::1;::::0;5562:24;;5597:34:::1;:::i;29346:142::-:0;1049:6;;29447:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;29471:12:4::1;::::0;29346:142;:::o;28767:225::-;1049:6;;28876:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;28913:15:4;::::1;;::::0;;;:8:::1;:15;::::0;;;;:21;::::1;;28905:47;;;;-1:-1:-1::0;;;28905:47:4::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;28965:15:4::1;;::::0;;;:8:::1;:15;::::0;;;;:22;-1:-1:-1;;;28965:22:4;::::1;-1:-1:-1::0;;;;;28965:22:4::1;::::0;28767:225::o;3206:108:3:-;3302:7;3295:14;;;;;;;;-1:-1:-1;;3295:14:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3272:13;;3295:14;;3302:7;;3295:14;;3302:7;3295:14;;;;;;;;;;;;;;;;;;;;;;;;9748:508:4;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;972:4;-1:-1:-1;;963:13:4;;;;;;;;;1134:11;::::1;-1:-1:-1::0;;;;;1134:11:4::1;1120:10;:25;1112:56;;;;-1:-1:-1::0;;;1112:56:4::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;9909:15:4;::::2;9885:21;9909:15:::0;;;:8:::2;:15;::::0;;;;9938:12;;::::2;;9930:38;;;;-1:-1:-1::0;;;9930:38:4::2;;;;;;;:::i;:::-;9983:12:::0;;::::2;::::0;::::2;;;9982:13;9974:35;;;;-1:-1:-1::0;;;9974:35:4::2;;;;;;;:::i;:::-;10029:23:::0;;889:7:0::2;10029:23:4::0;;;::::2;;;10023:3;:29;:53;;10015:86;;;;-1:-1:-1::0;;;10015:86:4::2;;;;;;;:::i;:::-;10107:37:::0;;-1:-1:-1;;10107:37:4::2;::::0;10140:3:::2;10107:37;;;;::::0;;-1:-1:-1;;;;;10150:23:4;::::2;-1:-1:-1::0;10150:23:4;;;:16:::2;:23;::::0;;;;;;:40;;;10201:50;::::2;::::0;::::2;::::0;10150:23;;:40;;10201:50:::2;:::i;:::-;;;;;;;;-1:-1:-1::0;;989:6:4;:14;;-1:-1:-1;;989:14:4;;;-1:-1:-1;9748:508:4:o;4560:132:3:-;4631:4;4643:27;4649:10;4661:3;4666;4643:5;:27::i;:::-;-1:-1:-1;4683:4:3;4560:132;;;;:::o;15306:1249:4:-;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;-1:-1:-1;;963:13:4;972:4;963:13;;;15457:7:::1;:14:::0;15433:38;::::1;15425:62;;;;-1:-1:-1::0;;;15425:62:4::1;;;;;;;:::i;:::-;15493:17;15513:13;:11;:13::i;:::-;15493:33;;15532:15;15550:28;15555:12;1587:4:0;15550::4;:28::i;:::-;15532:46;;15584:23;15610:27;15615:12;15629:7;15610:4;:27::i;:::-;15584:53;;15643:13;15659:32;15664:15;15681:9;15659:4;:32::i;:::-;15643:48:::0;-1:-1:-1;15705:10:4;15697:38:::1;;;;-1:-1:-1::0;;;15697:38:4::1;;;;;;;:::i;:::-;15742:40;15757:10;15769:12;15742:14;:40::i;:::-;15803:17;::::0;15788:42:::1;::::0;-1:-1:-1;;;;;15803:17:4::1;15822:7:::0;15788:14:::1;:42::i;:::-;15836:31;15851:15;15836:14;:31::i;:::-;15878:9;15873:678;15893:24:::0;;::::1;15873:678;;;15932:9;15944:7;15952:1;15944:10;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;15944:10:4::1;::::0;-1:-1:-1;15962:20:4::1;;:::i;:::-;-1:-1:-1::0;;;;;;15985:11:4;::::1;;::::0;;;:8:::1;:11;::::0;;;;;;;;15962:34;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;;;;;;;-1:-1:-1;;;;;;;;15962:34:4;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;15962:34:4;::::1;;::::0;;;;-1:-1:-1;;;15962:34:4;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;16004:541:::1;;16032:22;16057:27;16062:5;16069:6;:14;;;16057:4;:27::i;:::-;16032:52:::0;-1:-1:-1;16102:19:4;16094:47:::1;;;;-1:-1:-1::0;;;16094:47:4::1;;;;;;;:::i;:::-;16177:13;;16191:1;16177:16;;;;;;;;;;;;;16159:14;:34;;16151:60;;;;-1:-1:-1::0;;;16151:60:4::1;;;;;;;:::i;:::-;16244:36;16249:6;:14;;;16265;16244:4;:36::i;:::-;-1:-1:-1::0;;;;;16222:11:4;::::1;;::::0;;;:8:::1;:11;::::0;;;;;;:19:::1;;:58:::0;;;;16295:39;;16304:10:::1;::::0;16295:39:::1;::::0;::::1;::::0;16319:14;;16295:39:::1;:::i;:::-;;;;;;;;16344:46;16360:1;16363:10;16375:14;16344:15;:46::i;:::-;16004:541;;;;16493:13;;16507:1;16493:16;;;;;;;;;;;;;16513:1;16493:21;16485:51;;;;-1:-1:-1::0;;;16485:51:4::1;;;;;;;:::i;:::-;-1:-1:-1::0;;15919:3:4::1;;15873:678;;;-1:-1:-1::0;;989:6:4;:14;;-1:-1:-1;;989:14:4;;;-1:-1:-1;;;;;;15306:1249:4:o;7755:1731::-;935:6;;;;934:7;926:31;;;;-1:-1:-1;;;926:31:4;;;;;;;:::i;:::-;963:6;:13;;972:4;-1:-1:-1;;963:13:4;;;;;;;;;1134:11;::::1;-1:-1:-1::0;;;;;1134:11:4::1;1120:10;:25;1112:56;;;;-1:-1:-1::0;;;1112:56:4::1;;;;;;;:::i;:::-;7965:38:::0;;::::2;:81:::0;::::2;;;-1:-1:-1::0;8007:39:4;;::::2;7965:81;7950:123;;;;-1:-1:-1::0;;;7950:123:4::2;;;;;;;:::i;:::-;8260:7;:14:::0;8280:29:::2;8260:14:::0;8312:16:::2;::::0;::::2;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;8312:16:4::2;-1:-1:-1::0;8280:48:4;-1:-1:-1;8459:23:4::2;8498:6:::0;8485:27:::2;::::0;::::2;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;8459:53;;8647:9;8642:161;8662:17:::0;;::::2;8642:161;;;8707:8;:19;8716:6;;8723:1;8716:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8707:19:4::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;8707:19:4;8694:32;;::::2;::::0;::::2;::::0;;;;::::2;::::0;;::::2;;;::::0;;::::2;::::0;::::2;::::0;::::2;;;::::0;;::::2;::::0;;;;::::2;::::0;;::::2;;::::0;;;;;;;-1:-1:-1;;;;;;;;8694:32:4;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;8694:32:4;::::2;;::::0;;;;-1:-1:-1;;;8694:32:4;;::::2;::::0;;::::2;::::0;;;;;;;::::2;::::0;;;;;:10;;:7;;8702:1;;8694:10;::::2;;;;;;;;;;:32;;;;8738:7;8746:1;8738:10;;;;;;;;;;;;;;:16;;;8734:62;;;8792:4;8756:15;8772:7;8780:1;8772:10;;;;;;;;;;;;;;:16;;;8756:33;;;;;;;;;;:40:::0;::::2;;:33;::::0;;::::2;::::0;;;;;;;:40;8734:62:::2;8681:3;;8642:161;;;;8900:9;8895:125;8919:4;8915:1;:8;8895:125;;;8943:15;8959:1;8943:18;;;;;;;;;;;;;;8938:76;;8973:32;8991:7;8999:1;8991:10;;;;;;;;;::::0;;;::::2;::::0;;::::2;::::0;-1:-1:-1;;;;;8991:10:4::2;::::0;8973:17:::2;:32::i;:::-;8925:3;;8895:125;;;;9030:9;9025:457;9045:17:::0;;::::2;9025:457;;;9077:13;9093:6;;9100:1;9093:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;9077:25;;9189:13;9205:14;;9220:1;9205:17;;;;;;;;;;;;;;;;;;;;:::i;:::-;9189:33:::0;-1:-1:-1;1809:8:0;-1:-1:-1;;;;;9234:19:4;::::2;;9230:52;;;-1:-1:-1::0;1809:8:0;9230:52:4::2;9295:7;9303:1;9295:10;;;;;;;;;;;;;;:16;;;9290:186;;9370:40;9376:5;9383:15;;9399:1;9383:18;;;;;;;;;;;;;9403:6;9370:5;:40::i;:::-;9290:186;;;9435:32;9453:5;9460:6;9435:17;:32::i;:::-;-1:-1:-1::0;;9064:3:4::2;;9025:457;;;-1:-1:-1::0;;989:6:4;:14;;-1:-1:-1;;989:14:4;;;-1:-1:-1;;;;;;;;7755:1731:4:o;27904:145::-;1049:6;;27995:23;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;28037:7:::1;28028:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;28028:16:4::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;27904:145:::0;:::o;27759:97::-;27837:7;:14;27759:97;:::o;26922:113::-;1049:6;;26987:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;27022:8:4::1;::::0;26922:113;:::o;3959:237:3:-;4087:10;4029:4;4076:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4076:27:3;;;;;;;;;;4071:38;;4105:3;4071:4;:38::i;:::-;4052:10;4041:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4041:27:3;;;;;;;;;;;:68;;;4120:54;;4041:27;;-1:-1:-1;;;;;;;;;;;4120:54:3;;;4041:68;4120:54;:::i;3425:142::-;-1:-1:-1;;;;;3542:15:3;;;3518:7;3542:15;;;:10;:15;;;;;;;;:20;;;;;;;;;;;;;3425:142::o;27039:113:4:-;1049:6;;27104:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;1587:4:0::1;27039:113:4::0;:::o;29559:208::-;1049:6;;29637:7;;1049:6;;1048:7;1040:31;;;;-1:-1:-1;;;1040:31:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;29676:15:4;::::1;29652:21;29676:15:::0;;;:8:::1;:15;::::0;;;;29705:12;;::::1;;29697:38;;;;-1:-1:-1::0;;;29697:38:4::1;;;;;;;:::i;:::-;29748:14;;::::0;;29559:208;-1:-1:-1;;29559:208:4:o;5748:159::-;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;5861:41:::1;::::0;-1:-1:-1;;;5861:41:4;;-1:-1:-1;;;;;5861:30:4;::::1;::::0;::::1;::::0;:41:::1;::::0;5892:9;;5861:41:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;5748:159:::0;;:::o;5969:254::-;1134:11;;;;;-1:-1:-1;;;;;1134:11:4;1120:10;:25;1112:56;;;;-1:-1:-1;;;1112:56:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;6066:30:4;::::1;6058:59;;;;-1:-1:-1::0;;;6058:59:4::1;;;;;;;:::i;:::-;6123:17;:36:::0;;-1:-1:-1;;;;;;6123:36:4::1;-1:-1:-1::0;;;;;6123:36:4;::::1;;::::0;;6170:48:::1;::::0;::::1;::::0;::::1;::::0;6123:36;;6170:48:::1;:::i;26827:91::-:0;26902:11;;-1:-1:-1;;;26902:11:4;;;;;26827:91::o;42002:316::-;42077:20;;:::i;:::-;-1:-1:-1;;;;;;42116:15:4;;;;;;:8;:15;;;;;;;;;42107:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;42107:24:4;;;;;;;;-1:-1:-1;;;42107:24:4;;;;;;;-1:-1:-1;;;42107:24:4;;;;;;;;;;;;;;;;42137:38;;;;-1:-1:-1;;;42137:38:4;;;;;;;:::i;:::-;42279:6;:12;;;42271:42;;;;-1:-1:-1;;;42271:42:4;;;;;;;:::i;1304:273:2:-;1363:7;1391:5;;;1410:6;;;:21;;;1430:1;1425;1420:2;:6;;;;;;:11;1410:21;1402:50;;;;-1:-1:-1;;;1402:50:2;;;;;;;:::i;:::-;1477:8;1471:15;;1500:8;;;;1492:37;;;;-1:-1:-1;;;1492:37:2;;;;;;;:::i;:::-;1535:10;1260:6:0;1548:2:2;:9;;;1304:273;-1:-1:-1;;;;;;1304:273:2:o;12767:1207:1:-;12983:20;13059:24;13086:33;13091:14;13107:11;13086:4;:33::i;:::-;13059:60;;13192:11;13206:28;1260:6:0;13217:16:1;13206:4;:28::i;:::-;13192:42;;13240:11;13254:18;13259:3;13264:7;13254:4;:18::i;:::-;13240:32;;13278:35;13316:37;13321:14;13337:15;1260:6:0;13348:3:1;13337:4;:15::i;:::-;13316:4;:37::i;:::-;13278:75;;13360:26;13389:68;13401:15;13424:27;13389:4;:68::i;:::-;13360:97;;13463:21;13487:41;13492:18;13512:15;13487:4;:41::i;:::-;13463:65;;13597:17;13617:37;13622:13;13637:16;13617:4;:37::i;:::-;13597:57;;13660:21;13684:27;13689:9;13700:10;13684:4;:27::i;:::-;13660:51;;13717:32;13752:31;13757:10;13769:13;13752:4;:31::i;:::-;13717:66;;13892:52;13897:24;13923:20;1260:6:0;1587:4;13923::1;:20::i;13892:52::-;13877:67;;13950:19;;;;;;;;;12767:1207;;;;;;;;:::o;32196:365:4:-;32296:12;32310:17;32331:5;-1:-1:-1;;;;;32331:10:4;32381:24;;;32415:2;32427:6;32349:92;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;32349:92:4;;;;;;;;;;;;;;-1:-1:-1;;;;;32349:92:4;-1:-1:-1;;;;;;32349:92:4;;;;;;;;;;32331:116;;;;32349:92;32331:116;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32295:152;;;;32468:7;:57;;;;-1:-1:-1;32480:11:4;;:16;;:44;;;32511:4;32500:24;;;;;;;;;;;;:::i;:::-;32453:103;;;;-1:-1:-1;;;32453:103:4;;;;;;;:::i;932:173:2:-;991:7;1007:9;1018;1031:14;1040:1;1043;1031:8;:14::i;:::-;1006:39;;;;1060:4;1059:5;1051:35;;;;-1:-1:-1;;;1051:35:2;;;;;;;:::i;:::-;-1:-1:-1;1099:1:2;932:173;-1:-1:-1;;;932:173:2:o;36885:1296:4:-;37057:6;:20;;;-1:-1:-1;;;;;37040:37:4;:6;:13;;;-1:-1:-1;;;;;37040:37:4;;;:60;;;;37088:6;:12;;;37087:13;37040:60;:121;;;;757:10:0;37116:6:4;:23;;;37110:29;;:3;:29;:51;37040:121;37029:146;;;37168:7;;37029:146;37199:13;;;;37234:20;;;;37180:16;37278:34;-1:-1:-1;;;;;37278:34:4;;1219:3:0;1260:6;1214:8;;37278:34:4;37260:52;;37318:12;37333:23;37338:9;-1:-1:-1;;;;;37333:23:4;37349:6;-1:-1:-1;;;;;37333:23:4;:4;:23::i;:::-;37318:38;;37373:7;37366:4;:14;37362:98;;;37406:24;37411:9;-1:-1:-1;;;;;37406:24:4;37422:7;37406:4;:24::i;:::-;37390:41;;37446:7;37439:14;;37362:98;1809:8:0;-1:-1:-1;;;;;37469:20:4;;;37465:712;;37537:12;;37508:1;;-1:-1:-1;37532:26:4;;37508:1;37532:4;:26::i;:::-;37517:12;:41;37815:14;37823:5;37815:7;:14::i;:::-;37465:712;;;37865:24;37870:12;;37884:4;37865;:24::i;:::-;37850:12;:39;-1:-1:-1;;;;;37969:22:4;;:13;;;:22;;;-1:-1:-1;;;;;38039:15:4;;;;;;:8;:15;;;;;;;:31;;-1:-1:-1;;;;;;;;38039:31:4;-1:-1:-1;;;38039:31:4;;;;;;;-1:-1:-1;;38078:46:4;;38120:3;38078:46;;;;;;;38137:33;;-1:-1:-1;;;;;;;;;;;38137:33:4;;;37969:22;;38137:33;:::i;:::-;;;;;;;;36885:1296;;;;;;;:::o;31241:93::-;31310:19;31316:4;31322:6;31310:5;:19::i;31508:73::-;31563:13;31569:6;31563:5;:13::i;:::-;31508:73;:::o;31338:89::-;31405:17;31411:2;31415:6;31405:5;:17::i;41258:740::-;41332:20;;:::i;:::-;-1:-1:-1;;;;;;41392:15:4;;41354:19;41392:15;;;:8;:15;;;;;;;;41383:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;41383:24:4;;;;;;;;-1:-1:-1;;;41383:24:4;;;;;;;-1:-1:-1;;;41383:24:4;;;;;;;;;;;;;;;;;41354:19;41413:38;;;;-1:-1:-1;;;41413:38:4;;;;;;;:::i;:::-;-1:-1:-1;41472:14:4;;;;41681:12;;;;41676:318;;-1:-1:-1;;;;;41720:23:4;;;;;;:16;:23;;;;;;41703:14;;;:40;;;41776:79;;41790:33;;41811:11;41790:4;:33::i;:::-;41833:6;:14;;;41776:4;:79::i;:::-;41751:104;-1:-1:-1;41863:21:4;41887:37;41905:2;1816:1:0;1260:6;1809:8;;41892:15:4;;;;;;41909:14;41887:4;:37::i;:::-;41863:61;-1:-1:-1;41955:31:4;1816:1:0;1260:6;1809:8;;41972:13:4;41955:4;:31::i;:::-;-1:-1:-1;;;;;41932:55:4;:13;;;:55;-1:-1:-1;;41676:318:4;41258:740;;;:::o;1499:461:1:-;1682:17;1707:13;1723:35;1728:14;1744:13;1723:4;:35::i;:::-;1707:51;;1764:13;1780:37;1785:15;1802:14;1780:4;:37::i;:::-;1764:53;;1823:13;1839:18;1844:5;1851;1839:4;:18::i;:::-;1823:34;;1863:13;1879:31;1260:6:0;1890:19:1;1260:6:0;1901:7:1;1890:4;:19::i;1879:31::-;1863:47;;1936:18;1941:5;1948;1936:4;:18::i;:::-;1924:30;1499:461;-1:-1:-1;;;;;;;;;;1499:461:1:o;2821:273:3:-;2925:5;2919:19;;-1:-1:-1;;2919:19:3;;;;;;;;;;;:24;:57;;;;-1:-1:-1;2953:18:3;;:23;;2919:57;:92;;;;-1:-1:-1;2986:20:3;;:25;;2919:92;2904:145;;;;-1:-1:-1;;;2904:145:3;;;;;;;:::i;:::-;3055:12;;;;:5;;:12;;;;;:::i;:::-;-1:-1:-1;3073:16:3;;;;:7;;:16;;;;;:::i;:::-;;2821:273;;:::o;2224:269::-;-1:-1:-1;;;;;2317:13:3;;:8;:13;;;;;;;;;;;:20;-1:-1:-1;2317:20:3;2309:53;;;;-1:-1:-1;;;2309:53:3;;;;;;;:::i;:::-;-1:-1:-1;;;;;2389:13:3;;:8;:13;;;;;;;;;;;2384:24;;2404:3;2384:4;:24::i;:::-;-1:-1:-1;;;;;2368:13:3;;;:8;:13;;;;;;;;;;;:40;;;;2435:13;;;;;;;2430:24;;2450:3;2430:4;:24::i;:::-;-1:-1:-1;;;;;2414:13:3;;;:8;:13;;;;;;;;;;;;:40;;;;2465:23;;;;;;;;;;2484:3;;2465:23;:::i;:::-;;;;;;;;2224:269;;;:::o;777:151:2:-;836:7;863:5;;;882:6;;;;874:35;;;;-1:-1:-1;;;874:35:2;;;;;;;:::i;:::-;922:1;777:151;-1:-1:-1;;;777:151:2:o;31796:396:4:-;31898:12;31912:17;31933:5;-1:-1:-1;;;;;31933:10:4;31983:28;;;32021:4;32043;32058:6;31951:121;;;;;;;;;;:::i;31431:73::-;31486:13;31492:6;31486:5;:13::i;10481:1184:1:-;10695:22;10725:24;10752:33;10757:14;10773:11;10752:4;:33::i;:::-;10725:60;;10878:32;10913:40;10918:12;10932:20;1260:6:0;1587:4;10932::1;:20::i;:::-;10913:4;:40::i;:::-;10878:75;;10959:21;10983:42;10988:10;11000:24;10983:4;:42::i;:::-;10959:66;;11031:17;11051:31;11056:13;11071:10;11051:4;:31::i;:::-;11031:51;;11139:21;11163:45;11168:9;11179:28;1260:6:0;11190:16:1;11179:4;:28::i;:::-;11163:4;:45::i;:::-;11139:69;;11214:26;11243:36;11248:13;11263:15;11243:4;:36::i;:::-;11214:65;;11286:35;11324:59;11336:15;11359:18;11324:4;:59::i;:::-;11286:97;;11503:11;11517:43;11522:28;1260:6:0;11533:16:1;11522:4;:28::i;:::-;11552:7;11517:4;:43::i;:::-;11503:57;;11583:50;11588:27;11617:15;1260:6:0;11628:3:1;11617:4;:15::i;11583:50::-;11566:67;10481:1184;-1:-1:-1;;;;;;;;;;;;;;;10481:1184:1:o;1581:344:2:-;1640:7;1663:6;1655:31;;;;-1:-1:-1;;;1655:31:2;;;;;;;:::i;:::-;1260:6:0;1705:8:2;;1727:6;;;:24;;;1260:6:0;1742:1:2;1737:2;:6;;;;;;:14;1727:24;1719:53;;;;-1:-1:-1;;;1719:53:2;;;;;;;:::i;:::-;1818:1;1814:5;;1808:12;;1834:8;;;;1826:37;;;;-1:-1:-1;;;1826:37:2;;;;;;;:::i;:::-;1886:10;1904:1;1899:2;:6;;;;38815:1869:4;38942:6;:12;;;38937:1615;;39038:6;:14;;;39023:11;:29;39019:1304;;-1:-1:-1;;;;;39109:23:4;;39135:1;39109:23;;;:16;:23;;;;;;;;:27;;;39187:8;:15;;;;;:28;;-1:-1:-1;;39187:28:4;;;;;39211:4;39225:12;;;:19;;;;39259:22;;;39135:1;39259:22;39535:25;39563:33;39568:11;39581:6;:14;;;39563:4;:33::i;:::-;39535:61;;39606:16;39625:39;39630:17;39649:6;:14;;;39625:4;:39::i;:::-;39606:58;-1:-1:-1;39697:44:4;1809:8:0;39714:26:4;1809:8:0;39606:58:4;39714:4;:26::i;39697:44::-;-1:-1:-1;;;;;39674:68:4;:13;;;:68;;;39772:14;-1:-1:-1;39752:74:4;;;39811:14;39788:13;;;:38;39752:74;39861:13;;;;;-1:-1:-1;;;;;39836:15:4;;;;;;:8;:15;;;;;:38;;-1:-1:-1;;;;;;;;39836:38:4;-1:-1:-1;;;;;;;;39836:38:4;;;;;-1:-1:-1;;39884:46:4;;39926:3;39884:46;;;;;;39960:12;;39974:13;;39955:33;;39960:12;39955:33;:4;:33::i;:::-;39940:12;:48;40029:13;;;;40003:40;;-1:-1:-1;;;;;40003:40:4;;;-1:-1:-1;;;;;;;;;;;40003:40:4;;;40029:13;40003:40;:::i;:::-;;;;;;;;39019:1304;;;;;40068:22;40093:85;40109:33;40114:6;:14;;;40130:11;40109:4;:33::i;40093:85::-;40068:110;-1:-1:-1;40188:21:4;40212:37;40230:2;1816:1:0;1260:6;1809:8;;40212:37:4;40188:61;-1:-1:-1;40282:31:4;1816:1:0;1260:6;1809:8;;40282:31:4;-1:-1:-1;;;;;40259:55:4;:13;;;:55;-1:-1:-1;;39019:1304:4;38937:1615;;;40515:30;40531:6;40539:5;40515:15;:30::i;:::-;-1:-1:-1;;;;;40642:15:4;;;;;;;:8;:15;;;;;:23;;:37;;;;-1:-1:-1;38815:1869:4:o;35196:596::-;-1:-1:-1;;;;;35299:15:4;;35275:21;35299:15;;;:8;:15;;;;;35328:12;;;;35320:38;;;;-1:-1:-1;;;35320:38:4;;;;;;;:::i;:::-;1809:8:0;-1:-1:-1;;;;;35551:27:4;;;;;:49;;-1:-1:-1;;;;;;35582:18:4;;;35551:49;35536:94;;;;-1:-1:-1;;;35536:94:4;;;;;;;:::i;:::-;1860:9:0;-1:-1:-1;;;;;35644:27:4;;;;35636:54;;;;-1:-1:-1;;;35636:54:4;;;;;;;:::i;:::-;35696:36;;-1:-1:-1;;;;35696:36:4;-1:-1:-1;;;;;;;;35696:36:4;;;;;;35743:44;;-1:-1:-1;;;;;35743:44:4;;;;;;;35696:36;;35743:44;:::i;:::-;;;;;;;;35196:596;;;:::o;6196:1079:1:-;6409:21;6666:24;6693:32;6698:13;6713:11;6693:4;:32::i;:::-;6666:59;;6731:11;6745:43;6750:28;1260:6:0;6761:16:1;6750:4;:28::i;:::-;6780:7;6745:4;:43::i;:::-;6731:57;;6794:29;6826:36;6831:13;6846:15;1260:6:0;6857:3:1;6846:4;:15::i;6826:36::-;6794:68;;6869:25;6897:43;6902:14;6918:21;6897:4;:43::i;:::-;6869:71;;6946:20;6969:39;6974:17;6993:14;6969:4;:39::i;:::-;6946:62;;7078:17;7098:36;7103:12;7117:16;7098:4;:36::i;:::-;7078:56;;7140:21;7164:27;7169:9;7180:10;7164:4;:27::i;:::-;7140:51;;7213:31;7218:13;7233:10;7213:4;:31::i;:::-;7197:47;6196:1079;-1:-1:-1;;;;;;;;;;;;;;6196:1079:1:o;8277:1102::-;8490:21;8519:24;8546:32;8551:13;8566:11;8546:4;:32::i;:::-;8519:59;;8584:21;8608:31;8613:10;8625:13;8608:4;:31::i;:::-;8584:55;;8645:17;8665:31;8670:13;8685:10;8665:4;:31::i;:::-;8645:51;;8757:11;8771:28;1260:6:0;8782:16:1;8771:4;:28::i;:::-;8757:42;;8805:20;8828;8833:9;8844:3;8828:4;:20::i;:::-;8805:43;;8854:25;8882:34;8887:12;8901:14;8882:4;:34::i;:::-;8854:62;;8922:29;8954:39;8959:17;8978:14;8954:4;:39::i;:::-;8922:71;;9225:11;9239:43;9244:28;1260:6:0;9255:16:1;9244:4;:28::i;9239:43::-;9225:57;;9304:44;9309:21;9332:15;1260:6:0;9343:3:1;9332:4;:15::i;4586:608::-;4798:21;4827:19;4849:35;4854:14;4870:13;4849:4;:35::i;:::-;4827:57;;4890:12;4905:37;4910:15;4927:14;4905:4;:37::i;:::-;4890:52;;4948:9;4960:27;4965:15;4982:4;4960;:27::i;:::-;4948:39;;4993:11;5007:20;5012:1;5015:11;5007:4;:20::i;:::-;4993:34;;5039:15;5044:3;1260:6:0;5039:4:1;:15::i;:::-;5033:21;;5076:19;1260:6:0;5087:7:1;5076:4;:19::i;:::-;5060:35;;5117:46;5122:25;5127:14;5143:3;5122:4;:25::i;:::-;5149:13;5117:4;:46::i;:::-;5101:62;4586:608;-1:-1:-1;;;;;;;;;;;4586:608:1:o;2962:622::-;3173:22;3203:19;3225:35;3230:13;3245:14;3225:4;:35::i;:::-;3203:57;;3266:18;3287:19;1260:6:0;3298:7:1;3287:4;:19::i;:::-;3266:40;;3325:31;3330:13;3345:10;3325:4;:31::i;:::-;3312:44;;3362:9;3374:54;3379:14;3395:32;3400:14;3416:10;3395:4;:32::i;3374:54::-;3362:66;;3434:11;3448:20;3453:1;3456:11;3448:4;:20::i;:::-;3434:34;;3474:11;3488:15;1260:6:0;3499:3:1;3488:4;:15::i;:::-;3474:29;;3526:26;3531:15;3548:3;3526:4;:26::i;:::-;3509:43;2962:622;-1:-1:-1;;;;;;;;;;;;2962:622:1:o;33199:700:4:-;-1:-1:-1;;;;;33315:15:4;;;;;;:8;:15;;;;;:21;;;33314:22;33306:47;;;;-1:-1:-1;;;33306:47:4;;;;;;;:::i;:::-;1809:8:0;-1:-1:-1;;;;;33368:27:4;;;;33360:54;;;;-1:-1:-1;;;33360:54:4;;;;;;;:::i;:::-;1860:9:0;-1:-1:-1;;;;;33428:27:4;;;;33420:54;;;;-1:-1:-1;;;33420:54:4;;;;;;;:::i;:::-;2060:13:0;33488:29:4;;;33480:57;;;;-1:-1:-1;;;33480:57:4;;;;;;;:::i;:::-;33562:197;;;;;;;;33584:4;33562:197;;;;;;33603:5;33562:197;;;;;;33641:3;33562:197;;;;;;33661:1;-1:-1:-1;;;;;33562:197:4;;;;;33685:13;-1:-1:-1;;;;;33562:197:4;;;;;33719:7;:14;;;;33562:197;;;;;;33751:1;33562:197;;;33544:8;:15;33553:5;-1:-1:-1;;;;;33544:15:4;-1:-1:-1;;;;;33544:15:4;;;;;;;;;;;;:215;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33544:215:4;;;;;-1:-1:-1;;;;;33544:215:4;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33544:215:4;;;;;-1:-1:-1;;;;;33544:215:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33765:7;33778:5;33765:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33765:19:4;;;;;-1:-1:-1;;;;;33765:19:4;;;;;;33816:14;33790:16;:23;33807:5;-1:-1:-1;;;;;33790:23:4;-1:-1:-1;;;;;33790:23:4;;;;;;;;;;;;:40;;;;33857:5;-1:-1:-1;;;;;33841:53:4;;33864:13;33879:14;33841:53;;;;;;;:::i;2342:490:2:-;2406:7;2204:5:0;2429:4:2;:21;;2421:55;;;;-1:-1:-1;;;2421:55:2;;;;;;;:::i;:::-;2255:18:0;2490:21:2;;;2482:56;;;;-1:-1:-1;;;2482:56:2;;;;;;;:::i;:::-;2545:13;2561:11;2568:3;2561:6;:11::i;:::-;2545:27;;2578:14;2595:16;2600:3;2605:5;2595:4;:16::i;:::-;2578:33;;2618:16;2637:24;2643:4;2649:11;2654:5;2649:4;:11::i;:::-;2637:5;:24::i;:::-;2618:43;-1:-1:-1;2672:11:2;2668:47;;2700:8;-1:-1:-1;2693:15:2;;-1:-1:-1;;2693:15:2;2668:47;2721:21;2745:40;2756:4;2762:6;2320:13:0;2745:10:2;:40::i;:::-;2721:64;;2798:29;2803:8;2813:13;2798:4;:29::i;:::-;2791:36;2342:490;-1:-1:-1;;;;;;;2342:490:2:o;1109:191::-;1184:7;1193:4;1216:1;1211;:6;1207:89;;-1:-1:-1;;1235:5:2;;;1242;1227:21;;1207:89;-1:-1:-1;;1277:5:2;;;1284:4;1207:89;1109:191;;;;;:::o;34275:917:4:-;34322:20;;:::i;:::-;-1:-1:-1;;;;;;34345:15:4;;;;;;:8;:15;;;;;;;;;34322:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;34322:38:4;;;;;;;;-1:-1:-1;;;34322:38:4;;;;;;;-1:-1:-1;;;34322:38:4;;;;;;;;;;;;;;;;;;;;;;;34546:7;:14;34322:38;;;-1:-1:-1;;34546:18:4;34674:13;;;34670:117;;34714:7;34722:4;34714:13;;;;;;;;;;;;;;;;;;34697:7;:14;;-1:-1:-1;;;;;34714:13:4;;;;34705:5;;34697:14;;;;;;;;;;;;;;:30;;;;;-1:-1:-1;;;;;34697:30:4;;;;;-1:-1:-1;;;;;34697:30:4;;;;;;34774:5;34735:8;:24;34744:7;34752:5;34744:14;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34744:14:4;34735:24;;;;;;;;;;;;:45;;;;;;;-1:-1:-1;;;34735:45:4;-1:-1:-1;;;;;34735:45:4;;;;;;;;;34670:117;34792:7;:13;;;;;;;;;;;;;;;-1:-1:-1;;34792:13:4;;;;;;;-1:-1:-1;;;;;;34792:13:4;;;;;;;;;34829:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34811:15:4;;;;;:8;:15;;;;;;;:174;;;;;;;;;;;;;;-1:-1:-1;;34811:174:4;;;;;;;-1:-1:-1;;34811:174:4;34792:13;34811:174;;;;;;;;;;;-1:-1:-1;;34811:174:4;;34829:156;34811:174;;;;;;;;-1:-1:-1;;;;;;;;34811:174:4;-1:-1:-1;;;;;;;;34811:174:4;;;;;-1:-1:-1;;;;34811:174:4;-1:-1:-1;;;34811:174:4;;;;;;;;;-1:-1:-1;;;;;34811:174:4;-1:-1:-1;;;34829:156:4;34811:174;;;;;;;;;;;;;;-1:-1:-1;34811:174:4;;;;;;;;35063:14;;35032:61;;34811:15;;35063:14;35080:12;35032:15;:61::i;:::-;35099:14;;:53;;-1:-1:-1;;;35099:53:4;;-1:-1:-1;;;;;35099:14:4;;;;:32;;:53;;35132:5;;35139:12;;35099:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35163:24;35181:5;35163:24;;;;;;:::i;:::-;;;;;;;;34275:917;;;;;:::o;2590:93:3:-;2647:31;2653:4;2667;2674:3;2647:5;:31::i;1948:272::-;2016:4;1999:8;:23;;;;;;;;;;;:30;-1:-1:-1;1999:30:3;1991:63;;;;-1:-1:-1;;;1991:63:3;;;;;;;:::i;:::-;2108:4;2091:8;:23;;;;;;;;;;;2086:34;;2116:3;2086:4;:34::i;:::-;2077:4;2060:8;:23;;;;;;;;;;:60;2146:12;;2141:23;;2160:3;2141:4;:23::i;:::-;2126:12;:38;2175:40;;2207:1;;2192:4;;2175:40;;;;2211:3;;2175:40;:::i;:::-;;;;;;;;1948:272;:::o;2497:89::-;2552:29;2566:4;2573:2;2577:3;2552:5;:29::i;1741:203::-;1832:4;1815:8;:23;;;;;;;;;;;1810:34;;1840:3;1810:4;:34::i;:::-;1801:4;1784:8;:23;;;;;;;;;;:60;1870:12;;1865:23;;1884:3;1865:4;:23::i;:::-;1850:12;:38;1899:40;;1928:4;;1916:1;;1899:40;;;;1935:3;;1899:40;:::i;35796:1085:4:-;36007:6;:20;;;-1:-1:-1;;;;;35990:37:4;:6;:13;;;-1:-1:-1;;;;;35990:37:4;;;:60;;;;36038:6;:12;;;36037:13;35990:60;:121;;;;757:10:0;36066:6:4;:23;;;36060:29;;:3;:29;:51;35990:121;35979:146;;;36118:7;;35979:146;36149:13;;;;36184:20;;;;36130:16;36228:34;-1:-1:-1;;;;;36228:34:4;;1219:3:0;1260:6;1214:8;;36228:34:4;36210:52;;36268:12;36283:23;36288:6;-1:-1:-1;;;;;36283:23:4;36296:9;-1:-1:-1;;;;;36283:23:4;:4;:23::i;:::-;36268:38;;36323:7;36316:4;:14;36312:98;;;36356:24;36361:9;-1:-1:-1;;;;;36356:24:4;36372:7;36356:4;:24::i;:::-;36340:41;;36396:7;36389:14;;36312:98;36477:22;36502:24;36507:12;;36521:4;36502;:24::i;:::-;36477:49;;1945:5:0;36536:14:4;:33;36532:46;;;36571:7;;;;;;;36532:46;36583:12;:29;;;-1:-1:-1;;;;;36688:22:4;;:13;;;:22;;;-1:-1:-1;;;;;36749:15:4;;;;;;:8;:15;;;;;;;:31;;-1:-1:-1;;;;;;;;36749:31:4;-1:-1:-1;;;36749:31:4;;;;;;;-1:-1:-1;;36786:46:4;;36828:3;36786:46;;;;;;;36843:33;;-1:-1:-1;;;;;;;;;;;36843:33:4;;;36688:22;;36843:33;:::i;:::-;;;;;;;;35796:1085;;;;;;;:::o;682:91:2:-;732:7;1260:6:0;754:7:2;759:1;754:4;:7::i;:::-;:14;;682:91;-1:-1:-1;;682:91:2:o;595:83::-;1260:6:0;665:8:2;;;595:83::o;1946:248::-;2006:7;;2037:1;2033;:5;:21;;1260:6:0;2033:21:2;;;2046:1;2033:21;2021:33;-1:-1:-1;2071:1:2;2066:6;;;;2061:115;2074:6;;2061:115;;2102:10;2107:1;2110;2102:4;:10::i;:::-;2098:14;-1:-1:-1;2129:1:2;2125;:5;:10;2121:49;;2151:10;2156:1;2159;2151:4;:10::i;:::-;2147:14;;2121:49;2087:1;2082:6;;;;2061:115;;2836:937;2941:7;2983:3;2941:7;;3017:20;3026:4;1260:6:0;3017:8:2;:20::i;:::-;2992:45;;-1:-1:-1;2992:45:2;-1:-1:-1;1260:6:0;;3043:12:2;3345:1;3328:424;3356:9;3348:4;:17;3328:424;;3380:12;1260:6:0;3395:1:2;:8;3380:23;;3412:9;3423;3436:29;3445:1;3448:16;3453:4;1260:6:0;3448:4:2;:16::i;:::-;3436:8;:29::i;:::-;3411:54;;;;3480:22;3485:4;3491:10;3496:1;3499;3491:4;:10::i;3480:22::-;3473:29;;3517:16;3522:4;3528;3517;:16::i;:::-;3510:23;-1:-1:-1;3545:9:2;3541:20;;3556:5;;;;;3541:20;3574:4;3570:30;;;3591:9;;;3570:30;3612:4;3608:30;;;3629:9;;;3608:30;3650:8;3646:100;;;3676:15;3681:3;3686:4;3676;:15::i;:::-;3670:21;;3646:100;;;3722:15;3727:3;3732:4;3722;:15::i;:::-;3716:21;;3646:100;-1:-1:-1;;;3367:3:2;;3328:424;;;-1:-1:-1;3765:3:2;;2836:937;-1:-1:-1;;;;;;;;;2836:937:2:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;49255:54;;50250:35;;50240:2;;50299:1;;50289:12;160:352;;;290:3;283:4;275:6;271:17;267:27;257:2;;-1:-1;;298:12;257:2;-1:-1;328:20;;368:18;357:30;;354:2;;;-1:-1;;390:12;354:2;434:4;426:6;422:17;410:29;;485:3;434:4;;469:6;465:17;426:6;451:32;;448:41;445:2;;;502:1;;492:12;1555:337;;;1670:3;1663:4;1655:6;1651:17;1647:27;1637:2;;-1:-1;;1678:12;1637:2;-1:-1;1708:20;;1748:18;1737:30;;1734:2;;;-1:-1;;1770:12;1734:2;1814:4;1806:6;1802:17;1790:29;;1865:3;1814:4;1845:17;1806:6;1831:32;;1828:41;1825:2;;;1882:1;;1872:12;2313:241;;2417:2;2405:9;2396:7;2392:23;2388:32;2385:2;;;-1:-1;;2423:12;2385:2;2485:53;2530:7;2506:22;2485:53;:::i;2561:366::-;;;2682:2;2670:9;2661:7;2657:23;2653:32;2650:2;;;-1:-1;;2688:12;2650:2;2750:53;2795:7;2771:22;2750:53;:::i;:::-;2740:63;;2858:53;2903:7;2840:2;2883:9;2879:22;2858:53;:::i;:::-;2848:63;;2644:283;;;;;:::o;2934:491::-;;;;3072:2;3060:9;3051:7;3047:23;3043:32;3040:2;;;-1:-1;;3078:12;3040:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;3130:63;-1:-1;3230:2;3269:22;;72:20;97:33;72:20;97:33;:::i;:::-;3034:391;;3238:63;;-1:-1;;;3338:2;3377:22;;;;1967:20;;3034:391::o;3432:743::-;;;;;;3610:2;3598:9;3589:7;3585:23;3581:32;3578:2;;;-1:-1;;3616:12;3578:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;3668:63;-1:-1;3796:2;3781:18;;3768:32;3820:18;3809:30;;;3806:2;;;-1:-1;;3842:12;3806:2;3880:65;3937:7;3928:6;3917:9;3913:22;3880:65;:::i;:::-;3862:83;;-1:-1;3862:83;-1:-1;4010:2;3995:18;;3982:32;;-1:-1;4023:30;;;4020:2;;;-1:-1;;4056:12;4020:2;;4094:65;4151:7;4142:6;4131:9;4127:22;4094:65;:::i;:::-;3572:603;;;;-1:-1;3572:603;;-1:-1;4076:83;;;3572:603;-1:-1;;;3572:603::o;4182:366::-;;;4303:2;4291:9;4282:7;4278:23;4274:32;4271:2;;;-1:-1;;4309:12;4271:2;4371:53;4416:7;4392:22;4371:53;:::i;:::-;4361:63;4461:2;4500:22;;;;1967:20;;-1:-1;;;4265:283::o;4555:743::-;;;;;;4727:3;4715:9;4706:7;4702:23;4698:33;4695:2;;;-1:-1;;4734:12;4695:2;4796:53;4841:7;4817:22;4796:53;:::i;:::-;4786:63;;4886:2;4929:9;4925:22;1967:20;4894:63;;5012:53;5057:7;4994:2;5037:9;5033:22;5012:53;:::i;:::-;4689:609;;;;-1:-1;5002:63;;5102:2;5141:22;;1967:20;;-1:-1;5210:3;5250:22;1967:20;;4689:609;-1:-1;;4689:609::o;5305:491::-;;;;5443:2;5431:9;5422:7;5418:23;5414:32;5411:2;;;-1:-1;;5449:12;5411:2;5511:53;5556:7;5532:22;5511:53;:::i;:::-;5501:63;5601:2;5640:22;;1967:20;;-1:-1;5709:2;5748:22;;;1967:20;;5405:391;-1:-1;;;5405:391::o;5803:1335::-;;;;;;;;;;6096:3;6084:9;6075:7;6071:23;6067:33;6064:2;;;-1:-1;;6103:12;6064:2;6161:17;6148:31;6199:18;;6191:6;6188:30;6185:2;;;-1:-1;;6221:12;6185:2;6259:80;6331:7;6322:6;6311:9;6307:22;6259:80;:::i;:::-;6241:98;;-1:-1;6241:98;-1:-1;6404:2;6389:18;;6376:32;;-1:-1;6417:30;;;6414:2;;;-1:-1;;6450:12;6414:2;6488:80;6560:7;6551:6;6540:9;6536:22;6488:80;:::i;:::-;6470:98;;-1:-1;6470:98;-1:-1;6633:2;6618:18;;6605:32;;-1:-1;6646:30;;;6643:2;;;-1:-1;;6679:12;6643:2;;6717:79;6788:7;6779:6;6768:9;6764:22;6717:79;:::i;:::-;6699:97;;-1:-1;6699:97;-1:-1;;6833:2;6872:22;;72:20;97:33;72:20;97:33;:::i;:::-;6841:63;-1:-1;6941:3;6981:22;;72:20;97:33;72:20;97:33;:::i;:::-;6950:63;-1:-1;7050:3;7090:22;;72:20;97:33;72:20;97:33;:::i;:::-;7059:63;;;;6058:1080;;;;;;;;;;;:::o;7145:676::-;;;;;7335:2;7323:9;7314:7;7310:23;7306:32;7303:2;;;-1:-1;;7341:12;7303:2;7399:17;7386:31;7437:18;;7429:6;7426:30;7423:2;;;-1:-1;;7459:12;7423:2;7497:80;7569:7;7560:6;7549:9;7545:22;7497:80;:::i;:::-;7479:98;;-1:-1;7479:98;-1:-1;7642:2;7627:18;;7614:32;;-1:-1;7655:30;;;7652:2;;;-1:-1;;7688:12;7652:2;;7726:79;7797:7;7788:6;7777:9;7773:22;7726:79;:::i;:::-;7297:524;;;;-1:-1;7708:97;-1:-1;;;;7297:524::o;7828:957::-;;;;;;;8070:2;8058:9;8049:7;8045:23;8041:32;8038:2;;;-1:-1;;8076:12;8038:2;8134:17;8121:31;8172:18;;8164:6;8161:30;8158:2;;;-1:-1;;8194:12;8158:2;8232:80;8304:7;8295:6;8284:9;8280:22;8232:80;:::i;:::-;8214:98;;-1:-1;8214:98;-1:-1;8377:2;8362:18;;8349:32;;-1:-1;8390:30;;;8387:2;;;-1:-1;;8423:12;8387:2;8461:79;8532:7;8523:6;8512:9;8508:22;8461:79;:::i;:::-;8443:97;;-1:-1;8443:97;-1:-1;8605:2;8590:18;;8577:32;;-1:-1;8618:30;;;8615:2;;;-1:-1;;8651:12;8615:2;;8689:80;8761:7;8752:6;8741:9;8737:22;8689:80;:::i;:::-;8032:753;;;;-1:-1;8032:753;;-1:-1;8032:753;;8671:98;;8032:753;-1:-1;;;8032:753::o;8792:235::-;;8893:2;8881:9;8872:7;8868:23;8864:32;8861:2;;;-1:-1;;8899:12;8861:2;1351:6;1338:20;1363:30;1387:5;1363:30;:::i;9034:257::-;;9146:2;9134:9;9125:7;9121:23;9117:32;9114:2;;;-1:-1;;9152:12;9114:2;1486:6;1480:13;1498:30;1522:5;1498:30;:::i;9298:241::-;;9402:2;9390:9;9381:7;9377:23;9373:32;9370:2;;;-1:-1;;9408:12;9370:2;-1:-1;1967:20;;9364:175;-1:-1;9364:175::o;9546:263::-;;9661:2;9649:9;9640:7;9636:23;9632:32;9629:2;;;-1:-1;;9667:12;9629:2;-1:-1;2115:13;;9623:186;-1:-1;9623:186::o;9816:522::-;;;;9972:2;9960:9;9951:7;9947:23;9943:32;9940:2;;;-1:-1;;9978:12;9940:2;1980:6;1967:20;10030:63;;10158:2;10147:9;10143:18;10130:32;10182:18;10174:6;10171:30;10168:2;;;-1:-1;;10204:12;10168:2;10242:80;10314:7;10305:6;10294:9;10290:22;10242:80;:::i;:::-;9934:404;;10224:98;;-1:-1;10224:98;;-1:-1;;;;9934:404::o;10345:239::-;;10448:2;10436:9;10427:7;10423:23;10419:32;10416:2;;;-1:-1;;10454:12;10416:2;2257:6;2244:20;-1:-1;;;;;50642:5;49646:38;50618:5;50615:34;50605:2;;-1:-1;;50653:12;27430:271;;12104:5;48078:12;12215:52;12260:6;12255:3;12248:4;12241:5;12237:16;12215:52;:::i;:::-;12279:16;;;;;27564:137;-1:-1;;27564:137::o;27708:222::-;-1:-1;;;;;49255:54;;;;10834:37;;27835:2;27820:18;;27806:124::o;27937:444::-;-1:-1;;;;;49255:54;;;10834:37;;49255:54;;;;28284:2;28269:18;;10834:37;28367:2;28352:18;;26698:37;;;;28120:2;28105:18;;28091:290::o;28388:333::-;-1:-1;;;;;49255:54;;;;10834:37;;28707:2;28692:18;;26698:37;28543:2;28528:18;;28514:207::o;28728:370::-;28905:2;28919:47;;;48078:12;;28890:18;;;48610:19;;;28728:370;;28905:2;47932:14;;;;48650;;;;28728:370;11442:260;11467:6;11464:1;11461:13;11442:260;;;11528:13;;-1:-1;;;;;49255:54;10834:37;;48465:14;;;;10745;;;;49266:42;11482:9;11442:260;;;-1:-1;28972:116;;28876:222;-1:-1;;;;;;28876:222::o;29105:210::-;49167:13;;49160:21;11787:34;;29226:2;29211:18;;29197:118::o;29322:310::-;;29469:2;29490:17;29483:47;12452:5;48078:12;48622:6;29469:2;29458:9;29454:18;48610:19;12546:52;12591:6;48650:14;29458:9;48650:14;29469:2;12572:5;12568:16;12546:52;:::i;:::-;50170:7;50154:14;-1:-1;;50150:28;12610:39;;;;48650:14;12610:39;;29440:192;-1:-1;;29440:192::o;29639:416::-;29839:2;29853:47;;;12886:2;29824:18;;;48610:19;-1:-1;;;48650:14;;;12902:41;12962:12;;;29810:245::o;30062:416::-;30262:2;30276:47;;;13213:2;30247:18;;;48610:19;-1:-1;;;48650:14;;;13229:35;13283:12;;;30233:245::o;30485:416::-;30685:2;30699:47;;;13534:2;30670:18;;;48610:19;-1:-1;;;48650:14;;;13550:37;13606:12;;;30656:245::o;30908:416::-;31108:2;31122:47;;;13857:2;31093:18;;;48610:19;-1:-1;;;48650:14;;;13873:39;13931:12;;;31079:245::o;31331:416::-;31531:2;31545:47;;;14182:2;31516:18;;;48610:19;-1:-1;;;48650:14;;;14198:40;14257:12;;;31502:245::o;31754:416::-;31954:2;31968:47;;;14508:2;31939:18;;;48610:19;-1:-1;;;48650:14;;;14524:38;14581:12;;;31925:245::o;32177:416::-;32377:2;32391:47;;;14832:2;32362:18;;;48610:19;-1:-1;;;48650:14;;;14848:37;14904:12;;;32348:245::o;32600:416::-;32800:2;32814:47;;;15155:2;32785:18;;;48610:19;-1:-1;;;48650:14;;;15171:43;15233:12;;;32771:245::o;33023:416::-;33223:2;33237:47;;;15484:2;33208:18;;;48610:19;-1:-1;;;48650:14;;;15500:36;15555:12;;;33194:245::o;33446:416::-;33646:2;33660:47;;;15806:2;33631:18;;;48610:19;-1:-1;;;48650:14;;;15822:38;15879:12;;;33617:245::o;33869:416::-;34069:2;34083:47;;;16130:2;34054:18;;;48610:19;-1:-1;;;48650:14;;;16146:43;16208:12;;;34040:245::o;34292:416::-;34492:2;34506:47;;;16459:2;34477:18;;;48610:19;-1:-1;;;48650:14;;;16475:38;16532:12;;;34463:245::o;34715:416::-;34915:2;34929:47;;;16783:2;34900:18;;;48610:19;-1:-1;;;48650:14;;;16799:39;16857:12;;;34886:245::o;35138:416::-;35338:2;35352:47;;;17108:2;35323:18;;;48610:19;-1:-1;;;48650:14;;;17124:44;17187:12;;;35309:245::o;35561:416::-;35761:2;35775:47;;;17438:2;35746:18;;;48610:19;-1:-1;;;48650:14;;;17454:35;17508:12;;;35732:245::o;35984:416::-;36184:2;36198:47;;;17759:2;36169:18;;;48610:19;-1:-1;;;48650:14;;;17775:45;17839:12;;;36155:245::o;36407:416::-;36607:2;36621:47;;;18090:2;36592:18;;;48610:19;-1:-1;;;48650:14;;;18106:34;18159:12;;;36578:245::o;36830:416::-;37030:2;37044:47;;;18410:2;37015:18;;;48610:19;-1:-1;;;48650:14;;;18426:40;18485:12;;;37001:245::o;37253:416::-;37453:2;37467:47;;;18736:2;37438:18;;;48610:19;-1:-1;;;48650:14;;;18752:36;18807:12;;;37424:245::o;37676:416::-;37876:2;37890:47;;;19058:2;37861:18;;;48610:19;-1:-1;;;48650:14;;;19074:40;19133:12;;;37847:245::o;38099:416::-;38299:2;38313:47;;;19384:2;38284:18;;;48610:19;-1:-1;;;48650:14;;;19400:37;19456:12;;;38270:245::o;38522:416::-;38722:2;38736:47;;;19707:2;38707:18;;;48610:19;-1:-1;;;48650:14;;;19723:42;19784:12;;;38693:245::o;38945:416::-;39145:2;39159:47;;;20035:2;39130:18;;;48610:19;-1:-1;;;48650:14;;;20051:37;20107:12;;;39116:245::o;39368:416::-;39568:2;39582:47;;;20358:2;39553:18;;;48610:19;-1:-1;;;48650:14;;;20374:39;20432:12;;;39539:245::o;39791:416::-;39991:2;40005:47;;;20683:2;39976:18;;;48610:19;-1:-1;;;48650:14;;;20699:34;20752:12;;;39962:245::o;40214:416::-;40414:2;40428:47;;;21003:1;40399:18;;;48610:19;-1:-1;;;48650:14;;;21018:32;21069:12;;;40385:245::o;40637:416::-;40837:2;40851:47;;;21320:2;40822:18;;;48610:19;-1:-1;;;48650:14;;;21336:38;21393:12;;;40808:245::o;41060:416::-;41260:2;41274:47;;;21644:2;41245:18;;;48610:19;-1:-1;;;48650:14;;;21660:37;21716:12;;;41231:245::o;41483:416::-;41683:2;41697:47;;;21967:2;41668:18;;;48610:19;-1:-1;;;48650:14;;;21983:35;22037:12;;;41654:245::o;41906:416::-;42106:2;42120:47;;;22288:2;42091:18;;;48610:19;-1:-1;;;48650:14;;;22304:44;22367:12;;;42077:245::o;42329:416::-;42529:2;42543:47;;;22618:2;42514:18;;;48610:19;-1:-1;;;48650:14;;;22634:38;22691:12;;;42500:245::o;42752:416::-;42952:2;42966:47;;;22942:2;42937:18;;;48610:19;-1:-1;;;48650:14;;;22958:40;23017:12;;;42923:245::o;43175:416::-;43375:2;43389:47;;;23268:2;43360:18;;;48610:19;-1:-1;;;48650:14;;;23284:39;23342:12;;;43346:245::o;43598:416::-;43798:2;43812:47;;;23593:2;43783:18;;;48610:19;-1:-1;;;48650:14;;;23609:39;23667:12;;;43769:245::o;44021:416::-;44221:2;44235:47;;;23918:2;44206:18;;;48610:19;-1:-1;;;48650:14;;;23934:38;23991:12;;;44192:245::o;44444:416::-;44644:2;44658:47;;;24242:2;44629:18;;;48610:19;-1:-1;;;48650:14;;;24258:37;24314:12;;;44615:245::o;44867:416::-;45067:2;45081:47;;;24565:2;45052:18;;;48610:19;-1:-1;;;48650:14;;;24581:45;24645:12;;;45038:245::o;45290:416::-;45490:2;45504:47;;;24896:2;45475:18;;;48610:19;-1:-1;;;48650:14;;;24912:34;24965:12;;;45461:245::o;45713:416::-;45913:2;45927:47;;;25216:2;45898:18;;;48610:19;-1:-1;;;48650:14;;;25232:43;25294:12;;;45884:245::o;46136:319::-;;46311:3;46300:9;46296:19;46288:27;;25593:16;25587:23;49167:13;49160:21;11794:3;11787:34;25753:4;25746:5;25742:16;25736:23;49167:13;49160:21;25753:4;25811:3;25807:14;11787:34;49472:12;25913:4;25906:5;25902:16;25896:23;49461:24;25913:4;25975:3;25971:14;26926:36;26067:4;26060:5;26056:16;26050:23;-1:-1;;;;;49657:26;27411:5;49646:38;26067:4;26129:3;26125:14;27382:36;49657:26;26228:4;26221:5;26217:16;26211:23;49646:38;26228:4;26290:3;26286:14;27382:36;;;49568:4;26381;26374:5;26370:16;26364:23;49557:16;26381:4;26441:3;26437:14;27031:35;26534:4;26527:5;26523:16;26517:23;26534:4;26598:3;26594:14;26698:37;46282:173;;;;:::o;46462:222::-;26698:37;;;46589:2;46574:18;;46560:124::o;46691:333::-;26698:37;;;47010:2;46995:18;;26698:37;46846:2;46831:18;;46817:207::o;47031:214::-;49568:4;49557:16;;;;27031:35;;47154:2;47139:18;;47125:120::o;47252:220::-;-1:-1;;;;;49646:38;;;;27262:49;;47378:2;47363:18;;47349:123::o;47479:331::-;-1:-1;;;;;49646:38;;;;27262:49;;47796:2;47781:18;;26698:37;47633:2;47618:18;;47604:206::o;49810:268::-;49875:1;49882:101;49896:6;49893:1;49890:13;49882:101;;;49963:11;;;49957:18;49944:11;;;49937:39;49918:2;49911:10;49882:101;;;49998:6;49995:1;49992:13;49989:2;;;49875:1;50054:6;50049:3;50045:16;50038:27;49989:2;;49859:219;;;:::o;50191:117::-;-1:-1;;;;;49255:54;;50250:35;;50240:2;;50299:1;;50289:12;50315:111;50396:5;49167:13;49160:21;50374:5;50371:32;50361:2;;50417:1;;50407:12
Swarm Source
ipfs://e82b157d45f4e522ea20b9bb4c0f872a13392a53a155ce16660632cb1b4c4bf4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.