Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Vyper_contract
- Optimization enabled
- true
- Compiler version
- v0.2.4+commit.7949850
- Verified at
- 2024-05-13T06:16:06.102278Z
Constructor Arguments
0x0000000000000000000000006e8f6d1da6232d5e40b0b8758a0145d6c5123eb70000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000006c3f90f043a72fa612cbac8115ee7e52bde6e490000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000003d09000000000000000000000000000000000000000000000000000000000000000000
Contract source code
# @version 0.2.4
# (c) Curve.Fi, 2020
# Pool for DAI/USDC/USDT
from vyper.interfaces import ERC20
interface CurveToken:
def totalSupply() -> uint256: view
def mint(_to: address, _value: uint256) -> bool: nonpayable
def burnFrom(_to: address, _value: uint256) -> bool: nonpayable
# Events
event TokenExchange:
buyer: indexed(address)
sold_id: int128
tokens_sold: uint256
bought_id: int128
tokens_bought: uint256
event AddLiquidity:
provider: indexed(address)
token_amounts: uint256[N_COINS]
fees: uint256[N_COINS]
invariant: uint256
token_supply: uint256
event RemoveLiquidity:
provider: indexed(address)
token_amounts: uint256[N_COINS]
fees: uint256[N_COINS]
token_supply: uint256
event RemoveLiquidityOne:
provider: indexed(address)
token_amount: uint256
coin_amount: uint256
event RemoveLiquidityImbalance:
provider: indexed(address)
token_amounts: uint256[N_COINS]
fees: uint256[N_COINS]
invariant: uint256
token_supply: uint256
event CommitNewAdmin:
deadline: indexed(uint256)
admin: indexed(address)
event NewAdmin:
admin: indexed(address)
event CommitNewFee:
deadline: indexed(uint256)
fee: uint256
admin_fee: uint256
event NewFee:
fee: uint256
admin_fee: uint256
event RampA:
old_A: uint256
new_A: uint256
initial_time: uint256
future_time: uint256
event StopRampA:
A: uint256
t: uint256
# This can (and needs to) be changed at compile time
N_COINS: constant(int128) = 3 # <- change
FEE_DENOMINATOR: constant(uint256) = 10 ** 10
LENDING_PRECISION: constant(uint256) = 10 ** 18
PRECISION: constant(uint256) = 10 ** 18 # The precision to convert to
PRECISION_MUL: constant(uint256[N_COINS]) = [1, 1000000000000, 1000000000000]
RATES: constant(uint256[N_COINS]) = [1000000000000000000, 1000000000000000000000000000000, 1000000000000000000000000000000]
FEE_INDEX: constant(int128) = 2 # Which coin may potentially have fees (USDT)
MAX_ADMIN_FEE: constant(uint256) = 10 * 10 ** 9
MAX_FEE: constant(uint256) = 5 * 10 ** 9
MAX_A: constant(uint256) = 10 ** 6
MAX_A_CHANGE: constant(uint256) = 10
ADMIN_ACTIONS_DELAY: constant(uint256) = 3 * 86400
MIN_RAMP_TIME: constant(uint256) = 86400
coins: public(address[N_COINS])
balances: public(uint256[N_COINS])
fee: public(uint256) # fee * 1e10
admin_fee: public(uint256) # admin_fee * 1e10
owner: public(address)
token: CurveToken
initial_A: public(uint256)
future_A: public(uint256)
initial_A_time: public(uint256)
future_A_time: public(uint256)
admin_actions_deadline: public(uint256)
transfer_ownership_deadline: public(uint256)
future_fee: public(uint256)
future_admin_fee: public(uint256)
future_owner: public(address)
is_killed: bool
kill_deadline: uint256
KILL_DEADLINE_DT: constant(uint256) = 2 * 30 * 86400
@external
def __init__(
_owner: address,
_coins: address[N_COINS],
_pool_token: address,
_A: uint256,
_fee: uint256,
_admin_fee: uint256
):
"""
@notice Contract constructor
@param _owner Contract owner address
@param _coins Addresses of ERC20 conracts of coins
@param _pool_token Address of the token representing LP share
@param _A Amplification coefficient multiplied by n * (n - 1)
@param _fee Fee to charge for exchanges
@param _admin_fee Admin fee
"""
for i in range(N_COINS):
assert _coins[i] != ZERO_ADDRESS
self.coins = _coins
self.initial_A = _A
self.future_A = _A
self.fee = _fee
self.admin_fee = _admin_fee
self.owner = _owner
self.kill_deadline = block.timestamp + KILL_DEADLINE_DT
self.token = CurveToken(_pool_token)
@view
@internal
def _A() -> uint256:
"""
Handle ramping A up or down
"""
t1: uint256 = self.future_A_time
A1: uint256 = self.future_A
if block.timestamp < t1:
A0: uint256 = self.initial_A
t0: uint256 = self.initial_A_time
# Expressions in uint256 cannot have negative numbers, thus "if"
if A1 > A0:
return A0 + (A1 - A0) * (block.timestamp - t0) / (t1 - t0)
else:
return A0 - (A0 - A1) * (block.timestamp - t0) / (t1 - t0)
else: # when t1 == 0 or block.timestamp >= t1
return A1
@view
@external
def A() -> uint256:
return self._A()
@view
@internal
def _xp() -> uint256[N_COINS]:
result: uint256[N_COINS] = RATES
for i in range(N_COINS):
result[i] = result[i] * self.balances[i] / LENDING_PRECISION
return result
@pure
@internal
def _xp_mem(_balances: uint256[N_COINS]) -> uint256[N_COINS]:
result: uint256[N_COINS] = RATES
for i in range(N_COINS):
result[i] = result[i] * _balances[i] / PRECISION
return result
@pure
@internal
def get_D(xp: uint256[N_COINS], amp: uint256) -> uint256:
S: uint256 = 0
for _x in xp:
S += _x
if S == 0:
return 0
Dprev: uint256 = 0
D: uint256 = S
Ann: uint256 = amp * N_COINS
for _i in range(255):
D_P: uint256 = D
for _x in xp:
D_P = D_P * D / (_x * N_COINS) # If division by 0, this will be borked: only withdrawal will work. And that is good
Dprev = D
D = (Ann * S + D_P * N_COINS) * D / ((Ann - 1) * D + (N_COINS + 1) * D_P)
# Equality with the precision of 1
if D > Dprev:
if D - Dprev <= 1:
break
else:
if Dprev - D <= 1:
break
return D
@view
@internal
def get_D_mem(_balances: uint256[N_COINS], amp: uint256) -> uint256:
return self.get_D(self._xp_mem(_balances), amp)
@view
@external
def get_virtual_price() -> uint256:
"""
Returns portfolio virtual price (for calculating profit)
scaled up by 1e18
"""
D: uint256 = self.get_D(self._xp(), self._A())
# D is in the units similar to DAI (e.g. converted to precision 1e18)
# When balanced, D = n * x_u - total virtual value of the portfolio
token_supply: uint256 = self.token.totalSupply()
return D * PRECISION / token_supply
@view
@external
def calc_token_amount(amounts: uint256[N_COINS], deposit: bool) -> uint256:
"""
Simplified method to calculate addition or reduction in token supply at
deposit or withdrawal without taking fees into account (but looking at
slippage).
Needed to prevent front-running, not for precise calculations!
"""
_balances: uint256[N_COINS] = self.balances
amp: uint256 = self._A()
D0: uint256 = self.get_D_mem(_balances, amp)
for i in range(N_COINS):
if deposit:
_balances[i] += amounts[i]
else:
_balances[i] -= amounts[i]
D1: uint256 = self.get_D_mem(_balances, amp)
token_amount: uint256 = self.token.totalSupply()
diff: uint256 = 0
if deposit:
diff = D1 - D0
else:
diff = D0 - D1
return diff * token_amount / D0
@external
@nonreentrant('lock')
def add_liquidity(amounts: uint256[N_COINS], min_mint_amount: uint256):
assert not self.is_killed # dev: is killed
fees: uint256[N_COINS] = empty(uint256[N_COINS])
_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
_admin_fee: uint256 = self.admin_fee
amp: uint256 = self._A()
token_supply: uint256 = self.token.totalSupply()
# Initial invariant
D0: uint256 = 0
old_balances: uint256[N_COINS] = self.balances
if token_supply > 0:
D0 = self.get_D_mem(old_balances, amp)
new_balances: uint256[N_COINS] = old_balances
for i in range(N_COINS):
in_amount: uint256 = amounts[i]
if token_supply == 0:
assert in_amount > 0 # dev: initial deposit requires all coins
in_coin: address = self.coins[i]
# Take coins from the sender
if in_amount > 0:
if i == FEE_INDEX:
in_amount = ERC20(in_coin).balanceOf(self)
# "safeTransferFrom" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
in_coin,
concat(
method_id("transferFrom(address,address,uint256)"),
convert(msg.sender, bytes32),
convert(self, bytes32),
convert(amounts[i], bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
if i == FEE_INDEX:
in_amount = ERC20(in_coin).balanceOf(self) - in_amount
new_balances[i] = old_balances[i] + in_amount
# Invariant after change
D1: uint256 = self.get_D_mem(new_balances, amp)
assert D1 > D0
# We need to recalculate the invariant accounting for fees
# to calculate fair user's share
D2: uint256 = D1
if token_supply > 0:
# Only account for fees if we are not the first to deposit
for i in range(N_COINS):
ideal_balance: uint256 = D1 * old_balances[i] / D0
difference: uint256 = 0
if ideal_balance > new_balances[i]:
difference = ideal_balance - new_balances[i]
else:
difference = new_balances[i] - ideal_balance
fees[i] = _fee * difference / FEE_DENOMINATOR
self.balances[i] = new_balances[i] - (fees[i] * _admin_fee / FEE_DENOMINATOR)
new_balances[i] -= fees[i]
D2 = self.get_D_mem(new_balances, amp)
else:
self.balances = new_balances
# Calculate, how much pool tokens to mint
mint_amount: uint256 = 0
if token_supply == 0:
mint_amount = D1 # Take the dust if there was any
else:
mint_amount = token_supply * (D2 - D0) / D0
assert mint_amount >= min_mint_amount, "Slippage screwed you"
# Mint pool tokens
self.token.mint(msg.sender, mint_amount)
log AddLiquidity(msg.sender, amounts, fees, D1, token_supply + mint_amount)
@view
@internal
def get_y(i: int128, j: int128, x: uint256, xp_: uint256[N_COINS]) -> uint256:
# x in the input is converted to the same price/precision
assert i != j # dev: same coin
assert j >= 0 # dev: j below zero
assert j < N_COINS # dev: j above N_COINS
# should be unreachable, but good for safety
assert i >= 0
assert i < N_COINS
amp: uint256 = self._A()
D: uint256 = self.get_D(xp_, amp)
c: uint256 = D
S_: uint256 = 0
Ann: uint256 = amp * N_COINS
_x: uint256 = 0
for _i in range(N_COINS):
if _i == i:
_x = x
elif _i != j:
_x = xp_[_i]
else:
continue
S_ += _x
c = c * D / (_x * N_COINS)
c = c * D / (Ann * N_COINS)
b: uint256 = S_ + D / Ann # - D
y_prev: uint256 = 0
y: uint256 = D
for _i in range(255):
y_prev = y
y = (y*y + c) / (2 * y + b - D)
# Equality with the precision of 1
if y > y_prev:
if y - y_prev <= 1:
break
else:
if y_prev - y <= 1:
break
return y
@view
@external
def get_dy(i: int128, j: int128, dx: uint256) -> uint256:
# dx and dy in c-units
rates: uint256[N_COINS] = RATES
xp: uint256[N_COINS] = self._xp()
x: uint256 = xp[i] + (dx * rates[i] / PRECISION)
y: uint256 = self.get_y(i, j, x, xp)
dy: uint256 = (xp[j] - y - 1) * PRECISION / rates[j]
_fee: uint256 = self.fee * dy / FEE_DENOMINATOR
return dy - _fee
@view
@external
def get_dy_underlying(i: int128, j: int128, dx: uint256) -> uint256:
# dx and dy in underlying units
xp: uint256[N_COINS] = self._xp()
precisions: uint256[N_COINS] = PRECISION_MUL
x: uint256 = xp[i] + dx * precisions[i]
y: uint256 = self.get_y(i, j, x, xp)
dy: uint256 = (xp[j] - y - 1) / precisions[j]
_fee: uint256 = self.fee * dy / FEE_DENOMINATOR
return dy - _fee
@external
@nonreentrant('lock')
def exchange(i: int128, j: int128, dx: uint256, min_dy: uint256):
assert not self.is_killed # dev: is killed
rates: uint256[N_COINS] = RATES
old_balances: uint256[N_COINS] = self.balances
xp: uint256[N_COINS] = self._xp_mem(old_balances)
# Handling an unexpected charge of a fee on transfer (USDT, PAXG)
dx_w_fee: uint256 = dx
input_coin: address = self.coins[i]
if i == FEE_INDEX:
dx_w_fee = ERC20(input_coin).balanceOf(self)
# "safeTransferFrom" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
input_coin,
concat(
method_id("transferFrom(address,address,uint256)"),
convert(msg.sender, bytes32),
convert(self, bytes32),
convert(dx, bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
if i == FEE_INDEX:
dx_w_fee = ERC20(input_coin).balanceOf(self) - dx_w_fee
x: uint256 = xp[i] + dx_w_fee * rates[i] / PRECISION
y: uint256 = self.get_y(i, j, x, xp)
dy: uint256 = xp[j] - y - 1 # -1 just in case there were some rounding errors
dy_fee: uint256 = dy * self.fee / FEE_DENOMINATOR
# Convert all to real units
dy = (dy - dy_fee) * PRECISION / rates[j]
assert dy >= min_dy, "Exchange resulted in fewer coins than expected"
dy_admin_fee: uint256 = dy_fee * self.admin_fee / FEE_DENOMINATOR
dy_admin_fee = dy_admin_fee * PRECISION / rates[j]
# Change balances exactly in same way as we change actual ERC20 coin amounts
self.balances[i] = old_balances[i] + dx_w_fee
# When rounding errors happen, we undercharge admin fee in favor of LP
self.balances[j] = old_balances[j] - dy - dy_admin_fee
# "safeTransfer" which works for ERC20s which return bool or not
_response = raw_call(
self.coins[j],
concat(
method_id("transfer(address,uint256)"),
convert(msg.sender, bytes32),
convert(dy, bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
log TokenExchange(msg.sender, i, dx, j, dy)
@external
@nonreentrant('lock')
def remove_liquidity(_amount: uint256, min_amounts: uint256[N_COINS]):
total_supply: uint256 = self.token.totalSupply()
amounts: uint256[N_COINS] = empty(uint256[N_COINS])
fees: uint256[N_COINS] = empty(uint256[N_COINS]) # Fees are unused but we've got them historically in event
for i in range(N_COINS):
value: uint256 = self.balances[i] * _amount / total_supply
assert value >= min_amounts[i], "Withdrawal resulted in fewer coins than expected"
self.balances[i] -= value
amounts[i] = value
# "safeTransfer" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
self.coins[i],
concat(
method_id("transfer(address,uint256)"),
convert(msg.sender, bytes32),
convert(value, bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
self.token.burnFrom(msg.sender, _amount) # dev: insufficient funds
log RemoveLiquidity(msg.sender, amounts, fees, total_supply - _amount)
@external
@nonreentrant('lock')
def remove_liquidity_imbalance(amounts: uint256[N_COINS], max_burn_amount: uint256):
assert not self.is_killed # dev: is killed
token_supply: uint256 = self.token.totalSupply()
assert token_supply != 0 # dev: zero total supply
_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
_admin_fee: uint256 = self.admin_fee
amp: uint256 = self._A()
old_balances: uint256[N_COINS] = self.balances
new_balances: uint256[N_COINS] = old_balances
D0: uint256 = self.get_D_mem(old_balances, amp)
for i in range(N_COINS):
new_balances[i] -= amounts[i]
D1: uint256 = self.get_D_mem(new_balances, amp)
fees: uint256[N_COINS] = empty(uint256[N_COINS])
for i in range(N_COINS):
ideal_balance: uint256 = D1 * old_balances[i] / D0
difference: uint256 = 0
if ideal_balance > new_balances[i]:
difference = ideal_balance - new_balances[i]
else:
difference = new_balances[i] - ideal_balance
fees[i] = _fee * difference / FEE_DENOMINATOR
self.balances[i] = new_balances[i] - (fees[i] * _admin_fee / FEE_DENOMINATOR)
new_balances[i] -= fees[i]
D2: uint256 = self.get_D_mem(new_balances, amp)
token_amount: uint256 = (D0 - D2) * token_supply / D0
assert token_amount != 0 # dev: zero tokens burned
token_amount += 1 # In case of rounding errors - make it unfavorable for the "attacker"
assert token_amount <= max_burn_amount, "Slippage screwed you"
self.token.burnFrom(msg.sender, token_amount) # dev: insufficient funds
for i in range(N_COINS):
if amounts[i] != 0:
# "safeTransfer" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
self.coins[i],
concat(
method_id("transfer(address,uint256)"),
convert(msg.sender, bytes32),
convert(amounts[i], bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
log RemoveLiquidityImbalance(msg.sender, amounts, fees, D1, token_supply - token_amount)
@view
@internal
def get_y_D(A_: uint256, i: int128, xp: uint256[N_COINS], D: uint256) -> uint256:
"""
Calculate x[i] if one reduces D from being calculated for xp to D
Done by solving quadratic equation iteratively.
x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
x_1**2 + b*x_1 = c
x_1 = (x_1**2 + c) / (2*x_1 + b)
"""
# x in the input is converted to the same price/precision
assert i >= 0 # dev: i below zero
assert i < N_COINS # dev: i above N_COINS
c: uint256 = D
S_: uint256 = 0
Ann: uint256 = A_ * N_COINS
_x: uint256 = 0
for _i in range(N_COINS):
if _i != i:
_x = xp[_i]
else:
continue
S_ += _x
c = c * D / (_x * N_COINS)
c = c * D / (Ann * N_COINS)
b: uint256 = S_ + D / Ann
y_prev: uint256 = 0
y: uint256 = D
for _i in range(255):
y_prev = y
y = (y*y + c) / (2 * y + b - D)
# Equality with the precision of 1
if y > y_prev:
if y - y_prev <= 1:
break
else:
if y_prev - y <= 1:
break
return y
@view
@internal
def _calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> (uint256, uint256):
# First, need to calculate
# * Get current D
# * Solve Eqn against y_i for D - _token_amount
amp: uint256 = self._A()
_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
precisions: uint256[N_COINS] = PRECISION_MUL
total_supply: uint256 = self.token.totalSupply()
xp: uint256[N_COINS] = self._xp()
D0: uint256 = self.get_D(xp, amp)
D1: uint256 = D0 - _token_amount * D0 / total_supply
xp_reduced: uint256[N_COINS] = xp
new_y: uint256 = self.get_y_D(amp, i, xp, D1)
dy_0: uint256 = (xp[i] - new_y) / precisions[i] # w/o fees
for j in range(N_COINS):
dx_expected: uint256 = 0
if j == i:
dx_expected = xp[j] * D1 / D0 - new_y
else:
dx_expected = xp[j] - xp[j] * D1 / D0
xp_reduced[j] -= _fee * dx_expected / FEE_DENOMINATOR
dy: uint256 = xp_reduced[i] - self.get_y_D(amp, i, xp_reduced, D1)
dy = (dy - 1) / precisions[i] # Withdraw less to account for rounding errors
return dy, dy_0 - dy
@view
@external
def calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> uint256:
return self._calc_withdraw_one_coin(_token_amount, i)[0]
@external
@nonreentrant('lock')
def remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_amount: uint256):
"""
Remove _amount of liquidity all in a form of coin i
"""
assert not self.is_killed # dev: is killed
dy: uint256 = 0
dy_fee: uint256 = 0
dy, dy_fee = self._calc_withdraw_one_coin(_token_amount, i)
assert dy >= min_amount, "Not enough coins removed"
self.balances[i] -= (dy + dy_fee * self.admin_fee / FEE_DENOMINATOR)
self.token.burnFrom(msg.sender, _token_amount) # dev: insufficient funds
# "safeTransfer" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
self.coins[i],
concat(
method_id("transfer(address,uint256)"),
convert(msg.sender, bytes32),
convert(dy, bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
log RemoveLiquidityOne(msg.sender, _token_amount, dy)
### Admin functions ###
@external
def ramp_A(_future_A: uint256, _future_time: uint256):
assert msg.sender == self.owner # dev: only owner
assert block.timestamp >= self.initial_A_time + MIN_RAMP_TIME
assert _future_time >= block.timestamp + MIN_RAMP_TIME # dev: insufficient time
_initial_A: uint256 = self._A()
assert (_future_A > 0) and (_future_A < MAX_A)
assert ((_future_A >= _initial_A) and (_future_A <= _initial_A * MAX_A_CHANGE)) or\
((_future_A < _initial_A) and (_future_A * MAX_A_CHANGE >= _initial_A))
self.initial_A = _initial_A
self.future_A = _future_A
self.initial_A_time = block.timestamp
self.future_A_time = _future_time
log RampA(_initial_A, _future_A, block.timestamp, _future_time)
@external
def stop_ramp_A():
assert msg.sender == self.owner # dev: only owner
current_A: uint256 = self._A()
self.initial_A = current_A
self.future_A = current_A
self.initial_A_time = block.timestamp
self.future_A_time = block.timestamp
# now (block.timestamp < t1) is always False, so we return saved A
log StopRampA(current_A, block.timestamp)
@external
def commit_new_fee(new_fee: uint256, new_admin_fee: uint256):
assert msg.sender == self.owner # dev: only owner
assert self.admin_actions_deadline == 0 # dev: active action
assert new_fee <= MAX_FEE # dev: fee exceeds maximum
assert new_admin_fee <= MAX_ADMIN_FEE # dev: admin fee exceeds maximum
_deadline: uint256 = block.timestamp + ADMIN_ACTIONS_DELAY
self.admin_actions_deadline = _deadline
self.future_fee = new_fee
self.future_admin_fee = new_admin_fee
log CommitNewFee(_deadline, new_fee, new_admin_fee)
@external
def apply_new_fee():
assert msg.sender == self.owner # dev: only owner
assert block.timestamp >= self.admin_actions_deadline # dev: insufficient time
assert self.admin_actions_deadline != 0 # dev: no active action
self.admin_actions_deadline = 0
_fee: uint256 = self.future_fee
_admin_fee: uint256 = self.future_admin_fee
self.fee = _fee
self.admin_fee = _admin_fee
log NewFee(_fee, _admin_fee)
@external
def revert_new_parameters():
assert msg.sender == self.owner # dev: only owner
self.admin_actions_deadline = 0
@external
def commit_transfer_ownership(_owner: address):
assert msg.sender == self.owner # dev: only owner
assert self.transfer_ownership_deadline == 0 # dev: active transfer
_deadline: uint256 = block.timestamp + ADMIN_ACTIONS_DELAY
self.transfer_ownership_deadline = _deadline
self.future_owner = _owner
log CommitNewAdmin(_deadline, _owner)
@external
def apply_transfer_ownership():
assert msg.sender == self.owner # dev: only owner
assert block.timestamp >= self.transfer_ownership_deadline # dev: insufficient time
assert self.transfer_ownership_deadline != 0 # dev: no active transfer
self.transfer_ownership_deadline = 0
_owner: address = self.future_owner
self.owner = _owner
log NewAdmin(_owner)
@external
def revert_transfer_ownership():
assert msg.sender == self.owner # dev: only owner
self.transfer_ownership_deadline = 0
@view
@external
def admin_balances(i: uint256) -> uint256:
return ERC20(self.coins[i]).balanceOf(self) - self.balances[i]
@external
def withdraw_admin_fees():
assert msg.sender == self.owner # dev: only owner
for i in range(N_COINS):
c: address = self.coins[i]
value: uint256 = ERC20(c).balanceOf(self) - self.balances[i]
if value > 0:
# "safeTransfer" which works for ERC20s which return bool or not
_response: Bytes[32] = raw_call(
c,
concat(
method_id("transfer(address,uint256)"),
convert(msg.sender, bytes32),
convert(value, bytes32),
),
max_outsize=32,
) # dev: failed transfer
if len(_response) > 0:
assert convert(_response, bool) # dev: failed transfer
@external
def donate_admin_fees():
assert msg.sender == self.owner # dev: only owner
for i in range(N_COINS):
self.balances[i] = ERC20(self.coins[i]).balanceOf(self)
@external
def kill_me():
assert msg.sender == self.owner # dev: only owner
assert self.kill_deadline > block.timestamp # dev: deadline has passed
self.is_killed = True
@external
def unkill_me():
assert msg.sender == self.owner # dev: only owner
self.is_killed = False
Contract ABI
[{"type":"event","name":"TokenExchange","inputs":[{"type":"address","name":"buyer","indexed":true},{"type":"int128","name":"sold_id","indexed":false},{"type":"uint256","name":"tokens_sold","indexed":false},{"type":"int128","name":"bought_id","indexed":false},{"type":"uint256","name":"tokens_bought","indexed":false}],"anonymous":false},{"type":"event","name":"AddLiquidity","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"invariant","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false},{"type":"event","name":"RemoveLiquidity","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false},{"type":"event","name":"RemoveLiquidityOne","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256","name":"token_amount","indexed":false},{"type":"uint256","name":"coin_amount","indexed":false}],"anonymous":false},{"type":"event","name":"RemoveLiquidityImbalance","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"invariant","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false},{"type":"event","name":"CommitNewAdmin","inputs":[{"type":"uint256","name":"deadline","indexed":true},{"type":"address","name":"admin","indexed":true}],"anonymous":false},{"type":"event","name":"NewAdmin","inputs":[{"type":"address","name":"admin","indexed":true}],"anonymous":false},{"type":"event","name":"CommitNewFee","inputs":[{"type":"uint256","name":"deadline","indexed":true},{"type":"uint256","name":"fee","indexed":false},{"type":"uint256","name":"admin_fee","indexed":false}],"anonymous":false},{"type":"event","name":"NewFee","inputs":[{"type":"uint256","name":"fee","indexed":false},{"type":"uint256","name":"admin_fee","indexed":false}],"anonymous":false},{"type":"event","name":"RampA","inputs":[{"type":"uint256","name":"old_A","indexed":false},{"type":"uint256","name":"new_A","indexed":false},{"type":"uint256","name":"initial_time","indexed":false},{"type":"uint256","name":"future_time","indexed":false}],"anonymous":false},{"type":"event","name":"StopRampA","inputs":[{"type":"uint256","name":"A","indexed":false},{"type":"uint256","name":"t","indexed":false}],"anonymous":false},{"type":"constructor","stateMutability":"nonpayable","outputs":[],"inputs":[{"type":"address","name":"_owner"},{"type":"address[3]","name":"_coins"},{"type":"address","name":"_pool_token"},{"type":"uint256","name":"_A"},{"type":"uint256","name":"_fee"},{"type":"uint256","name":"_admin_fee"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"A","inputs":[],"gas":5227},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"get_virtual_price","inputs":[],"gas":1133537},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"calc_token_amount","inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"bool","name":"deposit"}],"gas":4508776},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"add_liquidity","inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"uint256","name":"min_mint_amount"}],"gas":6954858},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"get_dy","inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"}],"gas":2673791},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"get_dy_underlying","inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"}],"gas":2673474},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"exchange","inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"},{"type":"uint256","name":"min_dy"}],"gas":2818066},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"remove_liquidity","inputs":[{"type":"uint256","name":"_amount"},{"type":"uint256[3]","name":"min_amounts"}],"gas":192846},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"remove_liquidity_imbalance","inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"uint256","name":"max_burn_amount"}],"gas":6951851},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"calc_withdraw_one_coin","inputs":[{"type":"uint256","name":"_token_amount"},{"type":"int128","name":"i"}],"gas":1102},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"remove_liquidity_one_coin","inputs":[{"type":"uint256","name":"_token_amount"},{"type":"int128","name":"i"},{"type":"uint256","name":"min_amount"}],"gas":4025523},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"ramp_A","inputs":[{"type":"uint256","name":"_future_A"},{"type":"uint256","name":"_future_time"}],"gas":151919},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stop_ramp_A","inputs":[],"gas":148637},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"commit_new_fee","inputs":[{"type":"uint256","name":"new_fee"},{"type":"uint256","name":"new_admin_fee"}],"gas":110461},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"apply_new_fee","inputs":[],"gas":97242},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revert_new_parameters","inputs":[],"gas":21895},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"commit_transfer_ownership","inputs":[{"type":"address","name":"_owner"}],"gas":74572},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"apply_transfer_ownership","inputs":[],"gas":60710},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revert_transfer_ownership","inputs":[],"gas":21985},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"admin_balances","inputs":[{"type":"uint256","name":"i"}],"gas":3481},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw_admin_fees","inputs":[],"gas":21502},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"donate_admin_fees","inputs":[],"gas":111389},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"kill_me","inputs":[],"gas":37998},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unkill_me","inputs":[],"gas":22135},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"coins","inputs":[{"type":"uint256","name":"arg0"}],"gas":2220},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"balances","inputs":[{"type":"uint256","name":"arg0"}],"gas":2250},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"fee","inputs":[],"gas":2171},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"admin_fee","inputs":[],"gas":2201},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"gas":2231},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"initial_A","inputs":[],"gas":2261},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"future_A","inputs":[],"gas":2291},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"initial_A_time","inputs":[],"gas":2321},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"future_A_time","inputs":[],"gas":2351},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"admin_actions_deadline","inputs":[],"gas":2381},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"transfer_ownership_deadline","inputs":[],"gas":2411},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"future_fee","inputs":[],"gas":2441},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"future_admin_fee","inputs":[],"gas":2471},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"future_owner","inputs":[],"gas":2501}]
Contract Creation Code
0x740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a0526101006154cf6101403934156100a257600080fd5b60206154cf60c03960c05160205181106100bb57600080fd5b50602060206154cf0160c03960c05160205181106100d857600080fd5b50602060406154cf0160c03960c05160205181106100f557600080fd5b50602060606154cf0160c03960c051602051811061011257600080fd5b50602060806154cf0160c03960c051602051811061012f57600080fd5b5061024060006003818352015b6000610160610240516003811061015257600080fd5b60200201511861016157600080fd5b5b815160010180835281141561013c575b5050600060c052602060c02061016080518255806020015160018301558060400151600283015550506101e0516006556101e05160075561020051600255610220516003556101405160045542624f1a008181830110156101d257600080fd5b808201905090506010556101c0516005556154b756600436101561000d576152c9565b600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610244575b61014052600954610160526007546101805261016051421015610231576006546101c0526008546101e0526101c05161018051111561018a576101c051610180516101c051808210156100fb57600080fd5b80820390509050426101e0518082101561011457600080fd5b80820390509050808202821582848304141761012f57600080fd5b80905090509050610160516101e0518082101561014b57600080fd5b80820390509050808061015d57600080fd5b82049050905081818301101561017257600080fd5b8082019050905060005260005161014051565061022c565b6101c0516101c05161018051808210156101a357600080fd5b80820390509050426101e051808210156101bc57600080fd5b8082039050905080820282158284830414176101d757600080fd5b80905090509050610160516101e051808210156101f357600080fd5b80820390509050808061020557600080fd5b8204905090508082101561021857600080fd5b808203905090506000526000516101405156505b610242565b610180516000526000516101405156505b005b63f446c1d0600051141561027957341561025d57600080fd5b600658016100a9565b610140526101405160005260206000f350005b600015610399575b61014052610160670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101c060006003818352015b6101606101c051600381106102da57600080fd5b60200201516101c051600381106102f057600080fd5b600160c052602060c0200154808202821582848304141761031057600080fd5b80905090509050670de0b6b3a7640000808061032b57600080fd5b8204905090506101606101c0516003811061034557600080fd5b60200201525b81516001018083528114156102c6575b505060606101e0525b60006101e05111151561037657610392565b60206101e05103610160015160206101e051036101e052610364565b6101405156005b6000156104c1575b6101a0526101405261016052610180526101c0670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea4000000081604001525061022060006003818352015b6101c0610220516003811061040657600080fd5b6020020151610140610220516003811061041f57600080fd5b6020020151808202821582848304141761043857600080fd5b80905090509050670de0b6b3a7640000808061045357600080fd5b8204905090506101c0610220516003811061046d57600080fd5b60200201525b81516001018083528114156103f2575b50506060610240525b60006102405111151561049e576104ba565b602061024051036101c00151602061024051036102405261048c565b6101a05156005b6000156107af575b6101c0526101405261016052610180526101a05260006101e05261022060006003818352015b602061022051026101400151610200526101e080516102005181818301101561051757600080fd5b808201905090508152505b81516001018083528114156104ef575b50506101e051151561054d5760006000526000516101c05156505b6000610260526101e051610280526101a0516003808202821582848304141761057557600080fd5b809050905090506102a0526102c0600060ff818352015b610280516102e05261032060006003818352015b602061032051026101400151610300526102e0516102805180820282158284830414176105cc57600080fd5b8090509050905061030051600380820282158284830414176105ed57600080fd5b8090509050905080806105ff57600080fd5b8204905090506102e0525b81516001018083528114156105a0575b505061028051610260526102a0516101e051808202821582848304141761064057600080fd5b809050905090506102e0516003808202821582848304141761066157600080fd5b8090509050905081818301101561067757600080fd5b8082019050905061028051808202821582848304141761069657600080fd5b809050905090506102a0516001808210156106b057600080fd5b808203905090506102805180820282158284830414176106cf57600080fd5b8090509050905060046102e05180820282158284830414176106f057600080fd5b8090509050905081818301101561070657600080fd5b80820190509050808061071857600080fd5b820490509050610280526102605161028051111561075f57600161028051610260518082101561074757600080fd5b8082039050905011151561075a5761079b565b61078a565b600161026051610280518082101561077657600080fd5b808203905090501115156107895761079b565b5b5b815160010180835281141561058c575b5050610280516000526000516101c0515650005b60001561090d575b6101c0526101405261016052610180526101a052610140610420525b610420515160206104205101610420526104206104205110156107f5576107d3565b610440610140610300525b6103005151602061030051016103005261030061030051101561082257610800565b6103206101408051825280602001518260200152806040015182604001525050610360516103405161032051600658016103a1565b6103c0526103e052610400526102e0610300525b610300515260206103005103610300526101406103005110151561088e5761086b565b6103c080518252806020015182602001528060400151826040015250506101a0516104a0526104a051610480516104605161044051600658016104c9565b61050052610400610420525b61042051526020610420510361042052610140610420511015156108fb576108d8565b610500516000526000516101c0515650005b63bb7b8b806000511415610af857341561092657600080fd5b6101406102e0525b6102e0515160206102e051016102e0526102e06102e05110156109505761092e565b6103006101405161016051610180516101a0516101c0516101e0516102005160065801610281565b610240526102605261028052610200526101e0526101c0526101a05261018052610160526101405261024080518252806020015182602001528060400151826040015250506101406102a0525b6102a0515160206102a051016102a0526102a06102a05110156109e7576109c5565b600658016100a9565b6102c0526102806102a0525b6102a0515260206102a051036102a0526101406102a051101515610a1f576109fc565b6102c0516103605261036051610340516103205161030051600658016104c9565b6103c0526102c06102e0525b6102e0515260206102e051036102e0526101406102e051101515610a6f57610a4c565b6103c05161014052602061046060046318160ddd6104005261041c6005545afa610a9857600080fd5b601f3d11610aa557600080fd5b600050610460516103e05261014051670de0b6b3a76400008082028215828483041417610ad157600080fd5b809050905090506103e0518080610ae757600080fd5b82049050905060005260206000f350005b633883e1196000511415610e46573415610b1157600080fd5b60643560028110610b2157600080fd5b5061014060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506101405161016051610180516101a051600658016100a9565b6101e0526101a0526101805261016052610140526101e0516101a0526101405161016051610180516101a0516101c0516101e0516102005161024061014080518252806020015182602001528060400151826040015250506101a0516102a0526102a051610280516102605161024051600658016107b7565b61030052610200526101e0526101c0526101a052610180526101605261014052610300516102005261032060006003818352015b60643515610c77576101406103205160038110610c3b57600080fd5b60200201805160046103205160038110610c5457600080fd5b6020020135818183011015610c6857600080fd5b80820190509050815250610cc1565b6101406103205160038110610c8b57600080fd5b60200201805160046103205160038110610ca457600080fd5b602002013580821015610cb657600080fd5b808203905090508152505b5b8151600101808352811415610c1f575b5050610140610360525b61036051516020610360510161036052610360610360511015610cfe57610cdc565b61038061014080518252806020015182602001528060400151826040015250506101a0516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b6103605152602061036051036103605261014061036051101515610d6e57610d4b565b610440516103405260206104e060046318160ddd6104805261049c6005545afa610d9757600080fd5b601f3d11610da457600080fd5b6000506104e0516104605260006105005260643515610de257610340516102005180821015610dd257600080fd5b8082039050905061050052610e03565b610200516103405180821015610df757600080fd5b80820390509050610500525b61050051610460518082028215828483041417610e1f57600080fd5b80905090509050610200518080610e3557600080fd5b82049050905060005260206000f350005b634515cef3600051141561189c5762ffffff5415610e6357600080fd5b600162ffffff553415610e7557600080fd5b600f5415610e8257600080fd5b6060366101403760025460038082028215828483041417610ea257600080fd5b8090509050905060088080610eb657600080fd5b8204905090506101a0526003546101c0526101405161016051610180516101a0516101c0516101e051600658016100a9565b610220526101e0526101c0526101a052610180526101605261014052610220516101e05260206102c060046318160ddd6102605261027c6005545afa610f2d57600080fd5b601f3d11610f3a57600080fd5b6000506102c0516102405260006102e05261030060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c020015482604001525050600061024051111561103157610140610360525b61036051516020610360510161036052610360610360511015610fb857610f96565b61038061030080518252806020015182602001528060400151826040015250506101e0516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b610360515260206103605103610360526101406103605110151561102857611005565b610440516102e0525b61046061030080518252806020015182602001528060400151826040015250506104c060006003818352015b60046104c0516003811061107057600080fd5b60200201356104e0526102405115156110945760006104e0511161109357600080fd5b5b6104c051600381106110a557600080fd5b600060c052602060c02001546105005260006104e05111156112d65760026104c051141561110d5760206105a060246370a0823161052052306105405261053c610500515afa6110f457600080fd5b601f3d1161110157600080fd5b6000506105a0516104e0525b60006004610620527f23b872dd000000000000000000000000000000000000000000000000000000006106405261062060048060208461068001018260208501600060045af1505080518201915050336020826106800101526020810190503060208261068001015260208101905060046104c0516003811061118f57600080fd5b6020020135602082610680010152602081019050806106805261068090508051602001806107408284600060045af16111c757600080fd5b50506020610820610740516107606000610500515af16111e657600080fd5b60203d808211156111f757806111f9565b815b90509050610800526108008051602001806105c08284600060045af161121e57600080fd5b505060006105c0511115611271576105c080602001516000825180602090131561124757600080fd5b809190121561125557600080fd5b806020036101000a8204905090509050151561127057600080fd5b5b60026104c05114156112d55760206108e060246370a0823161086052306108805261087c610500515afa6112a457600080fd5b601f3d116112b157600080fd5b6000506108e0516104e051808210156112c957600080fd5b808203905090506104e0525b5b6103006104c051600381106112ea57600080fd5b60200201516104e05181818301101561130257600080fd5b808201905090506104606104c0516003811061131d57600080fd5b60200201525b815160010180835281141561105d575b5050610140610920525b6109205151602061092051016109205261092061092051101561135f5761133d565b61094061046080518252806020015182602001528060400151826040015250506101e0516109a0526109a051610980516109605161094051600658016107b7565b610a0052610900610920525b61092051526020610920510361092052610140610920511015156113cf576113ac565b610a0051610900526102e05161090051116113e957600080fd5b61090051610a205260006102405111156116e357610a4060006003818352015b61090051610300610a40516003811061142157600080fd5b6020020151808202821582848304141761143a57600080fd5b809050905090506102e051808061145057600080fd5b820490509050610a60526000610a8052610460610a40516003811061147457600080fd5b6020020151610a605111156114bd57610a6051610460610a40516003811061149b57600080fd5b6020020151808210156114ad57600080fd5b80820390509050610a80526114f3565b610460610a4051600381106114d157600080fd5b6020020151610a6051808210156114e757600080fd5b80820390509050610a80525b6101a051610a8051808202821582848304141761150f57600080fd5b809050905090506402540be400808061152757600080fd5b820490509050610140610a40516003811061154157600080fd5b6020020152610460610a40516003811061155a57600080fd5b6020020151610140610a40516003811061157357600080fd5b60200201516101c051808202821582848304141761159057600080fd5b809050905090506402540be40080806115a857600080fd5b820490509050808210156115bb57600080fd5b80820390509050610a4051600381106115d357600080fd5b600160c052602060c0200155610460610a4051600381106115f357600080fd5b602002018051610140610a40516003811061160d57600080fd5b60200201518082101561161f57600080fd5b808203905090508152505b8151600101808352811415611409575b5050610140610aa0525b610aa051516020610aa05101610aa052610a40610aa051101561166657611644565b610ac061046080518252806020015182602001528060400151826040015250506101e051610b2052610b2051610b0051610ae051610ac051600658016107b7565b610b8052610a20610aa0525b610aa051526020610aa05103610aa052610140610aa0511015156116d6576116b3565b610b8051610a205261170b565b600160c052602060c02061046080518255806020015160018301558060400151600283015550505b6000610ba0526102405115156117285761090051610ba05261177d565b61024051610a20516102e0518082101561174157600080fd5b80820390509050808202821582848304141761175c57600080fd5b809050905090506102e051808061177257600080fd5b820490509050610ba0525b6308c379a0610bc0526020610be0526014610c00527f536c697070616765207363726577656420796f75000000000000000000000000610c2052610c0050606435610ba05110156117cf576064610bdcfd5b6020610d0060446340c10f19610c605233610c8052610ba051610ca052610c7c60006005545af16117ff57600080fd5b601f3d1161180c57600080fd5b600050610d0050600435610d2052602435610d4052604435610d605261014051610d805261016051610da05261018051610dc05261090051610de05261024051610ba05181818301101561185f57600080fd5b80820190509050610e0052337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d610100610d20a2600062ffffff55005b600015611d13575b610200526101405261016052610180526101a0526101c0526101e0526101605161014051186118d257600080fd5b60006101605112156118e357600080fd5b600361016051126118f357600080fd5b600061014051121561190457600080fd5b6003610140511261191457600080fd5b6101405161016051610180516101a0516101c0516101e0516102005161022051600658016100a9565b6102605261022052610200526101e0526101c0526101a05261018052610160526101405261026051610220526101406102a0525b6102a0515160206102a051016102a0526102a06102a051101561199357611971565b6102c06101a08051825280602001518260200152806040015182604001525050610220516103205261032051610300516102e0516102c051600658016104c9565b610380526102806102a0525b6102a0515260206102a051036102a0526101406102a051101515611a03576119e0565b6103805161028052610280516103a05260006103c0526102205160038082028215828483041417611a3357600080fd5b809050905090506103e05260006104005261042060006003818352015b61014051610420511415611a6b576101805161040052611aa1565b61016051610420511815611a9b576101a06104205160038110611a8d57600080fd5b602002015161040052611aa0565b611b1d565b5b6103c0805161040051818183011015611ab957600080fd5b808201905090508152506103a051610280518082028215828483041417611adf57600080fd5b809050905090506104005160038082028215828483041417611b0057600080fd5b809050905090508080611b1257600080fd5b8204905090506103a0525b8151600101808352811415611a50575b50506103a051610280518082028215828483041417611b4b57600080fd5b809050905090506103e05160038082028215828483041417611b6c57600080fd5b809050905090508080611b7e57600080fd5b8204905090506103a0526103c051610280516103e0518080611b9f57600080fd5b820490509050818183011015611bb457600080fd5b808201905090506104405260006104605261028051610480526104a0600060ff818352015b610480516104605261048051610480518082028215828483041417611bfd57600080fd5b809050905090506103a051818183011015611c1757600080fd5b808201905090506002610480518082028215828483041417611c3857600080fd5b8090509050905061044051818183011015611c5257600080fd5b808201905090506102805180821015611c6a57600080fd5b808203905090508080611c7c57600080fd5b8204905090506104805261046051610480511115611cc3576001610480516104605180821015611cab57600080fd5b80820390509050111515611cbe57611cff565b611cee565b6001610460516104805180821015611cda57600080fd5b80820390509050111515611ced57611cff565b5b5b8151600101808352811415611bd9575b505061048051600052600051610200515650005b635e0d443f6000511415612045573415611d2c57600080fd5b60605160043580604051901315611d4257600080fd5b8091901215611d5057600080fd5b5060605160243580604051901315611d6757600080fd5b8091901215611d7557600080fd5b50610140670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101a06101405161016051610180516101a0516101c0516101e05160065801610281565b6102205261024052610260526101e0526101c0526101a05261018052610160526101405261022080518252806020015182602001528060400151826040015250506101a060043560038110611e2357600080fd5b602002015160443561014060043560038110611e3e57600080fd5b60200201518082028215828483041417611e5757600080fd5b80905090509050670de0b6b3a76400008080611e7257600080fd5b820490509050818183011015611e8757600080fd5b80820190509050610280526101406102c0525b6102c0515160206102c051016102c0526102c06102c0511015611ebc57611e9a565b6004356102e0526024356103005261028051610320526103406101a0805182528060200151826020015280604001518260400152505061038051610360516103405161032051610300516102e051600658016118a4565b6103e0526102a06102c0525b6102c0515260206102c051036102c0526101406102c051101515611f4257611f1f565b6103e0516102a0526101a060243560038110611f5d57600080fd5b60200201516102a05180821015611f7357600080fd5b80820390509050600180821015611f8957600080fd5b80820390509050670de0b6b3a76400008082028215828483041417611fad57600080fd5b8090509050905061014060243560038110611fc757600080fd5b60200201518080611fd757600080fd5b82049050905061040052600254610400518082028215828483041417611ffc57600080fd5b809050905090506402540be400808061201457600080fd5b8204905090506104205261040051610420518082101561203357600080fd5b8082039050905060005260206000f350005b6307211ef7600051141561230a57341561205e57600080fd5b6060516004358060405190131561207457600080fd5b809190121561208257600080fd5b506060516024358060405190131561209957600080fd5b80919012156120a757600080fd5b5061014061014051610160516101805160065801610281565b6101c0526101e052610200526101805261016052610140526101c080518252806020015182602001528060400151826040015250506102206001815264e8d4a51000816020015264e8d4a510008160400152506101406004356003811061212657600080fd5b60200201516044356102206004356003811061214157600080fd5b6020020151808202821582848304141761215a57600080fd5b8090509050905081818301101561217057600080fd5b80820190509050610280526101406102c0525b6102c0515160206102c051016102c0526102c06102c05110156121a557612183565b6004356102e052602435610300526102805161032052610340610140805182528060200151826020015280604001518260400152505061038051610360516103405161032051610300516102e051600658016118a4565b6103e0526102a06102c0525b6102c0515260206102c051036102c0526101406102c05110151561222b57612208565b6103e0516102a0526101406024356003811061224657600080fd5b60200201516102a0518082101561225c57600080fd5b8082039050905060018082101561227257600080fd5b808203905090506102206024356003811061228c57600080fd5b6020020151808061229c57600080fd5b820490509050610400526002546104005180820282158284830414176122c157600080fd5b809050905090506402540be40080806122d957600080fd5b820490509050610420526104005161042051808210156122f857600080fd5b8082039050905060005260206000f350005b633df021246000511415612c595762ffffff541561232757600080fd5b600162ffffff55341561233957600080fd5b6060516004358060405190131561234f57600080fd5b809190121561235d57600080fd5b506060516024358060405190131561237457600080fd5b809190121561238257600080fd5b50600f541561239057600080fd5b610140670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101a060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506102006101405161016051610180516101a0516101c0516101e0516102005161022051610240516102806101a080518252806020015182602001528060400151826040015250506102c0516102a05161028051600658016103a1565b6103205261034052610360526102405261022052610200526101e0526101c0526101a052610180526101605261014052610320805182528060200151826020015280604001518260400152505060443561038052600435600381106124bc57600080fd5b600060c052602060c02001546103a0526002600435141561251757602061044060246370a082316103c052306103e0526103dc6103a0515afa6124fe57600080fd5b601f3d1161250b57600080fd5b60005061044051610380525b600060046104c0527f23b872dd000000000000000000000000000000000000000000000000000000006104e0526104c060048060208461052001018260208501600060045af15050805182019150503360208261052001015260208101905030602082610520010152602081019050604435602082610520010152602081019050806105205261052090508051602001806105e08284600060045af16125bc57600080fd5b505060206106c06105e05161060060006103a0515af16125db57600080fd5b60203d808211156125ec57806125ee565b815b905090506106a0526106a08051602001806104608284600060045af161261357600080fd5b505060006104605111156126665761046080602001516000825180602090131561263c57600080fd5b809190121561264a57600080fd5b806020036101000a8204905090509050151561266557600080fd5b5b600260043514156126c957602061078060246370a0823161070052306107205261071c6103a0515afa61269857600080fd5b601f3d116126a557600080fd5b6000506107805161038051808210156126bd57600080fd5b80820390509050610380525b610200600435600381106126dc57600080fd5b602002015161038051610140600435600381106126f857600080fd5b6020020151808202821582848304141761271157600080fd5b80905090509050670de0b6b3a7640000808061272c57600080fd5b82049050905081818301101561274157600080fd5b808201905090506107a0526101406107e0525b6107e0515160206107e051016107e0526107e06107e051101561277657612754565b60043561080052602435610820526107a0516108405261086061020080518252806020015182602001528060400151826040015250506108a0516108805161086051610840516108205161080051600658016118a4565b610900526107c06107e0525b6107e0515260206107e051036107e0526101406107e0511015156127fc576127d9565b610900516107c0526102006024356003811061281757600080fd5b60200201516107c0518082101561282d57600080fd5b8082039050905060018082101561284357600080fd5b808203905090506109205261092051600254808202821582848304141761286957600080fd5b809050905090506402540be400808061288157600080fd5b820490509050610940526109205161094051808210156128a057600080fd5b80820390509050670de0b6b3a764000080820282158284830414176128c457600080fd5b80905090509050610140602435600381106128de57600080fd5b602002015180806128ee57600080fd5b820490509050610920526308c379a061096052602061098052602e6109a0527f45786368616e676520726573756c74656420696e20666577657220636f696e736109c0527f207468616e2065787065637465640000000000000000000000000000000000006109e0526109a05060643561092051101561296f57608461097cfd5b61094051600354808202821582848304141761298a57600080fd5b809050905090506402540be40080806129a257600080fd5b820490509050610a2052610a2051670de0b6b3a764000080820282158284830414176129cd57600080fd5b80905090509050610140602435600381106129e757600080fd5b602002015180806129f757600080fd5b820490509050610a20526101a060043560038110612a1457600080fd5b602002015161038051818183011015612a2c57600080fd5b8082019050905060043560038110612a4357600080fd5b600160c052602060c02001556101a060243560038110612a6257600080fd5b60200201516109205180821015612a7857600080fd5b80820390509050610a205180821015612a9057600080fd5b8082039050905060243560038110612aa757600080fd5b600160c052602060c020015560006004610a40527fa9059cbb00000000000000000000000000000000000000000000000000000000610a6052610a40600480602084610aa001018260208501600060045af150508051820191505033602082610aa001015260208101905061092051602082610aa001015260208101905080610aa052610aa09050805160200180610b408284600060045af1612b4957600080fd5b50506020610c00610b4051610b60600060243560038110612b6957600080fd5b600060c052602060c02001545af1612b8057600080fd5b60203d80821115612b915780612b93565b815b90509050610be052610be08051602001806104608284600060045af1612bb857600080fd5b50506000610460511115612c0b57610460806020015160008251806020901315612be157600080fd5b8091901215612bef57600080fd5b806020036101000a82049050905090501515612c0a57600080fd5b5b600435610c4052604435610c6052602435610c805261092051610ca052337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd971406080610c40a2600062ffffff55005b63ecb586a560005114156130405762ffffff5415612c7657600080fd5b600162ffffff553415612c8857600080fd5b60206101c060046318160ddd6101605261017c6005545afa612ca957600080fd5b601f3d11612cb657600080fd5b6000506101c051610140526060366101e037606036610240376102a060006003818352015b6102a05160038110612cec57600080fd5b600160c052602060c02001546004358082028215828483041417612d0f57600080fd5b80905090509050610140518080612d2557600080fd5b8204905090506102c0526308c379a06102e0526020610300526030610320527f5769746864726177616c20726573756c74656420696e20666577657220636f69610340527f6e73207468616e20657870656374656400000000000000000000000000000000610360526103205060246102a05160038110612da557600080fd5b60200201356102c0511015612dbb5760846102fcfd5b6102a05160038110612dcc57600080fd5b600160c052602060c0200180546102c05180821015612dea57600080fd5b808203905090508155506102c0516101e06102a05160038110612e0c57600080fd5b602002015260006004610400527fa9059cbb000000000000000000000000000000000000000000000000000000006104205261040060048060208461046001018260208501600060045af1505080518201915050336020826104600101526020810190506102c051602082610460010152602081019050806104605261046090508051602001806105008284600060045af1612ea757600080fd5b505060206105c06105005161052060006102a05160038110612ec857600080fd5b600060c052602060c02001545af1612edf57600080fd5b60203d80821115612ef05780612ef2565b815b905090506105a0526105a08051602001806103a08284600060045af1612f1757600080fd5b505060006103a0511115612f6a576103a0806020015160008251806020901315612f4057600080fd5b8091901215612f4e57600080fd5b806020036101000a82049050905090501515612f6957600080fd5b5b5b8151600101808352811415612cdb575b505060206106a060446379cc67906106005233610620526004356106405261061c60006005545af1612fac57600080fd5b601f3d11612fb957600080fd5b6000506106a0506101e0516106c052610200516106e0526102205161070052610240516107205261026051610740526102805161076052610140516004358082101561300457600080fd5b8082039050905061078052337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d60e06106c0a2600062ffffff55005b639fdaea0c60005114156139915762ffffff541561305d57600080fd5b600162ffffff55341561306f57600080fd5b600f541561307c57600080fd5b60206101c060046318160ddd6101605261017c6005545afa61309d57600080fd5b601f3d116130aa57600080fd5b6000506101c05161014052600061014051186130c557600080fd5b600254600380820282158284830414176130de57600080fd5b80905090509050600880806130f257600080fd5b8204905090506101e052600354610200526101405161016051610180516101a0516101c0516101e0516102005161022051600658016100a9565b6102605261022052610200526101e0526101c0526101a052610180526101605261014052610260516102205261028060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506102e06102808051825280602001518260200152806040015182604001525050610140610360525b610360515160206103605101610360526103606103605110156131d9576131b7565b6103806102808051825280602001518260200152806040015182604001525050610220516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b610360515260206103605103610360526101406103605110151561324957613226565b610440516103405261046060006003818352015b6102e0610460516003811061327157600080fd5b6020020180516004610460516003811061328a57600080fd5b60200201358082101561329c57600080fd5b808203905090508152505b815160010180835281141561325d575b50506101406104a0525b6104a0515160206104a051016104a0526104a06104a05110156132e3576132c1565b6104c06102e08051825280602001518260200152806040015182604001525050610220516105205261052051610500516104e0516104c051600658016107b7565b610580526104806104a0525b6104a0515260206104a051036104a0526101406104a05110151561335357613330565b61058051610480526060366105a03761060060006003818352015b61048051610280610600516003811061338657600080fd5b6020020151808202821582848304141761339f57600080fd5b809050905090506103405180806133b557600080fd5b820490509050610620526000610640526102e061060051600381106133d957600080fd5b602002015161062051111561342257610620516102e0610600516003811061340057600080fd5b60200201518082101561341257600080fd5b8082039050905061064052613458565b6102e0610600516003811061343657600080fd5b6020020151610620518082101561344c57600080fd5b80820390509050610640525b6101e05161064051808202821582848304141761347457600080fd5b809050905090506402540be400808061348c57600080fd5b8204905090506105a061060051600381106134a657600080fd5b60200201526102e061060051600381106134bf57600080fd5b60200201516105a061060051600381106134d857600080fd5b60200201516102005180820282158284830414176134f557600080fd5b809050905090506402540be400808061350d57600080fd5b8204905090508082101561352057600080fd5b80820390509050610600516003811061353857600080fd5b600160c052602060c02001556102e0610600516003811061355857600080fd5b6020020180516105a0610600516003811061357257600080fd5b60200201518082101561358457600080fd5b808203905090508152505b815160010180835281141561336e575b5050610140610680525b610680515160206106805101610680526106806106805110156135cb576135a9565b6106a06102e080518252806020015182602001528060400151826040015250506102205161070052610700516106e0516106c0516106a051600658016107b7565b61076052610660610680525b610680515260206106805103610680526101406106805110151561363b57613618565b610760516106605261034051610660518082101561365857600080fd5b8082039050905061014051808202821582848304141761367757600080fd5b8090509050905061034051808061368d57600080fd5b82049050905061078052600061078051186136a757600080fd5b610780805160018181830110156136bd57600080fd5b808201905090508152506308c379a06107a05260206107c05260146107e0527f536c697070616765207363726577656420796f75000000000000000000000000610800526107e0506064356107805111156137195760646107bcfd5b60206108e060446379cc6790610840523361086052610780516108805261085c60006005545af161374957600080fd5b601f3d1161375657600080fd5b6000506108e05061090060006003818352015b60006004610900516003811061377e57600080fd5b602002013518156138f75760006004610980527fa9059cbb000000000000000000000000000000000000000000000000000000006109a0526109806004806020846109e001018260208501600060045af1505080518201915050336020826109e0010152602081019050600461090051600381106137fb57600080fd5b60200201356020826109e0010152602081019050806109e0526109e09050805160200180610a808284600060045af161383357600080fd5b50506020610b40610a8051610aa06000610900516003811061385457600080fd5b600060c052602060c02001545af161386b57600080fd5b60203d8082111561387c578061387e565b815b90509050610b2052610b208051602001806109208284600060045af16138a357600080fd5b505060006109205111156138f6576109208060200151600082518060209013156138cc57600080fd5b80919012156138da57600080fd5b806020036101000a820490509050905015156138f557600080fd5b5b5b5b8151600101808352811415613769575b5050600435610b8052602435610ba052604435610bc0526105a051610be0526105c051610c00526105e051610c205261048051610c405261014051610780518082101561395457600080fd5b80820390509050610c6052337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c2610100610b80a2600062ffffff55005b600015613cc2575b610200526101405261016052610180526101a0526101c0526101e05260006101605112156139c657600080fd5b600361016051126139d657600080fd5b6101e0516102205260006102405261014051600380820282158284830414176139fe57600080fd5b80905090509050610260526000610280526102a060006003818352015b610160516102a0511815613a4b576101806102a05160038110613a3d57600080fd5b602002015161028052613a50565b613acc565b610240805161028051818183011015613a6857600080fd5b80820190509050815250610220516101e0518082028215828483041417613a8e57600080fd5b809050905090506102805160038082028215828483041417613aaf57600080fd5b809050905090508080613ac157600080fd5b820490509050610220525b8151600101808352811415613a1b575b5050610220516101e0518082028215828483041417613afa57600080fd5b809050905090506102605160038082028215828483041417613b1b57600080fd5b809050905090508080613b2d57600080fd5b82049050905061022052610240516101e051610260518080613b4e57600080fd5b820490509050818183011015613b6357600080fd5b808201905090506102c05260006102e0526101e05161030052610320600060ff818352015b610300516102e05261030051610300518082028215828483041417613bac57600080fd5b8090509050905061022051818183011015613bc657600080fd5b808201905090506002610300518082028215828483041417613be757600080fd5b809050905090506102c051818183011015613c0157600080fd5b808201905090506101e05180821015613c1957600080fd5b808203905090508080613c2b57600080fd5b820490509050610300526102e051610300511115613c72576001610300516102e05180821015613c5a57600080fd5b80820390509050111515613c6d57613cae565b613c9d565b60016102e0516103005180821015613c8957600080fd5b80820390509050111515613c9c57613cae565b5b5b8151600101808352811415613b88575b505061030051600052600051610200515650005b600015614389575b6101805261014052610160526101405161016051610180516101a051600658016100a9565b6101e0526101a0526101805261016052610140526101e0516101a05260025460038082028215828483041417613d2457600080fd5b8090509050905060088080613d3857600080fd5b820490509050610200526102206001815264e8d4a51000816020015264e8d4a51000816040015250602061030060046318160ddd6102a0526102bc6005545afa613d8157600080fd5b601f3d11613d8e57600080fd5b6000506103005161028052610320610140610380525b61038051516020610380510161038052610380610380511015613dc657613da4565b60065801610281565b6103a0526103c0526103e052610360610380525b6103805152602061038051036103805261014061038051101515613e0657613de3565b6103a08051825280602001518260200152806040015182604001525050610140610420525b61042051516020610420510161042052610420610420511015613e4d57613e2b565b61044061032080518252806020015182602001528060400151826040015250506101a0516104a0526104a051610480516104605161044051600658016104c9565b61050052610400610420525b6104205152602061042051036104205261014061042051101515613ebd57613e9a565b61050051610400526104005161014051610400518082028215828483041417613ee557600080fd5b80905090509050610280518080613efb57600080fd5b82049050905080821015613f0e57600080fd5b808203905090506105205261054061032080518252806020015182602001528060400151826040015250506101406105c0525b6105c0515160206105c051016105c0526105c06105c0511015613f6357613f41565b6101a0516105e05261016051610600526106206103208051825280602001518260200152806040015182604001525050610520516106805261068051610660516106405161062051610600516105e05160065801613999565b6106e0526105a06105c0525b6105c0515260206105c051036105c0526101406105c051101515613feb57613fc8565b6106e0516105a052610320610160516003811061400757600080fd5b60200201516105a0518082101561401d57600080fd5b80820390509050610220610160516003811061403857600080fd5b6020020151808061404857600080fd5b8204905090506107005261072060006003818352015b600061074052610160516107205114156140e057610320610720516003811061408657600080fd5b60200201516105205180820282158284830414176140a357600080fd5b809050905090506104005180806140b957600080fd5b8204905090506105a051808210156140d057600080fd5b808203905090506107405261415f565b61032061072051600381106140f457600080fd5b6020020151610320610720516003811061410d57600080fd5b602002015161052051808202821582848304141761412a57600080fd5b8090509050905061040051808061414057600080fd5b8204905090508082101561415357600080fd5b80820390509050610740525b610540610720516003811061417357600080fd5b6020020180516102005161074051808202821582848304141761419557600080fd5b809050905090506402540be40080806141ad57600080fd5b820490509050808210156141c057600080fd5b808203905090508152505b815160010180835281141561405e575b505061054061016051600381106141f157600080fd5b6020020151610140610780525b61078051516020610780510161078052610780610780511015614220576141fe565b6101a0516107a052610160516107c0526107e0610540805182528060200151826020015280604001518260400152505061052051610840526108405161082051610800516107e0516107c0516107a05160065801613999565b6108a052610760610780525b61078051526020610780510361078052610140610780511015156142a857614285565b6108a051808210156142b957600080fd5b8082039050905061076052610760516001808210156142d757600080fd5b8082039050905061022061016051600381106142f257600080fd5b6020020151808061430257600080fd5b820490509050610760526108c08080806107605181525050602081019050808061070051610760518082101561433757600080fd5b808203905090508152505060409050905060c05260c051610900525b60006109005111151561436557614381565b602061090051036108c001516020610900510361090052614353565b610180515650005b63cc2b27d760005114156143fd5734156143a257600080fd5b606051602435806040519013156143b857600080fd5b80919012156143c657600080fd5b506004356101405260243561016052610160516101405160065801613cca565b6101c0526101e0526101c05160005260206000f350005b631a4d01d260005114156147685762ffffff541561441a57600080fd5b600162ffffff55341561442c57600080fd5b6060516024358060405190131561444257600080fd5b809190121561445057600080fd5b50600f541561445e57600080fd5b60006101405260006101605261014051610160516004356101a0526024356101c0526101c0516101a05160065801613cca565b61022052610240526101605261014052610220805161014052602081015161016052506308c379a06102605260206102805260186102a0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006102c0526102a05060443561014051101561450657606461027cfd5b6024356003811061451657600080fd5b600160c052602060c0200180546101405161016051600354808202821582848304141761454257600080fd5b809050905090506402540be400808061455a57600080fd5b82049050905081818301101561456f57600080fd5b808201905090508082101561458357600080fd5b8082039050905081555060206103a060446379cc67906103005233610320526004356103405261031c60006005545af16145bc57600080fd5b601f3d116145c957600080fd5b6000506103a05060006004610420527fa9059cbb000000000000000000000000000000000000000000000000000000006104405261042060048060208461048001018260208501600060045af15050805182019150503360208261048001015260208101905061014051602082610480010152602081019050806104805261048090508051602001806105208284600060045af161466657600080fd5b505060206105e06105205161054060006024356003811061468657600080fd5b600060c052602060c02001545af161469d57600080fd5b60203d808211156146ae57806146b0565b815b905090506105c0526105c08051602001806103c08284600060045af16146d557600080fd5b505060006103c0511115614728576103c08060200151600082518060209013156146fe57600080fd5b809190121561470c57600080fd5b806020036101000a8204905090509050151561472757600080fd5b5b600435610620526101405161064052337f9e96dd3b997a2a257eec4df9bb6eaf626e206df5f543bd963682d143300be3106040610620a2600062ffffff55005b633c157e64600051141561490b57341561478157600080fd5b600454331461478f57600080fd5b600854620151808181830110156147a557600080fd5b808201905090504210156147b857600080fd5b42620151808181830110156147cc57600080fd5b8082019050905060243510156147e157600080fd5b61014051600658016100a9565b610180526101405261018051610140526000600435111561481657620f424060043510614819565b60005b61482257600080fd5b6101405160043510151561485b5761014051600a808202821582848304141761484a57600080fd5b80905090509050600435111561485e565b60005b1561486a5760016148a6565b6101405160043510156148a25761014051600435600a808202821582848304141761489457600080fd5b8090509050905010156148a5565b60005b5b5b6148b057600080fd5b6101405160065560043560075542600855602435600955610140516101a0526004356101c052426101e052602435610200527fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c25460806101a0a1005b63551a6588600051141561499b57341561492457600080fd5b600454331461493257600080fd5b61014051600658016100a9565b6101805261014052610180516101405261014051600655610140516007554260085542600955610140516101a052426101c0527f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc20193860406101a0a1005b635b5a14676000511415614a645734156149b457600080fd5b60045433146149c257600080fd5b600a54156149cf57600080fd5b64012a05f20060043511156149e357600080fd5b6402540be40060243511156149f757600080fd5b426203f480818183011015614a0b57600080fd5b808201905090506101405261014051600a55600435600c55602435600d556004356101605260243561018052610140517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe06040610160a2005b634f12fe976000511415614b03573415614a7d57600080fd5b6004543314614a8b57600080fd5b600a54421015614a9a57600080fd5b6000600a5418614aa957600080fd5b6000600a55600c5461014052600d546101605261014051600255610160516003556101405161018052610160516101a0527fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d16040610180a1005b63226840fb6000511415614b31573415614b1c57600080fd5b6004543314614b2a57600080fd5b6000600a55005b636b441a406000511415614bd2573415614b4a57600080fd5b6004356020518110614b5b57600080fd5b506004543314614b6a57600080fd5b600b5415614b7757600080fd5b426203f480818183011015614b8b57600080fd5b808201905090506101405261014051600b55600435600e55600435610140517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb93560006000a3005b636a1c05ae6000511415614c56573415614beb57600080fd5b6004543314614bf957600080fd5b600b54421015614c0857600080fd5b6000600b5418614c1757600080fd5b6000600b55600e546101405261014051600455610140517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c60006000a2005b6386fbf1936000511415614c84573415614c6f57600080fd5b6004543314614c7d57600080fd5b6000600b55005b63e2e7d2646000511415614d2b573415614c9d57600080fd5b60206101c060246370a0823161014052306101605261015c60043560038110614cc557600080fd5b600060c052602060c02001545afa614cdc57600080fd5b601f3d11614ce957600080fd5b6000506101c05160043560038110614d0057600080fd5b600160c052602060c020015480821015614d1957600080fd5b8082039050905060005260206000f350005b6330c540856000511415614f51573415614d4457600080fd5b6004543314614d5257600080fd5b61014060006003818352015b6101405160038110614d6f57600080fd5b600060c052602060c020015461016052602061022060246370a082316101a052306101c0526101bc610160515afa614da657600080fd5b601f3d11614db357600080fd5b600050610220516101405160038110614dcb57600080fd5b600160c052602060c020015480821015614de457600080fd5b80820390509050610180526000610180511115614f3c57600060046102a0527fa9059cbb000000000000000000000000000000000000000000000000000000006102c0526102a060048060208461030001018260208501600060045af15050805182019150503360208261030001015260208101905061018051602082610300010152602081019050806103005261030090508051602001806103a08284600060045af1614e9157600080fd5b505060206104606103a0516103c06000610160515af1614eb057600080fd5b60203d80821115614ec15780614ec3565b815b90509050610440526104408051602001806102408284600060045af1614ee857600080fd5b50506000610240511115614f3b57610240806020015160008251806020901315614f1157600080fd5b8091901215614f1f57600080fd5b806020036101000a82049050905090501515614f3a57600080fd5b5b5b5b8151600101808352811415614d5e575b5050005b63524c3901600051141561500a573415614f6a57600080fd5b6004543314614f7857600080fd5b61014060006003818352015b60206101e060246370a0823161016052306101805261017c6101405160038110614fad57600080fd5b600060c052602060c02001545afa614fc457600080fd5b601f3d11614fd157600080fd5b6000506101e0516101405160038110614fe957600080fd5b600160c052602060c02001555b8151600101808352811415614f84575b5050005b63e3698853600051141561504657341561502357600080fd5b600454331461503157600080fd5b426010541161503f57600080fd5b6001600f55005b633046f972600051141561507457341561505f57600080fd5b600454331461506d57600080fd5b6000600f55005b63c661065760005114156150b457341561508d57600080fd5b6004356003811061509d57600080fd5b600060c052602060c020015460005260206000f350005b634903b0d160005114156150f45734156150cd57600080fd5b600435600381106150dd57600080fd5b600160c052602060c020015460005260206000f350005b63ddca3f43600051141561511b57341561510d57600080fd5b60025460005260206000f350005b63fee3f7f9600051141561514257341561513457600080fd5b60035460005260206000f350005b638da5cb5b600051141561516957341561515b57600080fd5b60045460005260206000f350005b635409491a600051141561519057341561518257600080fd5b60065460005260206000f350005b63b4b577ad60005114156151b75734156151a957600080fd5b60075460005260206000f350005b632081066c60005114156151de5734156151d057600080fd5b60085460005260206000f350005b631405228860005114156152055734156151f757600080fd5b60095460005260206000f350005b63405e28f8600051141561522c57341561521e57600080fd5b600a5460005260206000f350005b63e0a0b586600051141561525357341561524557600080fd5b600b5460005260206000f350005b6358680d0b600051141561527a57341561526c57600080fd5b600c5460005260206000f350005b63e382446260005114156152a157341561529357600080fd5b600d5460005260206000f350005b631ec0cdc160005114156152c85734156152ba57600080fd5b600e5460005260206000f350005b5b60006000fd5b6101e86154b7036101e86000396101e86154b7036000f30000000000000000000000006e8f6d1da6232d5e40b0b8758a0145d6c5123eb70000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000006c3f90f043a72fa612cbac8115ee7e52bde6e490000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000003d09000000000000000000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x600436101561000d576152c9565b600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610244575b61014052600954610160526007546101805261016051421015610231576006546101c0526008546101e0526101c05161018051111561018a576101c051610180516101c051808210156100fb57600080fd5b80820390509050426101e0518082101561011457600080fd5b80820390509050808202821582848304141761012f57600080fd5b80905090509050610160516101e0518082101561014b57600080fd5b80820390509050808061015d57600080fd5b82049050905081818301101561017257600080fd5b8082019050905060005260005161014051565061022c565b6101c0516101c05161018051808210156101a357600080fd5b80820390509050426101e051808210156101bc57600080fd5b8082039050905080820282158284830414176101d757600080fd5b80905090509050610160516101e051808210156101f357600080fd5b80820390509050808061020557600080fd5b8204905090508082101561021857600080fd5b808203905090506000526000516101405156505b610242565b610180516000526000516101405156505b005b63f446c1d0600051141561027957341561025d57600080fd5b600658016100a9565b610140526101405160005260206000f350005b600015610399575b61014052610160670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101c060006003818352015b6101606101c051600381106102da57600080fd5b60200201516101c051600381106102f057600080fd5b600160c052602060c0200154808202821582848304141761031057600080fd5b80905090509050670de0b6b3a7640000808061032b57600080fd5b8204905090506101606101c0516003811061034557600080fd5b60200201525b81516001018083528114156102c6575b505060606101e0525b60006101e05111151561037657610392565b60206101e05103610160015160206101e051036101e052610364565b6101405156005b6000156104c1575b6101a0526101405261016052610180526101c0670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea4000000081604001525061022060006003818352015b6101c0610220516003811061040657600080fd5b6020020151610140610220516003811061041f57600080fd5b6020020151808202821582848304141761043857600080fd5b80905090509050670de0b6b3a7640000808061045357600080fd5b8204905090506101c0610220516003811061046d57600080fd5b60200201525b81516001018083528114156103f2575b50506060610240525b60006102405111151561049e576104ba565b602061024051036101c00151602061024051036102405261048c565b6101a05156005b6000156107af575b6101c0526101405261016052610180526101a05260006101e05261022060006003818352015b602061022051026101400151610200526101e080516102005181818301101561051757600080fd5b808201905090508152505b81516001018083528114156104ef575b50506101e051151561054d5760006000526000516101c05156505b6000610260526101e051610280526101a0516003808202821582848304141761057557600080fd5b809050905090506102a0526102c0600060ff818352015b610280516102e05261032060006003818352015b602061032051026101400151610300526102e0516102805180820282158284830414176105cc57600080fd5b8090509050905061030051600380820282158284830414176105ed57600080fd5b8090509050905080806105ff57600080fd5b8204905090506102e0525b81516001018083528114156105a0575b505061028051610260526102a0516101e051808202821582848304141761064057600080fd5b809050905090506102e0516003808202821582848304141761066157600080fd5b8090509050905081818301101561067757600080fd5b8082019050905061028051808202821582848304141761069657600080fd5b809050905090506102a0516001808210156106b057600080fd5b808203905090506102805180820282158284830414176106cf57600080fd5b8090509050905060046102e05180820282158284830414176106f057600080fd5b8090509050905081818301101561070657600080fd5b80820190509050808061071857600080fd5b820490509050610280526102605161028051111561075f57600161028051610260518082101561074757600080fd5b8082039050905011151561075a5761079b565b61078a565b600161026051610280518082101561077657600080fd5b808203905090501115156107895761079b565b5b5b815160010180835281141561058c575b5050610280516000526000516101c0515650005b60001561090d575b6101c0526101405261016052610180526101a052610140610420525b610420515160206104205101610420526104206104205110156107f5576107d3565b610440610140610300525b6103005151602061030051016103005261030061030051101561082257610800565b6103206101408051825280602001518260200152806040015182604001525050610360516103405161032051600658016103a1565b6103c0526103e052610400526102e0610300525b610300515260206103005103610300526101406103005110151561088e5761086b565b6103c080518252806020015182602001528060400151826040015250506101a0516104a0526104a051610480516104605161044051600658016104c9565b61050052610400610420525b61042051526020610420510361042052610140610420511015156108fb576108d8565b610500516000526000516101c0515650005b63bb7b8b806000511415610af857341561092657600080fd5b6101406102e0525b6102e0515160206102e051016102e0526102e06102e05110156109505761092e565b6103006101405161016051610180516101a0516101c0516101e0516102005160065801610281565b610240526102605261028052610200526101e0526101c0526101a05261018052610160526101405261024080518252806020015182602001528060400151826040015250506101406102a0525b6102a0515160206102a051016102a0526102a06102a05110156109e7576109c5565b600658016100a9565b6102c0526102806102a0525b6102a0515260206102a051036102a0526101406102a051101515610a1f576109fc565b6102c0516103605261036051610340516103205161030051600658016104c9565b6103c0526102c06102e0525b6102e0515260206102e051036102e0526101406102e051101515610a6f57610a4c565b6103c05161014052602061046060046318160ddd6104005261041c6005545afa610a9857600080fd5b601f3d11610aa557600080fd5b600050610460516103e05261014051670de0b6b3a76400008082028215828483041417610ad157600080fd5b809050905090506103e0518080610ae757600080fd5b82049050905060005260206000f350005b633883e1196000511415610e46573415610b1157600080fd5b60643560028110610b2157600080fd5b5061014060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506101405161016051610180516101a051600658016100a9565b6101e0526101a0526101805261016052610140526101e0516101a0526101405161016051610180516101a0516101c0516101e0516102005161024061014080518252806020015182602001528060400151826040015250506101a0516102a0526102a051610280516102605161024051600658016107b7565b61030052610200526101e0526101c0526101a052610180526101605261014052610300516102005261032060006003818352015b60643515610c77576101406103205160038110610c3b57600080fd5b60200201805160046103205160038110610c5457600080fd5b6020020135818183011015610c6857600080fd5b80820190509050815250610cc1565b6101406103205160038110610c8b57600080fd5b60200201805160046103205160038110610ca457600080fd5b602002013580821015610cb657600080fd5b808203905090508152505b5b8151600101808352811415610c1f575b5050610140610360525b61036051516020610360510161036052610360610360511015610cfe57610cdc565b61038061014080518252806020015182602001528060400151826040015250506101a0516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b6103605152602061036051036103605261014061036051101515610d6e57610d4b565b610440516103405260206104e060046318160ddd6104805261049c6005545afa610d9757600080fd5b601f3d11610da457600080fd5b6000506104e0516104605260006105005260643515610de257610340516102005180821015610dd257600080fd5b8082039050905061050052610e03565b610200516103405180821015610df757600080fd5b80820390509050610500525b61050051610460518082028215828483041417610e1f57600080fd5b80905090509050610200518080610e3557600080fd5b82049050905060005260206000f350005b634515cef3600051141561189c5762ffffff5415610e6357600080fd5b600162ffffff553415610e7557600080fd5b600f5415610e8257600080fd5b6060366101403760025460038082028215828483041417610ea257600080fd5b8090509050905060088080610eb657600080fd5b8204905090506101a0526003546101c0526101405161016051610180516101a0516101c0516101e051600658016100a9565b610220526101e0526101c0526101a052610180526101605261014052610220516101e05260206102c060046318160ddd6102605261027c6005545afa610f2d57600080fd5b601f3d11610f3a57600080fd5b6000506102c0516102405260006102e05261030060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c020015482604001525050600061024051111561103157610140610360525b61036051516020610360510161036052610360610360511015610fb857610f96565b61038061030080518252806020015182602001528060400151826040015250506101e0516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b610360515260206103605103610360526101406103605110151561102857611005565b610440516102e0525b61046061030080518252806020015182602001528060400151826040015250506104c060006003818352015b60046104c0516003811061107057600080fd5b60200201356104e0526102405115156110945760006104e0511161109357600080fd5b5b6104c051600381106110a557600080fd5b600060c052602060c02001546105005260006104e05111156112d65760026104c051141561110d5760206105a060246370a0823161052052306105405261053c610500515afa6110f457600080fd5b601f3d1161110157600080fd5b6000506105a0516104e0525b60006004610620527f23b872dd000000000000000000000000000000000000000000000000000000006106405261062060048060208461068001018260208501600060045af1505080518201915050336020826106800101526020810190503060208261068001015260208101905060046104c0516003811061118f57600080fd5b6020020135602082610680010152602081019050806106805261068090508051602001806107408284600060045af16111c757600080fd5b50506020610820610740516107606000610500515af16111e657600080fd5b60203d808211156111f757806111f9565b815b90509050610800526108008051602001806105c08284600060045af161121e57600080fd5b505060006105c0511115611271576105c080602001516000825180602090131561124757600080fd5b809190121561125557600080fd5b806020036101000a8204905090509050151561127057600080fd5b5b60026104c05114156112d55760206108e060246370a0823161086052306108805261087c610500515afa6112a457600080fd5b601f3d116112b157600080fd5b6000506108e0516104e051808210156112c957600080fd5b808203905090506104e0525b5b6103006104c051600381106112ea57600080fd5b60200201516104e05181818301101561130257600080fd5b808201905090506104606104c0516003811061131d57600080fd5b60200201525b815160010180835281141561105d575b5050610140610920525b6109205151602061092051016109205261092061092051101561135f5761133d565b61094061046080518252806020015182602001528060400151826040015250506101e0516109a0526109a051610980516109605161094051600658016107b7565b610a0052610900610920525b61092051526020610920510361092052610140610920511015156113cf576113ac565b610a0051610900526102e05161090051116113e957600080fd5b61090051610a205260006102405111156116e357610a4060006003818352015b61090051610300610a40516003811061142157600080fd5b6020020151808202821582848304141761143a57600080fd5b809050905090506102e051808061145057600080fd5b820490509050610a60526000610a8052610460610a40516003811061147457600080fd5b6020020151610a605111156114bd57610a6051610460610a40516003811061149b57600080fd5b6020020151808210156114ad57600080fd5b80820390509050610a80526114f3565b610460610a4051600381106114d157600080fd5b6020020151610a6051808210156114e757600080fd5b80820390509050610a80525b6101a051610a8051808202821582848304141761150f57600080fd5b809050905090506402540be400808061152757600080fd5b820490509050610140610a40516003811061154157600080fd5b6020020152610460610a40516003811061155a57600080fd5b6020020151610140610a40516003811061157357600080fd5b60200201516101c051808202821582848304141761159057600080fd5b809050905090506402540be40080806115a857600080fd5b820490509050808210156115bb57600080fd5b80820390509050610a4051600381106115d357600080fd5b600160c052602060c0200155610460610a4051600381106115f357600080fd5b602002018051610140610a40516003811061160d57600080fd5b60200201518082101561161f57600080fd5b808203905090508152505b8151600101808352811415611409575b5050610140610aa0525b610aa051516020610aa05101610aa052610a40610aa051101561166657611644565b610ac061046080518252806020015182602001528060400151826040015250506101e051610b2052610b2051610b0051610ae051610ac051600658016107b7565b610b8052610a20610aa0525b610aa051526020610aa05103610aa052610140610aa0511015156116d6576116b3565b610b8051610a205261170b565b600160c052602060c02061046080518255806020015160018301558060400151600283015550505b6000610ba0526102405115156117285761090051610ba05261177d565b61024051610a20516102e0518082101561174157600080fd5b80820390509050808202821582848304141761175c57600080fd5b809050905090506102e051808061177257600080fd5b820490509050610ba0525b6308c379a0610bc0526020610be0526014610c00527f536c697070616765207363726577656420796f75000000000000000000000000610c2052610c0050606435610ba05110156117cf576064610bdcfd5b6020610d0060446340c10f19610c605233610c8052610ba051610ca052610c7c60006005545af16117ff57600080fd5b601f3d1161180c57600080fd5b600050610d0050600435610d2052602435610d4052604435610d605261014051610d805261016051610da05261018051610dc05261090051610de05261024051610ba05181818301101561185f57600080fd5b80820190509050610e0052337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d610100610d20a2600062ffffff55005b600015611d13575b610200526101405261016052610180526101a0526101c0526101e0526101605161014051186118d257600080fd5b60006101605112156118e357600080fd5b600361016051126118f357600080fd5b600061014051121561190457600080fd5b6003610140511261191457600080fd5b6101405161016051610180516101a0516101c0516101e0516102005161022051600658016100a9565b6102605261022052610200526101e0526101c0526101a05261018052610160526101405261026051610220526101406102a0525b6102a0515160206102a051016102a0526102a06102a051101561199357611971565b6102c06101a08051825280602001518260200152806040015182604001525050610220516103205261032051610300516102e0516102c051600658016104c9565b610380526102806102a0525b6102a0515260206102a051036102a0526101406102a051101515611a03576119e0565b6103805161028052610280516103a05260006103c0526102205160038082028215828483041417611a3357600080fd5b809050905090506103e05260006104005261042060006003818352015b61014051610420511415611a6b576101805161040052611aa1565b61016051610420511815611a9b576101a06104205160038110611a8d57600080fd5b602002015161040052611aa0565b611b1d565b5b6103c0805161040051818183011015611ab957600080fd5b808201905090508152506103a051610280518082028215828483041417611adf57600080fd5b809050905090506104005160038082028215828483041417611b0057600080fd5b809050905090508080611b1257600080fd5b8204905090506103a0525b8151600101808352811415611a50575b50506103a051610280518082028215828483041417611b4b57600080fd5b809050905090506103e05160038082028215828483041417611b6c57600080fd5b809050905090508080611b7e57600080fd5b8204905090506103a0526103c051610280516103e0518080611b9f57600080fd5b820490509050818183011015611bb457600080fd5b808201905090506104405260006104605261028051610480526104a0600060ff818352015b610480516104605261048051610480518082028215828483041417611bfd57600080fd5b809050905090506103a051818183011015611c1757600080fd5b808201905090506002610480518082028215828483041417611c3857600080fd5b8090509050905061044051818183011015611c5257600080fd5b808201905090506102805180821015611c6a57600080fd5b808203905090508080611c7c57600080fd5b8204905090506104805261046051610480511115611cc3576001610480516104605180821015611cab57600080fd5b80820390509050111515611cbe57611cff565b611cee565b6001610460516104805180821015611cda57600080fd5b80820390509050111515611ced57611cff565b5b5b8151600101808352811415611bd9575b505061048051600052600051610200515650005b635e0d443f6000511415612045573415611d2c57600080fd5b60605160043580604051901315611d4257600080fd5b8091901215611d5057600080fd5b5060605160243580604051901315611d6757600080fd5b8091901215611d7557600080fd5b50610140670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101a06101405161016051610180516101a0516101c0516101e05160065801610281565b6102205261024052610260526101e0526101c0526101a05261018052610160526101405261022080518252806020015182602001528060400151826040015250506101a060043560038110611e2357600080fd5b602002015160443561014060043560038110611e3e57600080fd5b60200201518082028215828483041417611e5757600080fd5b80905090509050670de0b6b3a76400008080611e7257600080fd5b820490509050818183011015611e8757600080fd5b80820190509050610280526101406102c0525b6102c0515160206102c051016102c0526102c06102c0511015611ebc57611e9a565b6004356102e0526024356103005261028051610320526103406101a0805182528060200151826020015280604001518260400152505061038051610360516103405161032051610300516102e051600658016118a4565b6103e0526102a06102c0525b6102c0515260206102c051036102c0526101406102c051101515611f4257611f1f565b6103e0516102a0526101a060243560038110611f5d57600080fd5b60200201516102a05180821015611f7357600080fd5b80820390509050600180821015611f8957600080fd5b80820390509050670de0b6b3a76400008082028215828483041417611fad57600080fd5b8090509050905061014060243560038110611fc757600080fd5b60200201518080611fd757600080fd5b82049050905061040052600254610400518082028215828483041417611ffc57600080fd5b809050905090506402540be400808061201457600080fd5b8204905090506104205261040051610420518082101561203357600080fd5b8082039050905060005260206000f350005b6307211ef7600051141561230a57341561205e57600080fd5b6060516004358060405190131561207457600080fd5b809190121561208257600080fd5b506060516024358060405190131561209957600080fd5b80919012156120a757600080fd5b5061014061014051610160516101805160065801610281565b6101c0526101e052610200526101805261016052610140526101c080518252806020015182602001528060400151826040015250506102206001815264e8d4a51000816020015264e8d4a510008160400152506101406004356003811061212657600080fd5b60200201516044356102206004356003811061214157600080fd5b6020020151808202821582848304141761215a57600080fd5b8090509050905081818301101561217057600080fd5b80820190509050610280526101406102c0525b6102c0515160206102c051016102c0526102c06102c05110156121a557612183565b6004356102e052602435610300526102805161032052610340610140805182528060200151826020015280604001518260400152505061038051610360516103405161032051610300516102e051600658016118a4565b6103e0526102a06102c0525b6102c0515260206102c051036102c0526101406102c05110151561222b57612208565b6103e0516102a0526101406024356003811061224657600080fd5b60200201516102a0518082101561225c57600080fd5b8082039050905060018082101561227257600080fd5b808203905090506102206024356003811061228c57600080fd5b6020020151808061229c57600080fd5b820490509050610400526002546104005180820282158284830414176122c157600080fd5b809050905090506402540be40080806122d957600080fd5b820490509050610420526104005161042051808210156122f857600080fd5b8082039050905060005260206000f350005b633df021246000511415612c595762ffffff541561232757600080fd5b600162ffffff55341561233957600080fd5b6060516004358060405190131561234f57600080fd5b809190121561235d57600080fd5b506060516024358060405190131561237457600080fd5b809190121561238257600080fd5b50600f541561239057600080fd5b610140670de0b6b3a764000081526c0c9f2c9cd04674edea4000000081602001526c0c9f2c9cd04674edea400000008160400152506101a060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506102006101405161016051610180516101a0516101c0516101e0516102005161022051610240516102806101a080518252806020015182602001528060400151826040015250506102c0516102a05161028051600658016103a1565b6103205261034052610360526102405261022052610200526101e0526101c0526101a052610180526101605261014052610320805182528060200151826020015280604001518260400152505060443561038052600435600381106124bc57600080fd5b600060c052602060c02001546103a0526002600435141561251757602061044060246370a082316103c052306103e0526103dc6103a0515afa6124fe57600080fd5b601f3d1161250b57600080fd5b60005061044051610380525b600060046104c0527f23b872dd000000000000000000000000000000000000000000000000000000006104e0526104c060048060208461052001018260208501600060045af15050805182019150503360208261052001015260208101905030602082610520010152602081019050604435602082610520010152602081019050806105205261052090508051602001806105e08284600060045af16125bc57600080fd5b505060206106c06105e05161060060006103a0515af16125db57600080fd5b60203d808211156125ec57806125ee565b815b905090506106a0526106a08051602001806104608284600060045af161261357600080fd5b505060006104605111156126665761046080602001516000825180602090131561263c57600080fd5b809190121561264a57600080fd5b806020036101000a8204905090509050151561266557600080fd5b5b600260043514156126c957602061078060246370a0823161070052306107205261071c6103a0515afa61269857600080fd5b601f3d116126a557600080fd5b6000506107805161038051808210156126bd57600080fd5b80820390509050610380525b610200600435600381106126dc57600080fd5b602002015161038051610140600435600381106126f857600080fd5b6020020151808202821582848304141761271157600080fd5b80905090509050670de0b6b3a7640000808061272c57600080fd5b82049050905081818301101561274157600080fd5b808201905090506107a0526101406107e0525b6107e0515160206107e051016107e0526107e06107e051101561277657612754565b60043561080052602435610820526107a0516108405261086061020080518252806020015182602001528060400151826040015250506108a0516108805161086051610840516108205161080051600658016118a4565b610900526107c06107e0525b6107e0515260206107e051036107e0526101406107e0511015156127fc576127d9565b610900516107c0526102006024356003811061281757600080fd5b60200201516107c0518082101561282d57600080fd5b8082039050905060018082101561284357600080fd5b808203905090506109205261092051600254808202821582848304141761286957600080fd5b809050905090506402540be400808061288157600080fd5b820490509050610940526109205161094051808210156128a057600080fd5b80820390509050670de0b6b3a764000080820282158284830414176128c457600080fd5b80905090509050610140602435600381106128de57600080fd5b602002015180806128ee57600080fd5b820490509050610920526308c379a061096052602061098052602e6109a0527f45786368616e676520726573756c74656420696e20666577657220636f696e736109c0527f207468616e2065787065637465640000000000000000000000000000000000006109e0526109a05060643561092051101561296f57608461097cfd5b61094051600354808202821582848304141761298a57600080fd5b809050905090506402540be40080806129a257600080fd5b820490509050610a2052610a2051670de0b6b3a764000080820282158284830414176129cd57600080fd5b80905090509050610140602435600381106129e757600080fd5b602002015180806129f757600080fd5b820490509050610a20526101a060043560038110612a1457600080fd5b602002015161038051818183011015612a2c57600080fd5b8082019050905060043560038110612a4357600080fd5b600160c052602060c02001556101a060243560038110612a6257600080fd5b60200201516109205180821015612a7857600080fd5b80820390509050610a205180821015612a9057600080fd5b8082039050905060243560038110612aa757600080fd5b600160c052602060c020015560006004610a40527fa9059cbb00000000000000000000000000000000000000000000000000000000610a6052610a40600480602084610aa001018260208501600060045af150508051820191505033602082610aa001015260208101905061092051602082610aa001015260208101905080610aa052610aa09050805160200180610b408284600060045af1612b4957600080fd5b50506020610c00610b4051610b60600060243560038110612b6957600080fd5b600060c052602060c02001545af1612b8057600080fd5b60203d80821115612b915780612b93565b815b90509050610be052610be08051602001806104608284600060045af1612bb857600080fd5b50506000610460511115612c0b57610460806020015160008251806020901315612be157600080fd5b8091901215612bef57600080fd5b806020036101000a82049050905090501515612c0a57600080fd5b5b600435610c4052604435610c6052602435610c805261092051610ca052337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd971406080610c40a2600062ffffff55005b63ecb586a560005114156130405762ffffff5415612c7657600080fd5b600162ffffff553415612c8857600080fd5b60206101c060046318160ddd6101605261017c6005545afa612ca957600080fd5b601f3d11612cb657600080fd5b6000506101c051610140526060366101e037606036610240376102a060006003818352015b6102a05160038110612cec57600080fd5b600160c052602060c02001546004358082028215828483041417612d0f57600080fd5b80905090509050610140518080612d2557600080fd5b8204905090506102c0526308c379a06102e0526020610300526030610320527f5769746864726177616c20726573756c74656420696e20666577657220636f69610340527f6e73207468616e20657870656374656400000000000000000000000000000000610360526103205060246102a05160038110612da557600080fd5b60200201356102c0511015612dbb5760846102fcfd5b6102a05160038110612dcc57600080fd5b600160c052602060c0200180546102c05180821015612dea57600080fd5b808203905090508155506102c0516101e06102a05160038110612e0c57600080fd5b602002015260006004610400527fa9059cbb000000000000000000000000000000000000000000000000000000006104205261040060048060208461046001018260208501600060045af1505080518201915050336020826104600101526020810190506102c051602082610460010152602081019050806104605261046090508051602001806105008284600060045af1612ea757600080fd5b505060206105c06105005161052060006102a05160038110612ec857600080fd5b600060c052602060c02001545af1612edf57600080fd5b60203d80821115612ef05780612ef2565b815b905090506105a0526105a08051602001806103a08284600060045af1612f1757600080fd5b505060006103a0511115612f6a576103a0806020015160008251806020901315612f4057600080fd5b8091901215612f4e57600080fd5b806020036101000a82049050905090501515612f6957600080fd5b5b5b8151600101808352811415612cdb575b505060206106a060446379cc67906106005233610620526004356106405261061c60006005545af1612fac57600080fd5b601f3d11612fb957600080fd5b6000506106a0506101e0516106c052610200516106e0526102205161070052610240516107205261026051610740526102805161076052610140516004358082101561300457600080fd5b8082039050905061078052337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d60e06106c0a2600062ffffff55005b639fdaea0c60005114156139915762ffffff541561305d57600080fd5b600162ffffff55341561306f57600080fd5b600f541561307c57600080fd5b60206101c060046318160ddd6101605261017c6005545afa61309d57600080fd5b601f3d116130aa57600080fd5b6000506101c05161014052600061014051186130c557600080fd5b600254600380820282158284830414176130de57600080fd5b80905090509050600880806130f257600080fd5b8204905090506101e052600354610200526101405161016051610180516101a0516101c0516101e0516102005161022051600658016100a9565b6102605261022052610200526101e0526101c0526101a052610180526101605261014052610260516102205261028060018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015250506102e06102808051825280602001518260200152806040015182604001525050610140610360525b610360515160206103605101610360526103606103605110156131d9576131b7565b6103806102808051825280602001518260200152806040015182604001525050610220516103e0526103e0516103c0516103a05161038051600658016107b7565b61044052610340610360525b610360515260206103605103610360526101406103605110151561324957613226565b610440516103405261046060006003818352015b6102e0610460516003811061327157600080fd5b6020020180516004610460516003811061328a57600080fd5b60200201358082101561329c57600080fd5b808203905090508152505b815160010180835281141561325d575b50506101406104a0525b6104a0515160206104a051016104a0526104a06104a05110156132e3576132c1565b6104c06102e08051825280602001518260200152806040015182604001525050610220516105205261052051610500516104e0516104c051600658016107b7565b610580526104806104a0525b6104a0515260206104a051036104a0526101406104a05110151561335357613330565b61058051610480526060366105a03761060060006003818352015b61048051610280610600516003811061338657600080fd5b6020020151808202821582848304141761339f57600080fd5b809050905090506103405180806133b557600080fd5b820490509050610620526000610640526102e061060051600381106133d957600080fd5b602002015161062051111561342257610620516102e0610600516003811061340057600080fd5b60200201518082101561341257600080fd5b8082039050905061064052613458565b6102e0610600516003811061343657600080fd5b6020020151610620518082101561344c57600080fd5b80820390509050610640525b6101e05161064051808202821582848304141761347457600080fd5b809050905090506402540be400808061348c57600080fd5b8204905090506105a061060051600381106134a657600080fd5b60200201526102e061060051600381106134bf57600080fd5b60200201516105a061060051600381106134d857600080fd5b60200201516102005180820282158284830414176134f557600080fd5b809050905090506402540be400808061350d57600080fd5b8204905090508082101561352057600080fd5b80820390509050610600516003811061353857600080fd5b600160c052602060c02001556102e0610600516003811061355857600080fd5b6020020180516105a0610600516003811061357257600080fd5b60200201518082101561358457600080fd5b808203905090508152505b815160010180835281141561336e575b5050610140610680525b610680515160206106805101610680526106806106805110156135cb576135a9565b6106a06102e080518252806020015182602001528060400151826040015250506102205161070052610700516106e0516106c0516106a051600658016107b7565b61076052610660610680525b610680515260206106805103610680526101406106805110151561363b57613618565b610760516106605261034051610660518082101561365857600080fd5b8082039050905061014051808202821582848304141761367757600080fd5b8090509050905061034051808061368d57600080fd5b82049050905061078052600061078051186136a757600080fd5b610780805160018181830110156136bd57600080fd5b808201905090508152506308c379a06107a05260206107c05260146107e0527f536c697070616765207363726577656420796f75000000000000000000000000610800526107e0506064356107805111156137195760646107bcfd5b60206108e060446379cc6790610840523361086052610780516108805261085c60006005545af161374957600080fd5b601f3d1161375657600080fd5b6000506108e05061090060006003818352015b60006004610900516003811061377e57600080fd5b602002013518156138f75760006004610980527fa9059cbb000000000000000000000000000000000000000000000000000000006109a0526109806004806020846109e001018260208501600060045af1505080518201915050336020826109e0010152602081019050600461090051600381106137fb57600080fd5b60200201356020826109e0010152602081019050806109e0526109e09050805160200180610a808284600060045af161383357600080fd5b50506020610b40610a8051610aa06000610900516003811061385457600080fd5b600060c052602060c02001545af161386b57600080fd5b60203d8082111561387c578061387e565b815b90509050610b2052610b208051602001806109208284600060045af16138a357600080fd5b505060006109205111156138f6576109208060200151600082518060209013156138cc57600080fd5b80919012156138da57600080fd5b806020036101000a820490509050905015156138f557600080fd5b5b5b5b8151600101808352811415613769575b5050600435610b8052602435610ba052604435610bc0526105a051610be0526105c051610c00526105e051610c205261048051610c405261014051610780518082101561395457600080fd5b80820390509050610c6052337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c2610100610b80a2600062ffffff55005b600015613cc2575b610200526101405261016052610180526101a0526101c0526101e05260006101605112156139c657600080fd5b600361016051126139d657600080fd5b6101e0516102205260006102405261014051600380820282158284830414176139fe57600080fd5b80905090509050610260526000610280526102a060006003818352015b610160516102a0511815613a4b576101806102a05160038110613a3d57600080fd5b602002015161028052613a50565b613acc565b610240805161028051818183011015613a6857600080fd5b80820190509050815250610220516101e0518082028215828483041417613a8e57600080fd5b809050905090506102805160038082028215828483041417613aaf57600080fd5b809050905090508080613ac157600080fd5b820490509050610220525b8151600101808352811415613a1b575b5050610220516101e0518082028215828483041417613afa57600080fd5b809050905090506102605160038082028215828483041417613b1b57600080fd5b809050905090508080613b2d57600080fd5b82049050905061022052610240516101e051610260518080613b4e57600080fd5b820490509050818183011015613b6357600080fd5b808201905090506102c05260006102e0526101e05161030052610320600060ff818352015b610300516102e05261030051610300518082028215828483041417613bac57600080fd5b8090509050905061022051818183011015613bc657600080fd5b808201905090506002610300518082028215828483041417613be757600080fd5b809050905090506102c051818183011015613c0157600080fd5b808201905090506101e05180821015613c1957600080fd5b808203905090508080613c2b57600080fd5b820490509050610300526102e051610300511115613c72576001610300516102e05180821015613c5a57600080fd5b80820390509050111515613c6d57613cae565b613c9d565b60016102e0516103005180821015613c8957600080fd5b80820390509050111515613c9c57613cae565b5b5b8151600101808352811415613b88575b505061030051600052600051610200515650005b600015614389575b6101805261014052610160526101405161016051610180516101a051600658016100a9565b6101e0526101a0526101805261016052610140526101e0516101a05260025460038082028215828483041417613d2457600080fd5b8090509050905060088080613d3857600080fd5b820490509050610200526102206001815264e8d4a51000816020015264e8d4a51000816040015250602061030060046318160ddd6102a0526102bc6005545afa613d8157600080fd5b601f3d11613d8e57600080fd5b6000506103005161028052610320610140610380525b61038051516020610380510161038052610380610380511015613dc657613da4565b60065801610281565b6103a0526103c0526103e052610360610380525b6103805152602061038051036103805261014061038051101515613e0657613de3565b6103a08051825280602001518260200152806040015182604001525050610140610420525b61042051516020610420510161042052610420610420511015613e4d57613e2b565b61044061032080518252806020015182602001528060400151826040015250506101a0516104a0526104a051610480516104605161044051600658016104c9565b61050052610400610420525b6104205152602061042051036104205261014061042051101515613ebd57613e9a565b61050051610400526104005161014051610400518082028215828483041417613ee557600080fd5b80905090509050610280518080613efb57600080fd5b82049050905080821015613f0e57600080fd5b808203905090506105205261054061032080518252806020015182602001528060400151826040015250506101406105c0525b6105c0515160206105c051016105c0526105c06105c0511015613f6357613f41565b6101a0516105e05261016051610600526106206103208051825280602001518260200152806040015182604001525050610520516106805261068051610660516106405161062051610600516105e05160065801613999565b6106e0526105a06105c0525b6105c0515260206105c051036105c0526101406105c051101515613feb57613fc8565b6106e0516105a052610320610160516003811061400757600080fd5b60200201516105a0518082101561401d57600080fd5b80820390509050610220610160516003811061403857600080fd5b6020020151808061404857600080fd5b8204905090506107005261072060006003818352015b600061074052610160516107205114156140e057610320610720516003811061408657600080fd5b60200201516105205180820282158284830414176140a357600080fd5b809050905090506104005180806140b957600080fd5b8204905090506105a051808210156140d057600080fd5b808203905090506107405261415f565b61032061072051600381106140f457600080fd5b6020020151610320610720516003811061410d57600080fd5b602002015161052051808202821582848304141761412a57600080fd5b8090509050905061040051808061414057600080fd5b8204905090508082101561415357600080fd5b80820390509050610740525b610540610720516003811061417357600080fd5b6020020180516102005161074051808202821582848304141761419557600080fd5b809050905090506402540be40080806141ad57600080fd5b820490509050808210156141c057600080fd5b808203905090508152505b815160010180835281141561405e575b505061054061016051600381106141f157600080fd5b6020020151610140610780525b61078051516020610780510161078052610780610780511015614220576141fe565b6101a0516107a052610160516107c0526107e0610540805182528060200151826020015280604001518260400152505061052051610840526108405161082051610800516107e0516107c0516107a05160065801613999565b6108a052610760610780525b61078051526020610780510361078052610140610780511015156142a857614285565b6108a051808210156142b957600080fd5b8082039050905061076052610760516001808210156142d757600080fd5b8082039050905061022061016051600381106142f257600080fd5b6020020151808061430257600080fd5b820490509050610760526108c08080806107605181525050602081019050808061070051610760518082101561433757600080fd5b808203905090508152505060409050905060c05260c051610900525b60006109005111151561436557614381565b602061090051036108c001516020610900510361090052614353565b610180515650005b63cc2b27d760005114156143fd5734156143a257600080fd5b606051602435806040519013156143b857600080fd5b80919012156143c657600080fd5b506004356101405260243561016052610160516101405160065801613cca565b6101c0526101e0526101c05160005260206000f350005b631a4d01d260005114156147685762ffffff541561441a57600080fd5b600162ffffff55341561442c57600080fd5b6060516024358060405190131561444257600080fd5b809190121561445057600080fd5b50600f541561445e57600080fd5b60006101405260006101605261014051610160516004356101a0526024356101c0526101c0516101a05160065801613cca565b61022052610240526101605261014052610220805161014052602081015161016052506308c379a06102605260206102805260186102a0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006102c0526102a05060443561014051101561450657606461027cfd5b6024356003811061451657600080fd5b600160c052602060c0200180546101405161016051600354808202821582848304141761454257600080fd5b809050905090506402540be400808061455a57600080fd5b82049050905081818301101561456f57600080fd5b808201905090508082101561458357600080fd5b8082039050905081555060206103a060446379cc67906103005233610320526004356103405261031c60006005545af16145bc57600080fd5b601f3d116145c957600080fd5b6000506103a05060006004610420527fa9059cbb000000000000000000000000000000000000000000000000000000006104405261042060048060208461048001018260208501600060045af15050805182019150503360208261048001015260208101905061014051602082610480010152602081019050806104805261048090508051602001806105208284600060045af161466657600080fd5b505060206105e06105205161054060006024356003811061468657600080fd5b600060c052602060c02001545af161469d57600080fd5b60203d808211156146ae57806146b0565b815b905090506105c0526105c08051602001806103c08284600060045af16146d557600080fd5b505060006103c0511115614728576103c08060200151600082518060209013156146fe57600080fd5b809190121561470c57600080fd5b806020036101000a8204905090509050151561472757600080fd5b5b600435610620526101405161064052337f9e96dd3b997a2a257eec4df9bb6eaf626e206df5f543bd963682d143300be3106040610620a2600062ffffff55005b633c157e64600051141561490b57341561478157600080fd5b600454331461478f57600080fd5b600854620151808181830110156147a557600080fd5b808201905090504210156147b857600080fd5b42620151808181830110156147cc57600080fd5b8082019050905060243510156147e157600080fd5b61014051600658016100a9565b610180526101405261018051610140526000600435111561481657620f424060043510614819565b60005b61482257600080fd5b6101405160043510151561485b5761014051600a808202821582848304141761484a57600080fd5b80905090509050600435111561485e565b60005b1561486a5760016148a6565b6101405160043510156148a25761014051600435600a808202821582848304141761489457600080fd5b8090509050905010156148a5565b60005b5b5b6148b057600080fd5b6101405160065560043560075542600855602435600955610140516101a0526004356101c052426101e052602435610200527fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c25460806101a0a1005b63551a6588600051141561499b57341561492457600080fd5b600454331461493257600080fd5b61014051600658016100a9565b6101805261014052610180516101405261014051600655610140516007554260085542600955610140516101a052426101c0527f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc20193860406101a0a1005b635b5a14676000511415614a645734156149b457600080fd5b60045433146149c257600080fd5b600a54156149cf57600080fd5b64012a05f20060043511156149e357600080fd5b6402540be40060243511156149f757600080fd5b426203f480818183011015614a0b57600080fd5b808201905090506101405261014051600a55600435600c55602435600d556004356101605260243561018052610140517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe06040610160a2005b634f12fe976000511415614b03573415614a7d57600080fd5b6004543314614a8b57600080fd5b600a54421015614a9a57600080fd5b6000600a5418614aa957600080fd5b6000600a55600c5461014052600d546101605261014051600255610160516003556101405161018052610160516101a0527fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d16040610180a1005b63226840fb6000511415614b31573415614b1c57600080fd5b6004543314614b2a57600080fd5b6000600a55005b636b441a406000511415614bd2573415614b4a57600080fd5b6004356020518110614b5b57600080fd5b506004543314614b6a57600080fd5b600b5415614b7757600080fd5b426203f480818183011015614b8b57600080fd5b808201905090506101405261014051600b55600435600e55600435610140517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb93560006000a3005b636a1c05ae6000511415614c56573415614beb57600080fd5b6004543314614bf957600080fd5b600b54421015614c0857600080fd5b6000600b5418614c1757600080fd5b6000600b55600e546101405261014051600455610140517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c60006000a2005b6386fbf1936000511415614c84573415614c6f57600080fd5b6004543314614c7d57600080fd5b6000600b55005b63e2e7d2646000511415614d2b573415614c9d57600080fd5b60206101c060246370a0823161014052306101605261015c60043560038110614cc557600080fd5b600060c052602060c02001545afa614cdc57600080fd5b601f3d11614ce957600080fd5b6000506101c05160043560038110614d0057600080fd5b600160c052602060c020015480821015614d1957600080fd5b8082039050905060005260206000f350005b6330c540856000511415614f51573415614d4457600080fd5b6004543314614d5257600080fd5b61014060006003818352015b6101405160038110614d6f57600080fd5b600060c052602060c020015461016052602061022060246370a082316101a052306101c0526101bc610160515afa614da657600080fd5b601f3d11614db357600080fd5b600050610220516101405160038110614dcb57600080fd5b600160c052602060c020015480821015614de457600080fd5b80820390509050610180526000610180511115614f3c57600060046102a0527fa9059cbb000000000000000000000000000000000000000000000000000000006102c0526102a060048060208461030001018260208501600060045af15050805182019150503360208261030001015260208101905061018051602082610300010152602081019050806103005261030090508051602001806103a08284600060045af1614e9157600080fd5b505060206104606103a0516103c06000610160515af1614eb057600080fd5b60203d80821115614ec15780614ec3565b815b90509050610440526104408051602001806102408284600060045af1614ee857600080fd5b50506000610240511115614f3b57610240806020015160008251806020901315614f1157600080fd5b8091901215614f1f57600080fd5b806020036101000a82049050905090501515614f3a57600080fd5b5b5b5b8151600101808352811415614d5e575b5050005b63524c3901600051141561500a573415614f6a57600080fd5b6004543314614f7857600080fd5b61014060006003818352015b60206101e060246370a0823161016052306101805261017c6101405160038110614fad57600080fd5b600060c052602060c02001545afa614fc457600080fd5b601f3d11614fd157600080fd5b6000506101e0516101405160038110614fe957600080fd5b600160c052602060c02001555b8151600101808352811415614f84575b5050005b63e3698853600051141561504657341561502357600080fd5b600454331461503157600080fd5b426010541161503f57600080fd5b6001600f55005b633046f972600051141561507457341561505f57600080fd5b600454331461506d57600080fd5b6000600f55005b63c661065760005114156150b457341561508d57600080fd5b6004356003811061509d57600080fd5b600060c052602060c020015460005260206000f350005b634903b0d160005114156150f45734156150cd57600080fd5b600435600381106150dd57600080fd5b600160c052602060c020015460005260206000f350005b63ddca3f43600051141561511b57341561510d57600080fd5b60025460005260206000f350005b63fee3f7f9600051141561514257341561513457600080fd5b60035460005260206000f350005b638da5cb5b600051141561516957341561515b57600080fd5b60045460005260206000f350005b635409491a600051141561519057341561518257600080fd5b60065460005260206000f350005b63b4b577ad60005114156151b75734156151a957600080fd5b60075460005260206000f350005b632081066c60005114156151de5734156151d057600080fd5b60085460005260206000f350005b631405228860005114156152055734156151f757600080fd5b60095460005260206000f350005b63405e28f8600051141561522c57341561521e57600080fd5b600a5460005260206000f350005b63e0a0b586600051141561525357341561524557600080fd5b600b5460005260206000f350005b6358680d0b600051141561527a57341561526c57600080fd5b600c5460005260206000f350005b63e382446260005114156152a157341561529357600080fd5b600d5460005260206000f350005b631ec0cdc160005114156152c85734156152ba57600080fd5b600e5460005260206000f350005b5b60006000fd