Contract
0x04996afcf40a14d0892b00c816874f9c1a52c93b
1
Contract Overview
My Name Tag:
Not Available
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
GmxSSOV
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan on 2022-01-16 */ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, 'Strings: hex length insufficient'); return string(buffer); } } // File @openzeppelin/contracts/proxy/[email protected] /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) instance := create(0, ptr, 0x37) } require(instance != address(0), 'ERC1167: create failed'); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) instance := create2(0, ptr, 0x37, salt) } require(instance != address(0), 'ERC1167: create2 failed'); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000 ) mstore(add(ptr, 0x38), shl(0x60, deployer)) mstore(add(ptr, 0x4c), salt) mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) predicted := keccak256(add(ptr, 0x37), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } } // File contracts/external/libraries/BokkyPooBahsDateTimeLibrary.sol // ---------------------------------------------------------------------------- // BokkyPooBah's DateTime Library v1.01 // // A gas-efficient Solidity date and time library // // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary // // Tested date range 1970/01/01 to 2345/12/31 // // Conventions: // Unit | Range | Notes // :-------- |:-------------:|:----- // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC // year | 1970 ... 2345 | // month | 1 ... 12 | // day | 1 ... 31 | // hour | 0 ... 23 | // minute | 0 ... 59 | // second | 0 ... 59 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday // // // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence. // ---------------------------------------------------------------------------- library BokkyPooBahsDateTimeLibrary { uint256 constant SECONDS_PER_DAY = 24 * 60 * 60; uint256 constant SECONDS_PER_HOUR = 60 * 60; uint256 constant SECONDS_PER_MINUTE = 60; int256 constant OFFSET19700101 = 2440588; uint256 constant DOW_MON = 1; uint256 constant DOW_TUE = 2; uint256 constant DOW_WED = 3; uint256 constant DOW_THU = 4; uint256 constant DOW_FRI = 5; uint256 constant DOW_SAT = 6; uint256 constant DOW_SUN = 7; // ------------------------------------------------------------------------ // Calculate the number of days from 1970/01/01 to year/month/day using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and subtracting the offset 2440588 so that 1970/01/01 is day 0 // // days = day // - 32075 // + 1461 * (year + 4800 + (month - 14) / 12) / 4 // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12 // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4 // - offset // ------------------------------------------------------------------------ function _daysFromDate( uint256 year, uint256 month, uint256 day ) internal pure returns (uint256 _days) { require(year >= 1970); int256 _year = int256(year); int256 _month = int256(month); int256 _day = int256(day); int256 __days = _day - 32075 + (1461 * (_year + 4800 + (_month - 14) / 12)) / 4 + (367 * (_month - 2 - ((_month - 14) / 12) * 12)) / 12 - (3 * ((_year + 4900 + (_month - 14) / 12) / 100)) / 4 - OFFSET19700101; _days = uint256(__days); } // ------------------------------------------------------------------------ // Calculate year/month/day from the number of days since 1970/01/01 using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and adding the offset 2440588 so that 1970/01/01 is day 0 // // int L = days + 68569 + offset // int N = 4 * L / 146097 // L = L - (146097 * N + 3) / 4 // year = 4000 * (L + 1) / 1461001 // L = L - 1461 * year / 4 + 31 // month = 80 * L / 2447 // dd = L - 2447 * month / 80 // L = month / 11 // month = month + 2 - 12 * L // year = 100 * (N - 49) + year + L // ------------------------------------------------------------------------ function _daysToDate(uint256 _days) internal pure returns ( uint256 year, uint256 month, uint256 day ) { int256 __days = int256(_days); int256 L = __days + 68569 + OFFSET19700101; int256 N = (4 * L) / 146097; L = L - (146097 * N + 3) / 4; int256 _year = (4000 * (L + 1)) / 1461001; L = L - (1461 * _year) / 4 + 31; int256 _month = (80 * L) / 2447; int256 _day = L - (2447 * _month) / 80; L = _month / 11; _month = _month + 2 - 12 * L; _year = 100 * (N - 49) + _year + L; year = uint256(_year); month = uint256(_month); day = uint256(_day); } function timestampFromDate( uint256 year, uint256 month, uint256 day ) internal pure returns (uint256 timestamp) { timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY; } function timestampFromDateTime( uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second ) internal pure returns (uint256 timestamp) { timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second; } function timestampToDate(uint256 timestamp) internal pure returns ( uint256 year, uint256 month, uint256 day ) { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); } function timestampToDateTime(uint256 timestamp) internal pure returns ( uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second ) { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); uint256 secs = timestamp % SECONDS_PER_DAY; hour = secs / SECONDS_PER_HOUR; secs = secs % SECONDS_PER_HOUR; minute = secs / SECONDS_PER_MINUTE; second = secs % SECONDS_PER_MINUTE; } function isValidDate( uint256 year, uint256 month, uint256 day ) internal pure returns (bool valid) { if (year >= 1970 && month > 0 && month <= 12) { uint256 daysInMonth = _getDaysInMonth(year, month); if (day > 0 && day <= daysInMonth) { valid = true; } } } function isValidDateTime( uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second ) internal pure returns (bool valid) { if (isValidDate(year, month, day)) { if (hour < 24 && minute < 60 && second < 60) { valid = true; } } } function isLeapYear(uint256 timestamp) internal pure returns (bool leapYear) { (uint256 year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY); leapYear = _isLeapYear(year); } function _isLeapYear(uint256 year) internal pure returns (bool leapYear) { leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); } function isWeekDay(uint256 timestamp) internal pure returns (bool weekDay) { weekDay = getDayOfWeek(timestamp) <= DOW_FRI; } function isWeekEnd(uint256 timestamp) internal pure returns (bool weekEnd) { weekEnd = getDayOfWeek(timestamp) >= DOW_SAT; } function getDaysInMonth(uint256 timestamp) internal pure returns (uint256 daysInMonth) { (uint256 year, uint256 month, ) = _daysToDate( timestamp / SECONDS_PER_DAY ); daysInMonth = _getDaysInMonth(year, month); } function _getDaysInMonth(uint256 year, uint256 month) internal pure returns (uint256 daysInMonth) { if ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) { daysInMonth = 31; } else if (month != 2) { daysInMonth = 30; } else { daysInMonth = _isLeapYear(year) ? 29 : 28; } } // 1 = Monday, 7 = Sunday function getDayOfWeek(uint256 timestamp) internal pure returns (uint256 dayOfWeek) { uint256 _days = timestamp / SECONDS_PER_DAY; dayOfWeek = ((_days + 3) % 7) + 1; } // 1 = Monday, 7 = Sunday function getDayOfWeek(uint256 timestamp, uint256 index) internal pure returns (uint256 dayOfWeek) { uint256 _days = timestamp / SECONDS_PER_DAY; dayOfWeek = ((_days + index) % 7) + 1; } function getYear(uint256 timestamp) internal pure returns (uint256 year) { (year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getMonth(uint256 timestamp) internal pure returns (uint256 month) { (, month, ) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getDay(uint256 timestamp) internal pure returns (uint256 day) { (, , day) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getHour(uint256 timestamp) internal pure returns (uint256 hour) { uint256 secs = timestamp % SECONDS_PER_DAY; hour = secs / SECONDS_PER_HOUR; } function getMinute(uint256 timestamp) internal pure returns (uint256 minute) { uint256 secs = timestamp % SECONDS_PER_HOUR; minute = secs / SECONDS_PER_MINUTE; } function getSecond(uint256 timestamp) internal pure returns (uint256 second) { second = timestamp % SECONDS_PER_MINUTE; } function addYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate( timestamp / SECONDS_PER_DAY ); year += _years; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp >= timestamp); } function addMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate( timestamp / SECONDS_PER_DAY ); month += _months; year += (month - 1) / 12; month = ((month - 1) % 12) + 1; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp >= timestamp); } function addDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _days * SECONDS_PER_DAY; require(newTimestamp >= timestamp); } function addHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _hours * SECONDS_PER_HOUR; require(newTimestamp >= timestamp); } function addMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE; require(newTimestamp >= timestamp); } function addSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _seconds; require(newTimestamp >= timestamp); } function subYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate( timestamp / SECONDS_PER_DAY ); year -= _years; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp <= timestamp); } function subMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate( timestamp / SECONDS_PER_DAY ); uint256 yearMonth = year * 12 + (month - 1) - _months; year = yearMonth / 12; month = (yearMonth % 12) + 1; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp <= timestamp); } function subDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _days * SECONDS_PER_DAY; require(newTimestamp <= timestamp); } function subHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _hours * SECONDS_PER_HOUR; require(newTimestamp <= timestamp); } function subMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE; require(newTimestamp <= timestamp); } function subSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _seconds; require(newTimestamp <= timestamp); } function diffYears(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _years) { require(fromTimestamp <= toTimestamp); (uint256 fromYear, , ) = _daysToDate(fromTimestamp / SECONDS_PER_DAY); (uint256 toYear, , ) = _daysToDate(toTimestamp / SECONDS_PER_DAY); _years = toYear - fromYear; } function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _months) { require(fromTimestamp <= toTimestamp); (uint256 fromYear, uint256 fromMonth, ) = _daysToDate( fromTimestamp / SECONDS_PER_DAY ); (uint256 toYear, uint256 toMonth, ) = _daysToDate( toTimestamp / SECONDS_PER_DAY ); _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth; } function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _days) { require(fromTimestamp <= toTimestamp); _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY; } function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _hours) { require(fromTimestamp <= toTimestamp); _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR; } function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _minutes) { require(fromTimestamp <= toTimestamp); _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE; } function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _seconds) { require(fromTimestamp <= toTimestamp); _seconds = toTimestamp - fromTimestamp; } } // File contracts/external/interfaces/IERC20.sol /** * @dev Interface of the ERC20 standard as defined in the EIP. * NOTE: Modified to include symbols and decimals. */ interface IERC20 { function totalSupply() external view returns (uint256); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); } // File @openzeppelin/contracts/utils/math/[email protected] // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File @openzeppelin/contracts/utils/[email protected] /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, 'Address: insufficient balance' ); (bool success, ) = recipient.call{value: amount}(''); require( success, 'Address: unable to send value, recipient may have reverted' ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'Address: low-level call with value failed' ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, 'Address: insufficient balance for call' ); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, 'Address: low-level static call failed' ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, 'Address: low-level delegate call failed' ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File contracts/external/libraries/SafeERC20.sol /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require( (value == 0) || (token.allowance(address(this), spender) == 0), 'SafeERC20: approve from non-zero to non-zero allowance' ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add( value ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, 'SafeERC20: decreased allowance below zero' ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, 'SafeERC20: low-level call failed' ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed' ); } } } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require( _initializing || !_initialized, 'Initializable: contract is already initialized' ); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer {} function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require( currentAllowance >= amount, 'ERC20: transfer amount exceeds allowance' ); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender] + addedValue ); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require( currentAllowance >= subtractedValue, 'ERC20: decreased allowance below zero' ); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), 'ERC20: transfer from the zero address'); require(recipient != address(0), 'ERC20: transfer to the zero address'); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require( senderBalance >= amount, 'ERC20: transfer amount exceeds balance' ); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: mint to the zero address'); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: burn from the zero address'); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, 'ERC20: burn amount exceeds balance'); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), 'ERC20: approve from the zero address'); require(spender != address(0), 'ERC20: approve to the zero address'); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable { function __ERC20Burnable_init() internal initializer { __Context_init_unchained(); __ERC20Burnable_init_unchained(); } function __ERC20Burnable_init_unchained() internal initializer {} /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require( currentAllowance >= amount, 'ERC20: burn amount exceeds allowance' ); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/security/[email protected] /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal initializer { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), 'Pausable: paused'); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), 'Pausable: not paused'); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] /** * @dev ERC20 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable { function __ERC20Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); __ERC20Pausable_init_unchained(); } function __ERC20Pausable_init_unchained() internal initializer {} /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(!paused(), 'ERC20Pausable: token transfer while paused'); } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/access/[email protected] /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File @openzeppelin/contracts-upgradeable/access/[email protected] /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); } // File @openzeppelin/contracts-upgradeable/utils/[email protected] /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, 'Strings: hex length insufficient'); return string(buffer); } } // File @openzeppelin/contracts-upgradeable/utils/introspection/[email protected] /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts-upgradeable/utils/introspection/[email protected] /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal initializer { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal initializer {} /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/access/[email protected] /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer {} struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( 'AccessControl: account ', StringsUpgradeable.toHexString(uint160(account), 20), ' is missing role ', StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require( account == _msgSender(), 'AccessControl: can only renounce roles for self' ); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/utils/structs/[email protected] /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } // File @openzeppelin/contracts-upgradeable/access/[email protected] /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable { function __AccessControlEnumerable_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); __AccessControlEnumerable_init_unchained(); } function __AccessControlEnumerable_init_unchained() internal initializer {} using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/presets/[email protected] /** * @dev {ERC20} token, including: * * - ability for holders to burn (destroy) their tokens * - a minter role that allows for token minting (creation) * - a pauser role that allows to stop all token transfers * * This contract uses {AccessControl} to lock permissioned functions using the * different roles - head to its documentation for details. * * The account that deploys the contract will be granted the minter and pauser * roles, as well as the default admin role, which will let it grant both minter * and pauser roles to other accounts. */ contract ERC20PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable { function initialize(string memory name, string memory symbol) public virtual initializer { __ERC20PresetMinterPauser_init(name, symbol); } bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE'); bytes32 public constant PAUSER_ROLE = keccak256('PAUSER_ROLE'); /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * See {ERC20-constructor}. */ function __ERC20PresetMinterPauser_init( string memory name, string memory symbol ) internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); __AccessControlEnumerable_init_unchained(); __ERC20_init_unchained(name, symbol); __ERC20Burnable_init_unchained(); __Pausable_init_unchained(); __ERC20Pausable_init_unchained(); __ERC20PresetMinterPauser_init_unchained(name, symbol); } function __ERC20PresetMinterPauser_init_unchained( string memory name, string memory symbol ) internal initializer { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); } /** * @dev Creates `amount` new tokens for `to`. * * See {ERC20-_mint}. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function mint(address to, uint256 amount) public virtual { require( hasRole(MINTER_ROLE, _msgSender()), 'ERC20PresetMinterPauser: must have minter role to mint' ); _mint(to, amount); } /** * @dev Pauses all token transfers. * * See {ERC20Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public virtual { require( hasRole(PAUSER_ROLE, _msgSender()), 'ERC20PresetMinterPauser: must have pauser role to pause' ); _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC20Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public virtual { require( hasRole(PAUSER_ROLE, _msgSender()), 'ERC20PresetMinterPauser: must have pauser role to unpause' ); _unpause(); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override(ERC20Upgradeable, ERC20PausableUpgradeable) { super._beforeTokenTransfer(from, to, amount); } uint256[50] private __gap; } // File @openzeppelin/contracts/utils/[email protected] /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/security/[email protected] /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), 'Pausable: paused'); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), 'Pausable: not paused'); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File @openzeppelin/contracts/access/[email protected] /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), 'Ownable: new owner is the zero address' ); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File contracts/helper/ContractWhitelist.sol /// @title ContractWhitelist /// @author witherblock /// @notice A helper contract that lets you add a list of whitelisted contracts that should be able to interact with restricited functions abstract contract ContractWhitelist is Ownable { /// @dev contract => whitelisted or not mapping(address => bool) public whitelistedContracts; /*==== SETTERS ====*/ /// @dev add to the contract whitelist /// @param _contract the address of the contract to add to the contract whitelist /// @return whether the contract was successfully added to the whitelist function addToContractWhitelist(address _contract) external onlyOwner returns (bool) { require( isContract(_contract), 'ContractWhitelist: Address must be a contract address' ); require( !whitelistedContracts[_contract], 'ContractWhitelist: Contract already whitelisted' ); whitelistedContracts[_contract] = true; emit AddToContractWhitelist(_contract); return true; } /// @dev remove from the contract whitelist /// @param _contract the address of the contract to remove from the contract whitelist /// @return whether the contract was successfully removed from the whitelist function removeFromContractWhitelist(address _contract) external returns (bool) { require( whitelistedContracts[_contract], 'ContractWhitelist: Contract not whitelisted' ); whitelistedContracts[_contract] = false; emit RemoveFromContractWhitelist(_contract); return true; } /* ========== MODIFIERS ========== */ // Modifier is eligible sender modifier modifier isEligibleSender() { if (isContract(msg.sender)) require( whitelistedContracts[msg.sender], 'ContractWhitelist: Contract must be whitelisted' ); _; } /*==== VIEWS ====*/ /// @dev checks for contract or eoa addresses /// @param addr the address to check /// @return whether the passed address is a contract address function isContract(address addr) public view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } /*==== EVENTS ====*/ event AddToContractWhitelist(address indexed _contract); event RemoveFromContractWhitelist(address indexed _contract); } // File contracts/interfaces/IVolatilityOracle.sol interface IVolatilityOracle { function getVolatility() external view returns (uint256); } // File contracts/interfaces/IOptionPricing.sol interface IOptionPricing { function getOptionPrice( bool isPut, uint256 expiry, uint256 strike, uint256 lastPrice, uint256 baseIv ) external view returns (uint256); } // File contracts/interfaces/ISSOV.sol interface ISSOV { function epochStrikeTokens(uint256 epoch, uint256 strike) external view returns (address); function getAddress(bytes32 name) external view returns (address); function currentEpoch() external view returns (uint256); function epochStrikes(uint256 epoch, uint256 strikeIndex) external view returns (uint256); function settle( uint256 strikeIndex, uint256 amount, uint256 epoch ) external returns (uint256); } // File contracts/interfaces/IERC20SSOV.sol interface IERC20SSOV is ISSOV { function purchase( uint256 strikeIndex, uint256 amount, address user ) external returns (uint256, uint256); function deposit( uint256 strikeIndex, uint256 amount, address user ) external returns (bool); function depositMultiple( uint256[] memory strikeIndices, uint256[] memory amounts, address user ) external returns (bool); } // File contracts/fees/IFeeStrategy.sol interface IFeeStrategy { function calculatePurchaseFees( uint256, uint256, uint256 ) external view returns (uint256); function calculateSettlementFees( uint256, uint256, uint256 ) external view returns (uint256); } interface IRewardRouterV2 { function stakeGmx(uint256 _amount) external; function stakeGmxForAccount(address _account, uint256 _amount) external; function stakeEsGmx(uint256 _amount) external; function unstakeGmx(uint256 _amount) external; function unstakeEsGmx(uint256 _amount) external; function claim() external; function claimEsGmx() external; function claimFees() external; function compound() external; function signalTransfer(address _receiver) external; function acceptTransfer(address _sender) external; function handleRewards( bool _shouldClaimGmx, bool _shouldStakeGmx, bool _shouldClaimEsGmx, bool _shouldStakeEsGmx, bool _shouldStakeMultiplierPoints, bool _shouldClaimWeth, bool _shouldConvertWethToEth ) external; function compoundForAccount(address _account) external; } // Libraries // Contracts // Interfaces interface IPriceOracle { function getPriceInUSD() external view returns (uint256); } contract GmxSSOV is ContractWhitelist, Pausable, IERC20SSOV { using BokkyPooBahsDateTimeLibrary for uint256; using Strings for uint256; using SafeERC20 for IERC20; /// @dev ERC20PresetMinterPauserUpgradeable implementation address address public immutable erc20Implementation; /// @dev Current epoch for ssov uint256 public currentEpoch; /// @dev Expire delay tolerance uint256 public expireDelayTolerance = 5 minutes; /// @dev The list of contract addresses the contract uses mapping(bytes32 => address) public addresses; /// @dev epoch => the epoch start time mapping(uint256 => uint256) public epochStartTimes; /// @notice Is epoch expired /// @dev epoch => whether the epoch is expired mapping(uint256 => bool) public isEpochExpired; /// @notice Is vault ready for next epoch /// @dev epoch => whether the vault is ready (boostrapped) mapping(uint256 => bool) public isVaultReady; /// @dev Mapping of strikes for each epoch mapping(uint256 => uint256[]) public epochStrikes; /// @dev Mapping of (epoch => (strike => tokens)) mapping(uint256 => mapping(uint256 => address)) public epochStrikeTokens; /// @notice Total epoch deposits for specific strikes /// @dev mapping (epoch => (strike => deposits)) mapping(uint256 => mapping(uint256 => uint256)) public totalEpochStrikeDeposits; /// @notice Total epoch deposits across all strikes /// @dev mapping (epoch => deposits) mapping(uint256 => uint256) public totalEpochDeposits; /// @notice Total epoch deposits for specific strikes including premiums and rewards /// @dev mapping (epoch => (strike => deposits)) mapping(uint256 => mapping(uint256 => uint256)) public totalEpochStrikeBalance; /// @notice Total epoch deposits across all strikes including premiums and rewards /// @dev mapping (epoch => deposits) mapping(uint256 => uint256) public totalEpochBalance; /// @notice Epoch deposits by user for each strike /// @dev mapping (epoch => (abi.encodePacked(user, strike) => user deposits)) mapping(uint256 => mapping(bytes32 => uint256)) public userEpochDeposits; /// @notice Epoch GMX balance per strike after accounting for rewards /// @dev mapping (epoch => (strike => balance)) mapping(uint256 => mapping(uint256 => uint256)) public totalEpochStrikeGmxBalance; // Calls purchased for each strike in an epoch /// @dev mapping (epoch => (strike => calls purchased)) mapping(uint256 => mapping(uint256 => uint256)) public totalEpochCallsPurchased; /// @notice Calls purchased by user for each strike /// @dev mapping (epoch => (abi.encodePacked(user, strike) => user calls purchased)) mapping(uint256 => mapping(bytes32 => uint256)) public userEpochCallsPurchased; /// @notice Premium collected per strike for an epoch /// @dev mapping (epoch => (strike => premium)) mapping(uint256 => mapping(uint256 => uint256)) public totalEpochPremium; /// @notice User premium collected per strike for an epoch /// @dev mapping (epoch => (abi.encodePacked(user, strike) => user premium)) mapping(uint256 => mapping(bytes32 => uint256)) public userEpochPremium; /// @dev epoch => settlement price mapping(uint256 => uint256) public settlementPrices; /// @dev epoch => claimed ETH Fees mapping(uint256 => uint256) public totalGmxFeesClaimed; /// @dev epoch => claimed esGMX mapping(uint256 => uint256) public totalEsGmxClaimed; /*==== EVENTS ====*/ event ExpireDelayToleranceUpdate(uint256 expireDelayTolerance); event AddressSet(bytes32 indexed name, address indexed destination); event EmergencyWithdraw(address sender, uint256 gmxWithdrawn); event NewStrike(uint256 epoch, uint256 strike); event Bootstrap(uint256 epoch); event NewDeposit( uint256 epoch, uint256 strike, uint256 amount, address user, address sender ); event NewPurchase( uint256 epoch, uint256 strike, uint256 amount, uint256 premium, uint256 fee, address user, address sender ); event NewSettle( uint256 epoch, uint256 strike, address user, uint256 amount, uint256 pnl ); // event Compound(uint256 epoch, uint256 oldBalance, uint256 newBalance); event NewWithdraw( uint256 epoch, uint256 strike, address user, uint256 amount, uint256 gmxAmount ); /*==== CONSTRUCTOR ====*/ error ZeroAddress(bytes32 source, address destination); constructor(bytes32[] memory sources, address[] memory destinations) { require(sources.length == destinations.length, 'E26'); for (uint256 i = 0; i < destinations.length; i++) { if (destinations[i] == address(0)) { revert ZeroAddress(sources[i], destinations[i]); } addresses[sources[i]] = destinations[i]; } addresses['Governance'] = msg.sender; erc20Implementation = address(new ERC20PresetMinterPauserUpgradeable()); IERC20(getAddress('GMX')).safeApprove( getAddress('StakedGmxTracker'), type(uint256).max ); IERC20(getAddress('GMX')).safeApprove( getAddress('BonusGmxTracker'), type(uint256).max ); IERC20(getAddress('GMX')).safeApprove( getAddress('FeeGmxTracker'), type(uint256).max ); IERC20(getAddress('esGMX')).safeApprove( getAddress('StakedGmxTracker'), type(uint256).max ); } /*==== SETTER METHODS ====*/ /// @notice Pauses the vault for emergency cases /// @dev Can only be called by governance /// @return Whether it was successfully paused function pause() external onlyGovernance returns (bool) { _pause(); _updateFinalEpochBalances(false); return true; } /// @notice Unpauses the vault /// @dev Can only be called by governance /// @return Whether it was successfully unpaused function unpause() external onlyGovernance returns (bool) { _unpause(); return true; } /// @notice Updates the delay tolerance for the expiry epoch function /// @dev Can only be called by governance /// @return Whether it was successfully updated function updateExpireDelayTolerance(uint256 _expireDelayTolerance) external onlyGovernance returns (bool) { expireDelayTolerance = _expireDelayTolerance; emit ExpireDelayToleranceUpdate(_expireDelayTolerance); return true; } /// @notice Sets (adds) a list of addresses to the address list /// @param names Names of the contracts /// @param destinations Addresses of the contract /// @return Whether the addresses were set function setAddresses( bytes32[] calldata names, address[] calldata destinations ) external onlyOwner returns (bool) { require(names.length == destinations.length, 'E2'); for (uint256 i = 0; i < names.length; i++) { bytes32 name = names[i]; address destination = destinations[i]; addresses[name] = destination; emit AddressSet(name, destination); } return true; } /*==== METHODS ====*/ /// @notice Transfers all funds to msg.sender /// @dev Can only be called by governance /// @return Whether emergency withdraw was successful function emergencyWithdraw() external onlyGovernance whenPaused returns (bool) { IERC20 gmx = IERC20(getAddress('GMX')); // IERC20 esGmx = IERC20(getAddress('esGMX')); IERC20 weth = IERC20(getAddress('WETH')); uint256 gmxBalance = gmx.balanceOf(address(this)); // uint256 esGmxBalance = esGmx.balanceOf(address(this)); uint256 wethBalance = weth.balanceOf(address(this)); gmx.safeTransfer(msg.sender, gmxBalance); // esGmx.safeTransfer(msg.sender, esGmxBalance); weth.safeTransfer(msg.sender, wethBalance); emit EmergencyWithdraw(msg.sender, gmxBalance); return true; } /// @notice Sets the current epoch as expired. /// @return Whether expire was successful function expireEpoch() external whenNotPaused isEligibleSender returns (bool) { require(!isEpochExpired[currentEpoch], 'E3'); (, uint256 epochExpiry) = getEpochTimes(currentEpoch); require((block.timestamp >= epochExpiry), 'E4'); require(block.timestamp <= epochExpiry + expireDelayTolerance, 'E23'); settlementPrices[currentEpoch] = getUsdPrice(); _updateFinalEpochBalances(true); isEpochExpired[currentEpoch] = true; return true; } /// @notice Sets the current epoch as expired. /// @return Whether expire was successful function expireEpoch(uint256 settlementPrice) external onlyGovernance whenNotPaused returns (bool) { require(!isEpochExpired[currentEpoch], 'E3'); (, uint256 epochExpiry) = getEpochTimes(currentEpoch); require((block.timestamp > epochExpiry + expireDelayTolerance), 'E4'); settlementPrices[currentEpoch] = settlementPrice; _updateFinalEpochBalances(true); isEpochExpired[currentEpoch] = true; return true; } /// @dev Updates the final epoch GMX balances per strike of the vault /// @param accountPremiums Should the fn account for premiums function _updateFinalEpochBalances(bool accountPremiums) internal { if (totalEpochBalance[currentEpoch] > 0) { uint256[] memory strikes = epochStrikes[currentEpoch]; for (uint256 i = 0; i < strikes.length; i++) { // PnL from ssov option settlements uint256 settlement = calculatePnl( settlementPrices[currentEpoch], strikes[i], totalEpochCallsPurchased[currentEpoch][strikes[i]] ); // Update final GMX balances for epoch and strike totalEpochStrikeGmxBalance[currentEpoch][strikes[i]] += totalEpochStrikeDeposits[currentEpoch][strikes[i]] - settlement; if (accountPremiums) { totalEpochStrikeGmxBalance[currentEpoch][ strikes[i] ] += totalEpochPremium[currentEpoch][strikes[i]]; } } } IERC20 weth = IERC20(getAddress('WETH')); IERC20 esGmx = IERC20(getAddress('esGMX')); uint256 gmxFeeClaimed = weth.balanceOf(address(this)); uint256 esGmxRewardsClaimed = esGmx.balanceOf(address(this)); IRewardRouterV2(getAddress('RewardRouterV2')).unstakeGmx( totalEpochBalance[currentEpoch] ); IRewardRouterV2(getAddress('RewardRouterV2')).claim(); gmxFeeClaimed = weth.balanceOf(address(this)) - gmxFeeClaimed; esGmxRewardsClaimed = esGmx.balanceOf(address(this)) - esGmxRewardsClaimed; if (gmxFeeClaimed > 0 && esGmxRewardsClaimed > 0) { totalGmxFeesClaimed[currentEpoch] = gmxFeeClaimed; totalEsGmxClaimed[currentEpoch] = esGmxRewardsClaimed; } } /** * @notice Bootstraps a new epoch and mints option tokens equivalent to user deposits for the epoch * @return Whether bootstrap was successful */ function bootstrap() external onlyOwner whenNotPaused returns (bool) { uint256 nextEpoch = currentEpoch + 1; require(!isVaultReady[nextEpoch], 'E5'); require(epochStrikes[nextEpoch].length > 0, 'E6'); if (currentEpoch > 0) { // Previous epoch must be expired require(isEpochExpired[currentEpoch], 'E7'); } for (uint256 i = 0; i < epochStrikes[nextEpoch].length; i++) { uint256 strike = epochStrikes[nextEpoch][i]; string memory name = concatenate('GMX-CALL', strike.toString()); name = concatenate(name, '-EPOCH-'); name = concatenate(name, (nextEpoch).toString()); // Create doTokens representing calls for selected strike in epoch ERC20PresetMinterPauserUpgradeable _erc20 = ERC20PresetMinterPauserUpgradeable( Clones.clone(erc20Implementation) ); _erc20.initialize(name, name); epochStrikeTokens[nextEpoch][strike] = address(_erc20); // Mint tokens equivalent to deposits for strike in epoch _erc20.mint( address(this), totalEpochStrikeDeposits[nextEpoch][strike] ); } // Mark vault as ready for epoch isVaultReady[nextEpoch] = true; // Increase the current epoch currentEpoch = nextEpoch; emit Bootstrap(nextEpoch); return true; } /** * @notice Sets strikes for next epoch * @param strikes Strikes to set for next epoch * @return Whether strikes were set */ function setStrikes(uint256[] memory strikes) external onlyOwner whenNotPaused returns (bool) { uint256 nextEpoch = currentEpoch + 1; require(totalEpochDeposits[nextEpoch] == 0, 'E8'); if (currentEpoch > 0) { (, uint256 epochExpiry) = getEpochTimes(currentEpoch); require((block.timestamp > epochExpiry), 'E9'); } // Set the next epoch strikes epochStrikes[nextEpoch] = strikes; // Set the next epoch start time epochStartTimes[nextEpoch] = block.timestamp; for (uint256 i = 0; i < strikes.length; i++) emit NewStrike(nextEpoch, strikes[i]); return true; } /** * @notice Deposits GMX into the ssov to mint options in the next epoch for selected strikes * @param strikeIndex Index of strike * @param amount Amount of GMX to deposit * @param user Address of the user to deposit for * @return Whether deposit was successful */ function deposit( uint256 strikeIndex, uint256 amount, address user ) public whenNotPaused isEligibleSender returns (bool) { uint256 nextEpoch = currentEpoch + 1; if (currentEpoch > 0) { require( isEpochExpired[currentEpoch] && !isVaultReady[nextEpoch], 'E19' ); } // Must be a valid strikeIndex require(strikeIndex < epochStrikes[nextEpoch].length, 'E10'); // Must +ve amount require(amount > 0, 'E11'); // Must be a valid strike uint256 strike = epochStrikes[nextEpoch][strikeIndex]; require(strike != 0, 'E12'); bytes32 userStrike = keccak256(abi.encodePacked(user, strike)); // Add to user epoch deposits userEpochDeposits[nextEpoch][userStrike] += amount; // Add to total epoch strike deposits totalEpochStrikeDeposits[nextEpoch][strike] += amount; // Add to total epoch deposits totalEpochDeposits[nextEpoch] += amount; // Add to total epoch strike deposits totalEpochStrikeBalance[nextEpoch][strike] += amount; // Add to total epoch deposits totalEpochBalance[nextEpoch] += amount; IERC20(getAddress('GMX')).safeTransferFrom( msg.sender, address(this), amount ); // Stake GMX IRewardRouterV2(getAddress('RewardRouterV2')).stakeGmx(amount); emit NewDeposit(nextEpoch, strike, amount, user, msg.sender); return true; } /** * @notice Deposit GMX multiple times * @param strikeIndices Indices of strikes to deposit into * @param amounts Amount of GMX to deposit into each strike index * @param user Address of the user to deposit for * @return Whether deposits went through successfully */ function depositMultiple( uint256[] memory strikeIndices, uint256[] memory amounts, address user ) external whenNotPaused returns (bool) { require(strikeIndices.length == amounts.length, 'E2'); for (uint256 i = 0; i < strikeIndices.length; i++) deposit(strikeIndices[i], amounts[i], user); return true; } /** * @notice Purchases calls for the current epoch * @param strikeIndex Strike index for current epoch * @param amount Amount of calls to purchase * @param user User to purchase options for * @return Whether purchase was successful */ function purchase( uint256 strikeIndex, uint256 amount, address user ) external whenNotPaused isEligibleSender returns (uint256, uint256) { (, uint256 epochExpiry) = getEpochTimes(currentEpoch); require((block.timestamp < epochExpiry), 'E24'); require(isVaultReady[currentEpoch], 'E20'); require(strikeIndex < epochStrikes[currentEpoch].length, 'E10'); require(amount > 0, 'E11'); uint256 strike = epochStrikes[currentEpoch][strikeIndex]; require(strike != 0, 'E12'); bytes32 userStrike = keccak256(abi.encodePacked(user, strike)); IERC20 gmxToken = IERC20(getAddress('GMX')); uint256 currentPrice = getUsdPrice(); // Get total premium for all calls being purchased uint256 premium = calculatePremium(strike, amount); // Total fee charged uint256 totalFee = calculatePurchaseFees(currentPrice, strike, amount); // Add to total epoch calls purchased totalEpochCallsPurchased[currentEpoch][strike] += amount; // Add to user epoch calls purchased userEpochCallsPurchased[currentEpoch][userStrike] += amount; // Add to total epoch premium totalEpochPremium[currentEpoch][strike] += premium; // Add to user epoch premium userEpochPremium[currentEpoch][userStrike] += premium; totalEpochStrikeBalance[currentEpoch][strike] += premium; totalEpochBalance[currentEpoch] += premium; // Transfer premium from msg.sender (need not be same as user) gmxToken.safeTransferFrom( msg.sender, address(this), premium + totalFee ); if (totalFee > 0) { // Transfer fee to FeeDistributor gmxToken.safeTransfer(getAddress('FeeDistributor'), totalFee); } // Transfer doTokens to user IERC20(epochStrikeTokens[currentEpoch][strike]).safeTransfer( user, amount ); // Stake premium via router IRewardRouterV2(getAddress('RewardRouterV2')).stakeGmx(premium); emit NewPurchase( currentEpoch, strike, amount, premium, totalFee, user, msg.sender ); return (premium, totalFee); } /** * @notice Settle calculates the PnL for the user and withdraws the PnL in GMX to the user. Will also the burn the option tokens from the user. * @param strikeIndex Strike index * @param amount Amount of options * @param epoch The epoch * @return pnl */ function settle( uint256 strikeIndex, uint256 amount, uint256 epoch ) external override whenNotPaused isEligibleSender returns (uint256 pnl) { require(isEpochExpired[epoch], 'E17'); require(strikeIndex < epochStrikes[epoch].length, 'E10'); require(amount > 0, 'E11'); uint256 strike = epochStrikes[epoch][strikeIndex]; require(strike != 0, 'E12'); require( IERC20(epochStrikeTokens[epoch][strike]).balanceOf(msg.sender) >= amount, 'E16' ); // Calculate PnL (in GMX) pnl = calculatePnl(settlementPrices[epoch], strike, amount); // Total fee charged uint256 totalFee = calculateSettlementFees( settlementPrices[epoch], pnl, amount ); require(pnl > 0, 'E15'); // Burn user option tokens ERC20PresetMinterPauserUpgradeable(epochStrikeTokens[epoch][strike]) .burnFrom(msg.sender, amount); IERC20 gmx = IERC20(getAddress('GMX')); // Transfer PnL to user gmx.safeTransfer(msg.sender, pnl - totalFee); emit NewSettle(epoch, strike, msg.sender, amount, pnl); } /** * @notice Call compound() * @dev RewardRouterV2's compound() claims & restakes esGmx rewards + multiplier points in a single tx * @return Whether compound was successful */ function compound() public whenNotPaused returns (bool) { require(!isEpochExpired[currentEpoch], 'E3'); require(isVaultReady[currentEpoch], 'E20'); IRewardRouterV2 rewardRouter = IRewardRouterV2( getAddress('RewardRouterV2') ); rewardRouter.compound(); // todo: is not accounting rewards claimed // emit Compound(currentEpoch, oldBalance, newBalance); return true; } /** * @notice Withdraws balances for a strike in a completed epoch * @param withdrawEpoch Epoch to withdraw from * @param strikeIndex Index of strike * @return GMX withdrawn and fees claimed */ function withdraw(uint256 withdrawEpoch, uint256 strikeIndex) external whenNotPaused isEligibleSender returns (uint256[2] memory) { require(isEpochExpired[withdrawEpoch], 'E17'); require(strikeIndex < epochStrikes[withdrawEpoch].length, 'E10'); uint256 strike = epochStrikes[withdrawEpoch][strikeIndex]; require(strike != 0, 'E12'); bytes32 userStrike = keccak256(abi.encodePacked(msg.sender, strike)); uint256 userStrikeDeposits = userEpochDeposits[withdrawEpoch][ userStrike ]; require(userStrikeDeposits > 0, 'E18'); // Transfer GMX tokens to user uint256 userGmxAmount = (totalEpochStrikeGmxBalance[withdrawEpoch][ strike ] * userStrikeDeposits) / totalEpochStrikeDeposits[withdrawEpoch][strike]; userEpochDeposits[withdrawEpoch][userStrike] = 0; // Total fee claimed uint256 claimedFees = totalGmxFeesClaimed[currentEpoch]; // Total fees claimable for strike uint256 claimableFeesForStrike = (claimedFees * totalEpochStrikeDeposits[withdrawEpoch][strike]) / totalEpochDeposits[withdrawEpoch]; // User claimable fee uint256 userClaimableFees = (claimableFeesForStrike * userStrikeDeposits) / totalEpochStrikeDeposits[withdrawEpoch][strike]; // Transfer GMX to user IERC20(getAddress('GMX')).safeTransfer(msg.sender, userGmxAmount); // Transfer fee bonus to user IERC20(getAddress('WETH')).safeTransfer(msg.sender, userClaimableFees); emit NewWithdraw( withdrawEpoch, strike, msg.sender, userStrikeDeposits, userGmxAmount ); return [userGmxAmount, userClaimableFees]; } /// @notice transfer all esGMX rewards earned to an EOA function initiateEsGmxRewardsTransfer( uint256 withdrawEpoch, address receiver ) external whenNotPaused onlyOwner returns (uint256) { IERC20 esGmx = IERC20(getAddress('esGMX')); uint256 accruedEsGmx = esGmx.balanceOf(address(this)); // total EsGmx accrued from all epochs so far require(isEpochExpired[withdrawEpoch], 'E17'); require(accruedEsGmx != 0, 'E25'); require(receiver != address(0), 'Cannot transfer to zero address'); IRewardRouterV2 rewardRouter = IRewardRouterV2( getAddress('RewardRouterV2') ); esGmx.safeApprove(getAddress('RewardRouterV2'), accruedEsGmx); rewardRouter.signalTransfer(receiver); return accruedEsGmx; } /*==== PURE FUNCTIONS ====*/ /// @notice Calculates the monthly expiry from a solidity date /// @param timestamp Timestamp from which the monthly expiry is to be calculated /// @return The monthly expiry function getMonthlyExpiryFromTimestamp(uint256 timestamp) public pure returns (uint256) { uint256 lastDay = BokkyPooBahsDateTimeLibrary.timestampFromDate( timestamp.getYear(), timestamp.getMonth() + 1, 0 ); if (lastDay.getDayOfWeek() < 5) { lastDay = BokkyPooBahsDateTimeLibrary.timestampFromDate( lastDay.getYear(), lastDay.getMonth(), lastDay.getDay() - 7 ); } uint256 lastFridayOfMonth = BokkyPooBahsDateTimeLibrary .timestampFromDateTime( lastDay.getYear(), lastDay.getMonth(), lastDay.getDay() + 5 - lastDay.getDayOfWeek(), 8, 0, 0 ); if (lastFridayOfMonth <= timestamp) { uint256 temp = BokkyPooBahsDateTimeLibrary.timestampFromDate( timestamp.getYear(), timestamp.getMonth() + 2, 0 ); if (temp.getDayOfWeek() < 5) { temp = BokkyPooBahsDateTimeLibrary.timestampFromDate( temp.getYear(), temp.getMonth(), temp.getDay() - 7 ); } lastFridayOfMonth = BokkyPooBahsDateTimeLibrary .timestampFromDateTime( temp.getYear(), temp.getMonth(), temp.getDay() + 5 - temp.getDayOfWeek(), 8, 0, 0 ); } return lastFridayOfMonth; } /** * @notice Returns a concatenated string of a and b * @param a string a * @param b string b */ function concatenate(string memory a, string memory b) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } /// @notice Calculate Pnl /// @param price price of GMX /// @param strike strike price of the the GMX option /// @param amount amount of options function calculatePnl( uint256 price, uint256 strike, uint256 amount ) public pure returns (uint256) { return price > strike ? (((price - strike) * amount) / price) : 0; } /*==== VIEWS ====*/ /// @notice Calculate premium for an option /// @param _strike Strike price of the option /// @param _amount Amount of options function calculatePremium(uint256 _strike, uint256 _amount) public view returns (uint256 premium) { uint256 currentPrice = getUsdPrice(); premium = (IOptionPricing(getAddress('OptionPricing')).getOptionPrice( false, getMonthlyExpiryFromTimestamp(block.timestamp), _strike, currentPrice, IVolatilityOracle(getAddress('VolatilityOracle')).getVolatility() ) * _amount) / currentPrice; } /// @notice Calculate Fees for purchase /// @param price price of GMX /// @param strike strike price of the the GMX option /// @param amount amount of options being bought function calculatePurchaseFees( uint256 price, uint256 strike, uint256 amount ) public view returns (uint256) { return IFeeStrategy(getAddress('FeeStrategy')).calculatePurchaseFees( price, strike, amount ); } /// @notice Calculate Fees for settlement /// @param settlementPrice settlement price of GMX /// @param pnl total pnl /// @param amount amount of options being settled function calculateSettlementFees( uint256 settlementPrice, uint256 pnl, uint256 amount ) public view returns (uint256) { return IFeeStrategy(getAddress('FeeStrategy')).calculateSettlementFees( settlementPrice, pnl, amount ); } /** * @notice Returns start and end times for an epoch * @param epoch Target epoch */ function getEpochTimes(uint256 epoch) public view epochGreaterThanZero(epoch) returns (uint256 start, uint256 end) { return ( epochStartTimes[epoch], getMonthlyExpiryFromTimestamp(epochStartTimes[epoch]) ); } /** * @notice Returns epoch strikes array for an epoch * @param epoch Target epoch */ function getEpochStrikes(uint256 epoch) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { return epochStrikes[epoch]; } /** * Returns epoch strike tokens array for an epoch * @param epoch Target epoch */ function getEpochStrikeTokens(uint256 epoch) external view epochGreaterThanZero(epoch) returns (address[] memory) { uint256 length = epochStrikes[epoch].length; address[] memory _epochStrikeTokens = new address[](length); for (uint256 i = 0; i < length; i++) { _epochStrikeTokens[i] = epochStrikeTokens[epoch][ epochStrikes[epoch][i] ]; } return _epochStrikeTokens; } /** * @notice Returns total epoch strike deposits array for an epoch * @param epoch Target epoch */ function getTotalEpochStrikeDeposits(uint256 epoch) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _totalEpochStrikeDeposits = new uint256[](length); for (uint256 i = 0; i < length; i++) { _totalEpochStrikeDeposits[i] = totalEpochStrikeDeposits[epoch][ epochStrikes[epoch][i] ]; } return _totalEpochStrikeDeposits; } /** * @notice Returns user epoch deposits array for an epoch * @param epoch Target epoch * @param user Address of the user */ function getUserEpochDeposits(uint256 epoch, address user) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _userEpochDeposits = new uint256[](length); for (uint256 i = 0; i < length; i++) { uint256 strike = epochStrikes[epoch][i]; bytes32 userStrike = keccak256(abi.encodePacked(user, strike)); _userEpochDeposits[i] = userEpochDeposits[epoch][userStrike]; } return _userEpochDeposits; } /** * @notice Returns total epoch calls purchased array for an epoch * @param epoch Target epoch */ function getTotalEpochCallsPurchased(uint256 epoch) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _totalEpochCallsPurchased = new uint256[](length); for (uint256 i = 0; i < length; i++) { _totalEpochCallsPurchased[i] = totalEpochCallsPurchased[epoch][ epochStrikes[epoch][i] ]; } return _totalEpochCallsPurchased; } /** * @notice Returns user epoch calls purchased array for an epoch * @param epoch Target epoch * @param user Address of the user */ function getUserEpochCallsPurchased(uint256 epoch, address user) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _userEpochCallsPurchased = new uint256[](length); for (uint256 i = 0; i < length; i++) { uint256 strike = epochStrikes[epoch][i]; bytes32 userStrike = keccak256(abi.encodePacked(user, strike)); _userEpochCallsPurchased[i] = userEpochCallsPurchased[epoch][ userStrike ]; } return _userEpochCallsPurchased; } /** * @notice Returns total epoch premium array for an epoch * @param epoch Target epoch */ function getTotalEpochPremium(uint256 epoch) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _totalEpochPremium = new uint256[](length); for (uint256 i = 0; i < length; i++) { _totalEpochPremium[i] = totalEpochPremium[epoch][ epochStrikes[epoch][i] ]; } return _totalEpochPremium; } /** * @notice Returns user epoch premium array for an epoch * @param epoch Target epoch * @param user Address of the user */ function getUserEpochPremium(uint256 epoch, address user) external view epochGreaterThanZero(epoch) returns (uint256[] memory) { uint256 length = epochStrikes[epoch].length; uint256[] memory _userEpochPremium = new uint256[](length); for (uint256 i = 0; i < length; i++) { uint256 strike = epochStrikes[epoch][i]; bytes32 userStrike = keccak256(abi.encodePacked(user, strike)); _userEpochPremium[i] = userEpochPremium[epoch][userStrike]; } return _userEpochPremium; } /** * @notice Returns GMX price in USD */ function getUsdPrice() public view returns (uint256) { return IPriceOracle(getAddress('GmxPriceOracle')).getPriceInUSD(); } /** * @notice Gets the address of a set contract * @param name Name of the contract * @return The address of the contract */ function getAddress(bytes32 name) public view returns (address) { return addresses[name]; } /*==== MODIFIERS ====*/ modifier onlyGovernance() { require(msg.sender == getAddress('Governance'), 'E22'); _; } modifier epochGreaterThanZero(uint256 epoch) { require(epoch > 0, 'E13'); _; } } // ERROR MAPPING: // { // "E1": "SSOV: Address cannot be a zero address", // "E2": "SSOV: Input lengths must match", // "E3": "SSOV: Epoch must not be expired", // "E4": "SSOV: Cannot expire epoch before epoch's expiry", // "E5": "SSOV: Already bootstrapped", // "E6": "SSOV: Strikes have not been set for next epoch", // "E7": "SSOV: Previous epoch has not expired", // "E8": "SSOV: Deposit already started", // "E9": "SSOV: Cannot set next strikes before current epoch's expiry", // "E10": "SSOV: Invalid strike index", // "E11": "SSOV: Invalid amount", // "E12": "SSOV: Invalid strike", // "E13": "SSOV: Epoch passed must be greater than 0", // "E14": "SSOV: Option must be in exercise window", // "E15": "SSOV: Strike is higher than current price", // "E16": "SSOV: Option token balance is not enough", // "E17": "SSOV: Epoch must be expired", // "E18": "SSOV: User strike deposit amount must be greater than zero", // "E19": "SSOV: Deposit is only available between epochs", // "E20": "SSOV: Not bootstrapped", // "E21": "SSOV: Can not call function in exercise window", // "E22": "SSOV: Caller is not governance", // "E23": "SSOV: Expire delay tolerance exceeded" // }
[{"inputs":[{"internalType":"bytes32[]","name":"sources","type":"bytes32[]"},{"internalType":"address[]","name":"destinations","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"source","type":"bytes32"},{"internalType":"address","name":"destination","type":"address"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"}],"name":"AddToContractWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":true,"internalType":"address","name":"destination","type":"address"}],"name":"AddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"Bootstrap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"gmxWithdrawn","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"expireDelayTolerance","type":"uint256"}],"name":"ExpireDelayToleranceUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"NewDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premium","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"NewPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pnl","type":"uint256"}],"name":"NewSettle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"}],"name":"NewStrike","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gmxAmount","type":"uint256"}],"name":"NewWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"}],"name":"RemoveFromContractWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"addToContractWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bootstrap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"strike","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculatePnl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_strike","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculatePremium","outputs":[{"internalType":"uint256","name":"premium","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"strike","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculatePurchaseFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"settlementPrice","type":"uint256"},{"internalType":"uint256","name":"pnl","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateSettlementFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"compound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"strikeIndices","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"user","type":"address"}],"name":"depositMultiple","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochStartTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochStrikeTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochStrikes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20Implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"expireDelayTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"expireEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"settlementPrice","type":"uint256"}],"name":"expireEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpochStrikeTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpochStrikes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpochTimes","outputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getMonthlyExpiryFromTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getTotalEpochCallsPurchased","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getTotalEpochPremium","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getTotalEpochStrikeDeposits","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUsdPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserEpochCallsPurchased","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserEpochDeposits","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserEpochPremium","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawEpoch","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"initiateEsGmxRewardsTransfer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isEpochExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isVaultReady","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"removeFromContractWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"names","type":"bytes32[]"},{"internalType":"address[]","name":"destinations","type":"address[]"}],"name":"setAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"strikes","type":"uint256[]"}],"name":"setStrikes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"settle","outputs":[{"internalType":"uint256","name":"pnl","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"settlementPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochCallsPurchased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochPremium","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochStrikeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochStrikeDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEpochStrikeGmxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalEsGmxClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalGmxFeesClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_expireDelayTolerance","type":"uint256"}],"name":"updateExpireDelayTolerance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"userEpochCallsPurchased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"userEpochDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"userEpochPremium","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawEpoch","type":"uint256"},{"internalType":"uint256","name":"strikeIndex","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256[2]","name":"","type":"uint256[2]"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405261012c6004553480156200001757600080fd5b5060405162007c1a38038062007c1a8339810160408190526200003a91620008fa565b6200004533620003da565b6002805460ff1916905580518251146200008c5760405162461bcd60e51b815260206004820152600360248201526222991b60e91b60448201526064015b60405180910390fd5b60005b8151811015620001bf5760006001600160a01b0316828281518110620000b957620000b9620009c1565b60200260200101516001600160a01b031614156200013957828181518110620000e657620000e6620009c1565b6020026020010151828281518110620001035762000103620009c1565b60200260200101516040516337c178ab60e01b8152600401620000839291909182526001600160a01b0316602082015260400190565b8181815181106200014e576200014e620009c1565b6020026020010151600560008584815181106200016f576200016f620009c1565b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080620001b690620009d7565b9150506200008f565b5069476f7665726e616e636560b01b60005260056020527fa3c20e4cfcdbe0796697a05f5cc56e3d568bc2f08a21308461ccefe56b2fecb580546001600160a01b031916331790556040516200021590620007f3565b604051809103906000f08015801562000232573d6000803e3d6000fd5b506001600160a01b039081166080526f29ba30b5b2b223b6bc2a3930b1b5b2b960811b600052600560205260008051602062007bfa83398151915254620002d291165b6208e9ab60eb1b60005260056020527fd8354cf2337f6ac01ea1d0584132e023fe2fb15ceb8670e7a28e1cf3fe692ac954600019906001600160a01b03165b6001600160a01b03166200042a60201b620038cd179092919060201c565b6e2137b73ab9a3b6bc2a3930b1b5b2b960891b60005260056020527f317a49ce4750747146cbbd12c3c39e6ed580eb8610fa56533b97fca3ab1c07925462000323906001600160a01b031662000275565b6c2332b2a3b6bc2a3930b1b5b2b960991b60005260056020527f7a79dbd092679d0017fce600fb4e162ffd567fa0134ca16e3b97dc0deae24d765462000372906001600160a01b031662000275565b600560205260008051602062007bfa83398151915254640cae68e9ab60db1b6000527f02dbbc89ede4d6e9e9a76dbf6c2ef2d95056be9005527c25f27b162585d13d4254620003d2916001600160a01b03908116916000199116620002b4565b505062000ac5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b801580620004b85750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200047b57600080fd5b505afa15801562000490573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004b6919062000a01565b155b6200052c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840162000083565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620005849185916200058916565b505050565b6000620005e5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200066760201b62003a29179092919060201c565b80519091501562000584578080602001905181019062000606919062000a1b565b620005845760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000083565b606062000678848460008562000682565b90505b9392505050565b606082471015620006e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000083565b843b620007355760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000083565b600080866001600160a01b0316858760405162000753919062000a72565b60006040518083038185875af1925050503d806000811462000792576040519150601f19603f3d011682016040523d82523d6000602084013e62000797565b606091505b509092509050620007aa828286620007b5565b979650505050505050565b60608315620007c65750816200067b565b825115620007d75782518084602001fd5b8160405162461bcd60e51b815260040162000083919062000a90565b611ed68062005d2483390190565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000842576200084262000801565b604052919050565b60006001600160401b0382111562000866576200086662000801565b5060051b60200190565b600082601f8301126200088257600080fd5b815160206200089b62000895836200084a565b62000817565b82815260059290921b84018101918181019086841115620008bb57600080fd5b8286015b84811015620008ef5780516001600160a01b0381168114620008e15760008081fd5b8352918301918301620008bf565b509695505050505050565b600080604083850312156200090e57600080fd5b82516001600160401b03808211156200092657600080fd5b818501915085601f8301126200093b57600080fd5b815160206200094e62000895836200084a565b82815260059290921b840181019181810190898411156200096e57600080fd5b948201945b838610156200098e5785518252948201949082019062000973565b91880151919650909350505080821115620009a857600080fd5b50620009b78582860162000870565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620009fa57634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121562000a1457600080fd5b5051919050565b60006020828403121562000a2e57600080fd5b815180151581146200067b57600080fd5b60005b8381101562000a5c57818101518382015260200162000a42565b8381111562000a6c576000848401525b50505050565b6000825162000a8681846020870162000a3f565b9190910192915050565b602081526000825180602084015262000ab181604085016020870162000a3f565b601f01601f19169190910160400192915050565b60805161523c62000ae86000396000818161072d015261372f015261523c6000f3fe608060405234801561001057600080fd5b50600436106103b95760003560e01c80638990d045116101f4578063c300fd641161011a578063ec856816116100ad578063f6ac84881161007c578063f6ac84881461098c578063f72bf8fe1461099f578063fb969b0a146109b2578063fe3b9be7146109ba57600080fd5b8063ec85681614610933578063f2fde38b14610946578063f306694a14610959578063f69e20461461098457600080fd5b8063d7e15131116100e9578063d7e15131146108e5578063db2e21bc14610905578063e8468ee41461090d578063ea3bd5df1461092057600080fd5b8063c300fd6414610899578063c3d9ed39146108ac578063cd653df6146108bf578063d3e3e352146108d257600080fd5b80639deb837e11610192578063acc3a00611610161578063acc3a00614610805578063b0f48cf714610818578063b12daf6914610843578063bf434b7a1461086e57600080fd5b80639deb837e14610792578063a6fe2b9e146107b2578063a88afabb146107d2578063ab2150cf146107f257600080fd5b80638e143ccb116101ce5780638e143ccb14610715578063901be0411461072857806393c82c751461074f5780639bbce4781461077257600080fd5b80638990d045146106c65780638da5cb5b146106f15780638dbdbe6d1461070257600080fd5b80635ba0bee1116102e45780636f56f56f116102775780638144eeba116102465780638144eeba14610678578063823c15121461068b5780638456cb59146106ab57806388e18e13146106b357600080fd5b80636f56f56f1461062a578063715018a614610652578063766718081461065c5780637e36701f1461066557600080fd5b80636274d49d116102b35780636274d49d146105d3578063699f200f146105e65780636a7784541461060f5780636db29f6d1461062257600080fd5b80635ba0bee1146105815780635c975abb146105ac57806361560c99146105b757806361644373146105ca57600080fd5b8063391feebb1161035c578063441a3e701161032b578063441a3e7014610507578063470f4224146105275780634ab01f5b1461055b578063574cdded1461056e57600080fd5b8063391feebb146104a657806339e0e760146104c95780633f4ba83a146104dc5780633f83b8a5146104e457600080fd5b80631acf5582116103985780631acf55821461042857806321f8a721146104305780632807b9a81461045b578063344afb5f1461048657600080fd5b806212100c146103be57806315943b99146103e45780631627905514610404575b600080fd5b6103d16103cc3660046149a7565b6109e5565b6040519081526020015b60405180910390f35b6103f76103f23660046149c9565b610b59565b6040516103db91906149e2565b610418610412366004614a3d565b3b151590565b60405190151581526020016103db565b6103d1610be6565b61044361043e3660046149c9565b610c77565b6040516001600160a01b0390911681526020016103db565b6103d16104693660046149a7565b601260209081526000928352604080842090915290825290205481565b6103d16104943660046149c9565b600e6020526000908152604090205481565b6104186104b4366004614a3d565b60016020526000908152604090205460ff1681565b6103d16104d7366004614a58565b610c92565b610418610ee2565b6104186104f23660046149c9565b60086020526000908152604090205460ff1681565b61051a6105153660046149a7565b610f38565b6040516103db9190614a84565b6104436105353660046149a7565b600a6020908152600092835260408084209091529082529020546001600160a01b031681565b610418610569366004614b00565b611232565b6103d161057c366004614b6b565b611359565b6103d161058f3660046149a7565b601460209081526000928352604080842090915290825290205481565b60025460ff16610418565b6103f76105c5366004614a58565b6116bf565b6103d160045481565b6103f76105e1366004614a58565b6117f3565b6104436105f43660046149c9565b6005602052600090815260409020546001600160a01b031681565b6103f761061d3660046149c9565b61191d565b610418611a1e565b61063d6106383660046149c9565b611b80565b604080519283526020830191909152016103db565b61065a611bc6565b005b6103d160035481565b6103d16106733660046149a7565b611bfc565b610418610686366004614c3c565b611c2d565b61069e6106993660046149c9565b611cf7565b6040516103db9190614caf565b610418611e0f565b6103d16106c1366004614b6b565b611e69565b6103d16106d43660046149a7565b600f60209081526000928352604080842090915290825290205481565b6000546001600160a01b0316610443565b610418610710366004614cf0565b611e85565b6103d16107233660046149c9565b612200565b6104437f000000000000000000000000000000000000000000000000000000000000000081565b61041861075d3660046149c9565b60076020526000908152604090205460ff1681565b6103d16107803660046149c9565b60156020526000908152604090205481565b6103d16107a03660046149c9565b60176020526000908152604090205481565b6103d16107c03660046149c9565b60066020526000908152604090205481565b6103d16107e03660046149c9565b60166020526000908152604090205481565b6104186108003660046149c9565b612334565b610418610813366004614a3d565b6123bd565b6103d16108263660046149a7565b601360209081526000928352604080842090915290825290205481565b6103d16108513660046149a7565b600b60209081526000928352604080842090915290825290205481565b6103d161087c3660046149a7565b601160209081526000928352604080842090915290825290205481565b6103f76108a73660046149c9565b612529565b6104186108ba366004614a3d565b612621565b6103f76108cd3660046149c9565b6126eb565b6104186108e0366004614d1c565b6127e3565b6103d16108f33660046149c9565b600c6020526000908152604090205481565b610418612986565b6103d161091b366004614b6b565b612ba4565b61063d61092e366004614cf0565b612c46565b6103f7610941366004614a58565b6130d4565b61065a610954366004614a3d565b6131fe565b6103d16109673660046149a7565b600d60209081526000928352604080842090915290825290205481565b610418613299565b61041861099a3660046149c9565b6133b6565b6103d16109ad366004614b6b565b6134e8565b61041861353e565b6103d16109c83660046149a7565b601060209081526000928352604080842090915290825290205481565b6000806109f0610be6565b90508083610a0d6c4f7074696f6e50726963696e6760981b610c77565b6001600160a01b0316635b7b6d886000610a2642612200565b8987610a446f566f6c6174696c6974794f7261636c6560801b610c77565b6001600160a01b0316633af2888b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a7c57600080fd5b505afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab49190614d50565b6040516001600160e01b031960e088901b1681529415156004860152602485019390935260448401919091526064830152608482015260a40160206040518083038186803b158015610b0557600080fd5b505afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190614d50565b610b479190614d7f565b610b519190614db4565b949350505050565b60608160008111610b855760405162461bcd60e51b8152600401610b7c90614dc8565b60405180910390fd5b60008381526009602090815260409182902080548351818402810184019094528084529091830182828015610bd957602002820191906000526020600020905b815481526020019060010190808311610bc5575b5050505050915050919050565b6000610c026d476d7850726963654f7261636c6560901b610c77565b6001600160a01b031663e1aa60366040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3a57600080fd5b505afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190614d50565b905090565b6000908152600560205260409020546001600160a01b031690565b6000610ca060025460ff1690565b15610cbd5760405162461bcd60e51b8152600401610b7c90614de5565b6000546001600160a01b03163314610ce75760405162461bcd60e51b8152600401610b7c90614e0f565b6000610cfa640cae68e9ab60db1b610c77565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a082319060240160206040518083038186803b158015610d3f57600080fd5b505afa158015610d53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d779190614d50565b60008681526007602052604090205490915060ff16610da85760405162461bcd60e51b8152600401610b7c90614e44565b80610ddb5760405162461bcd60e51b815260206004820152600360248201526245323560e81b6044820152606401610b7c565b6001600160a01b038416610e315760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207472616e7366657220746f207a65726f2061646472657373006044820152606401610b7c565b6000610e4d6d2932bbb0b9322937baba32b92b1960911b610c77565b9050610e7d610e6c6d2932bbb0b9322937baba32b92b1960911b610c77565b6001600160a01b03851690846138cd565b60405163ef9aacfd60e01b81526001600160a01b03868116600483015282169063ef9aacfd90602401600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b509398975050505050505050565b6000610efa69476f7665726e616e636560b01b610c77565b6001600160a01b0316336001600160a01b031614610f2a5760405162461bcd60e51b8152600401610b7c90614e61565b610f32613a38565b50600190565b610f40614929565b60025460ff1615610f635760405162461bcd60e51b8152600401610b7c90614de5565b333b15610f99573360009081526001602052604090205460ff16610f995760405162461bcd60e51b8152600401610b7c90614e7e565b60008381526007602052604090205460ff16610fc75760405162461bcd60e51b8152600401610b7c90614e44565b6000838152600960205260409020548210610ff45760405162461bcd60e51b8152600401610b7c90614ecd565b600083815260096020526040812080548490811061101457611014614eea565b9060005260206000200154905080600014156110425760405162461bcd60e51b8152600401610b7c90614f00565b60003382604051602001611057929190614f1d565b60408051601f1981840301815291815281516020928301206000888152600f8452828120828252909352912054909150806110ba5760405162461bcd60e51b815260206004820152600360248201526208a62760eb1b6044820152606401610b7c565b6000868152600b60209081526040808320868452825280832054898452601083528184208785529092528220546110f2908490614d7f565b6110fc9190614db4565b6000888152600f602090815260408083208784528252808320839055600354835260168252808320548b8452600c835281842054600b84528285208a8652909352908320549394509261114f9084614d7f565b6111599190614db4565b60008a8152600b602090815260408083208a8452909152812054919250906111818684614d7f565b61118b9190614db4565b90506111b133856111a16208e9ab60eb1b610c77565b6001600160a01b03169190613acb565b6111c633826111a1630ae8aa8960e31b610c77565b604080518b8152602081018990523381830152606081018790526080810186905290517fbe7586dfb192ca07af28bcc9fc95e78619abff84853e614ba95a4864e955c5929181900360a00190a16040805180820190915293845260208401525090979650505050505050565b600080546001600160a01b0316331461125d5760405162461bcd60e51b8152600401610b7c90614e0f565b8382146112915760405162461bcd60e51b8152602060048201526002602482015261229960f11b6044820152606401610b7c565b60005b8481101561134d5760008686838181106112b0576112b0614eea565b90506020020135905060008585848181106112cd576112cd614eea565b90506020020160208101906112e29190614a3d565b60008381526005602052604080822080546001600160a01b0319166001600160a01b03851690811790915590519293509184917fb37614c7d254ea8d16eb81fa11dddaeb266aa8ba4917980859c7740aff30c69191a35050808061134590614f3f565b915050611294565b50600195945050505050565b600061136760025460ff1690565b156113845760405162461bcd60e51b8152600401610b7c90614de5565b333b156113ba573360009081526001602052604090205460ff166113ba5760405162461bcd60e51b8152600401610b7c90614e7e565b60008281526007602052604090205460ff166113e85760405162461bcd60e51b8152600401610b7c90614e44565b60008281526009602052604090205484106114155760405162461bcd60e51b8152600401610b7c90614ecd565b600083116114355760405162461bcd60e51b8152600401610b7c90614f5a565b600082815260096020526040812080548690811061145557611455614eea565b9060005260206000200154905080600014156114835760405162461bcd60e51b8152600401610b7c90614f00565b6000838152600a60209081526040808320848452909152908190205490516370a0823160e01b815233600482015285916001600160a01b0316906370a082319060240160206040518083038186803b1580156114de57600080fd5b505afa1580156114f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115169190614d50565b101561154a5760405162461bcd60e51b815260206004820152600360248201526222989b60e91b6044820152606401610b7c565b600083815260156020526040902054611564908286611e69565b600084815260156020526040812054919350906115829084876134e8565b9050600083116115ba5760405162461bcd60e51b815260206004820152600360248201526245313560e81b6044820152606401610b7c565b6000848152600a602090815260408083208584529091529081902054905163079cc67960e41b8152336004820152602481018790526001600160a01b03909116906379cc679090604401600060405180830381600087803b15801561161e57600080fd5b505af1158015611632573d6000803e3d6000fd5b5050505060006116476208e9ab60eb1b610c77565b9050611668336116578487614f77565b6001600160a01b0384169190613acb565b60408051868152602081018590523381830152606081018890526080810186905290517f170d93e3a85ba1c08f72d2c0ebd8835178a9b9f444c318ab404506c743d925bd9181900360a00190a15050509392505050565b606082600081116116e25760405162461bcd60e51b8152600401610b7c90614dc8565b60008481526009602052604081205490816001600160401b0381111561170a5761170a614b97565b604051908082528060200260200182016040528015611733578160200160208202803683370190505b50905060005b828110156117e957600087815260096020526040812080548390811061176157611761614eea565b9060005260206000200154905060008782604051602001611783929190614f1d565b60408051601f19818403018152918152815160209283012060008c8152601484528281208282529093529120548551919250908590859081106117c8576117c8614eea565b602002602001018181525050505080806117e190614f3f565b915050611739565b5095945050505050565b606082600081116118165760405162461bcd60e51b8152600401610b7c90614dc8565b60008481526009602052604081205490816001600160401b0381111561183e5761183e614b97565b604051908082528060200260200182016040528015611867578160200160208202803683370190505b50905060005b828110156117e957600087815260096020526040812080548390811061189557611895614eea565b90600052602060002001549050600087826040516020016118b7929190614f1d565b60408051601f19818403018152918152815160209283012060008c8152600f84528281208282529093529120548551919250908590859081106118fc576118fc614eea565b6020026020010181815250505050808061191590614f3f565b91505061186d565b606081600081116119405760405162461bcd60e51b8152600401610b7c90614dc8565b60008381526009602052604081205490816001600160401b0381111561196857611968614b97565b604051908082528060200260200182016040528015611991578160200160208202803683370190505b50905060005b82811015611a15576000868152601160209081526040808320600990925282208054919291849081106119cc576119cc614eea565b90600052602060002001548152602001908152602001600020548282815181106119f8576119f8614eea565b602090810291909101015280611a0d81614f3f565b915050611997565b50949350505050565b6000611a2c60025460ff1690565b15611a495760405162461bcd60e51b8152600401610b7c90614de5565b333b15611a7f573360009081526001602052604090205460ff16611a7f5760405162461bcd60e51b8152600401610b7c90614e7e565b60035460009081526007602052604090205460ff1615611ab15760405162461bcd60e51b8152600401610b7c90614f8e565b6000611abe600354611b80565b91505080421015611af65760405162461bcd60e51b8152602060048201526002602482015261114d60f21b6044820152606401610b7c565b600454611b039082614faa565b421115611b385760405162461bcd60e51b815260206004820152600360248201526245323360e81b6044820152606401610b7c565b611b40610be6565b600354600090815260156020526040902055611b5c6001613afb565b50506003546000908152600760205260409020805460ff1916600190811790915590565b6000808260008111611ba45760405162461bcd60e51b8152600401610b7c90614dc8565b600084815260066020526040902054611bbc81612200565b9250925050915091565b6000546001600160a01b03163314611bf05760405162461bcd60e51b8152600401610b7c90614e0f565b611bfa60006140b2565b565b60096020528160005260406000208181548110611c1857600080fd5b90600052602060002001600091509150505481565b6000611c3b60025460ff1690565b15611c585760405162461bcd60e51b8152600401610b7c90614de5565b8251845114611c8e5760405162461bcd60e51b8152602060048201526002602482015261229960f11b6044820152606401610b7c565b60005b8451811015611cea57611cd7858281518110611caf57611caf614eea565b6020026020010151858381518110611cc957611cc9614eea565b602002602001015185611e85565b5080611ce281614f3f565b915050611c91565b50600190505b9392505050565b60608160008111611d1a5760405162461bcd60e51b8152600401610b7c90614dc8565b60008381526009602052604081205490816001600160401b03811115611d4257611d42614b97565b604051908082528060200260200182016040528015611d6b578160200160208202803683370190505b50905060005b82811015611a15576000868152600a6020908152604080832060099092528220805491929184908110611da657611da6614eea565b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b0316828281518110611de557611de5614eea565b6001600160a01b039092166020928302919091019091015280611e0781614f3f565b915050611d71565b6000611e2769476f7665726e616e636560b01b610c77565b6001600160a01b0316336001600160a01b031614611e575760405162461bcd60e51b8152600401610b7c90614e61565b611e5f614102565b610f326000613afb565b6000828411611e79576000610b51565b8382610b3d8583614f77565b6000611e9360025460ff1690565b15611eb05760405162461bcd60e51b8152600401610b7c90614de5565b333b15611ee6573360009081526001602052604090205460ff16611ee65760405162461bcd60e51b8152600401610b7c90614e7e565b60006003546001611ef79190614faa565b60035490915015611f645760035460009081526007602052604090205460ff168015611f32575060008181526008602052604090205460ff16155b611f645760405162461bcd60e51b815260206004820152600360248201526245313960e81b6044820152606401610b7c565b6000818152600960205260409020548510611f915760405162461bcd60e51b8152600401610b7c90614ecd565b60008411611fb15760405162461bcd60e51b8152600401610b7c90614f5a565b6000818152600960205260408120805487908110611fd157611fd1614eea565b906000526020600020015490508060001415611fff5760405162461bcd60e51b8152600401610b7c90614f00565b60008482604051602001612014929190614f1d565b60408051601f1981840301815291815281516020928301206000868152600f8452828120828252909352908220805491935088929091612055908490614faa565b90915550506000838152600b6020908152604080832085845290915281208054889290612083908490614faa565b90915550506000838152600c6020526040812080548892906120a6908490614faa565b90915550506000838152600d60209081526040808320858452909152812080548892906120d4908490614faa565b90915550506000838152600e6020526040812080548892906120f7908490614faa565b9091555061212390503330886121126208e9ab60eb1b610c77565b6001600160a01b031692919061415a565b61213d6d2932bbb0b9322937baba32b92b1960911b610c77565b6001600160a01b031663f3daeacc876040518263ffffffff1660e01b815260040161216a91815260200190565b600060405180830381600087803b15801561218457600080fd5b505af1158015612198573d6000803e3d6000fd5b505060408051868152602081018690529081018990526001600160a01b03881660608201523360808201527fcaa9001342572663a8f7c22e7c6f0331a45254407418d9f993ed2d1485adc205925060a001905060405180910390a15060019695505050505050565b60008061222a61220f84614198565b612218856141b8565b612223906001614faa565b60006141d2565b90506005612237826141ed565b101561226f5761226c61224982614198565b612252836141b8565b600761225d85614221565b6122679190614f77565b6141d2565b90505b60006122b761227d83614198565b612286846141b8565b61228f856141ed565b61229886614221565b6122a3906005614faa565b6122ad9190614f77565b6008600080614233565b9050838111611cf05760006122e26122ce86614198565b6122d7876141b8565b612223906002614faa565b905060056122ef826141ed565b10156123045761230161224982614198565b90505b61232b61231082614198565b612319836141b8565b612322846141ed565b61229885614221565b95945050505050565b600061234c69476f7665726e616e636560b01b610c77565b6001600160a01b0316336001600160a01b03161461237c5760405162461bcd60e51b8152600401610b7c90614e61565b60048290556040518281527f5259439c9ac2029585dd4a349897aa1e8298d26537c3b57453f275126db919189060200160405180910390a15060015b919050565b600080546001600160a01b031633146123e85760405162461bcd60e51b8152600401610b7c90614e0f565b813b6124545760405162461bcd60e51b815260206004820152603560248201527f436f6e747261637457686974656c6973743a2041646472657373206d757374206044820152746265206120636f6e7472616374206164647265737360581b6064820152608401610b7c565b6001600160a01b03821660009081526001602052604090205460ff16156124d55760405162461bcd60e51b815260206004820152602f60248201527f436f6e747261637457686974656c6973743a20436f6e747261637420616c726560448201526e18591e481dda1a5d195b1a5cdd1959608a1b6064820152608401610b7c565b6001600160a01b0382166000818152600160208190526040808320805460ff1916909217909155517ffbd3cde7ff522a917e485c8ed2a6e87590887ab399f5ac312307903f498543079190a2506001919050565b6060816000811161254c5760405162461bcd60e51b8152600401610b7c90614dc8565b60008381526009602052604081205490816001600160401b0381111561257457612574614b97565b60405190808252806020026020018201604052801561259d578160200160208202803683370190505b50905060005b82811015611a15576000868152600b60209081526040808320600990925282208054919291849081106125d8576125d8614eea565b906000526020600020015481526020019081526020016000205482828151811061260457612604614eea565b60209081029190910101528061261981614f3f565b9150506125a3565b6001600160a01b03811660009081526001602052604081205460ff1661269d5760405162461bcd60e51b815260206004820152602b60248201527f436f6e747261637457686974656c6973743a20436f6e7472616374206e6f742060448201526a1dda1a5d195b1a5cdd195960aa1b6064820152608401610b7c565b6001600160a01b038216600081815260016020526040808220805460ff19169055517f8e81447740597754af5db3e176253a36f7981a9549f48ace3f0cb233913f9d859190a2506001919050565b6060816000811161270e5760405162461bcd60e51b8152600401610b7c90614dc8565b60008381526009602052604081205490816001600160401b0381111561273657612736614b97565b60405190808252806020026020018201604052801561275f578160200160208202803683370190505b50905060005b82811015611a155760008681526013602090815260408083206009909252822080549192918490811061279a5761279a614eea565b90600052602060002001548152602001908152602001600020548282815181106127c6576127c6614eea565b6020908102919091010152806127db81614f3f565b915050612765565b600080546001600160a01b0316331461280e5760405162461bcd60e51b8152600401610b7c90614e0f565b60025460ff16156128315760405162461bcd60e51b8152600401610b7c90614de5565b600060035460016128429190614faa565b6000818152600c6020526040902054909150156128865760405162461bcd60e51b815260206004820152600260248201526108a760f31b6044820152606401610b7c565b600354156128d457600061289b600354611b80565b9150508042116128d25760405162461bcd60e51b8152602060048201526002602482015261453960f01b6044820152606401610b7c565b505b600081815260096020908152604090912084516128f392860190614947565b5060008181526006602052604081204290555b835181101561297c577f5185be10ef2a03e926961817be495a630ded54bceffb3ba11f6af477c9c766828285838151811061294357612943614eea565b6020026020010151604051612962929190918252602082015260400190565b60405180910390a18061297481614f3f565b915050612906565b5060019392505050565b600061299e69476f7665726e616e636560b01b610c77565b6001600160a01b0316336001600160a01b0316146129ce5760405162461bcd60e51b8152600401610b7c90614e61565b60025460ff16612a175760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610b7c565b6000612a286208e9ab60eb1b610c77565b90506000612a3c630ae8aa8960e31b610c77565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015612a8157600080fd5b505afa158015612a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab99190614d50565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015612afe57600080fd5b505afa158015612b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b369190614d50565b9050612b4c6001600160a01b0385163384613acb565b612b606001600160a01b0384163383613acb565b60408051338152602081018490527f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695910160405180910390a1600194505050505090565b6000612bbd6a466565537472617465677960a81b610c77565b604051633a11a3b960e21b81526004810186905260248101859052604481018490526001600160a01b03919091169063e8468ee4906064015b60206040518083038186803b158015612c0e57600080fd5b505afa158015612c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b519190614d50565b600080612c5560025460ff1690565b15612c725760405162461bcd60e51b8152600401610b7c90614de5565b333b15612ca8573360009081526001602052604090205460ff16612ca85760405162461bcd60e51b8152600401610b7c90614e7e565b6000612cb5600354611b80565b915050804210612ced5760405162461bcd60e51b8152602060048201526003602482015262114c8d60ea1b6044820152606401610b7c565b60035460009081526008602052604090205460ff16612d345760405162461bcd60e51b815260206004820152600360248201526204532360ec1b6044820152606401610b7c565b6003546000908152600960205260409020548610612d645760405162461bcd60e51b8152600401610b7c90614ecd565b60008511612d845760405162461bcd60e51b8152600401610b7c90614f5a565b6003546000908152600960205260408120805488908110612da757612da7614eea565b906000526020600020015490508060001415612dd55760405162461bcd60e51b8152600401610b7c90614f00565b60008582604051602001612dea929190614f1d565b6040516020818303038152906040528051906020012090506000612e136208e9ab60eb1b610c77565b90506000612e1f610be6565b90506000612e2d858b6109e5565b90506000612e3c83878d612ba4565b60035460009081526011602090815260408083208a8452909152812080549293508d92909190612e6d908490614faa565b90915550506003546000908152601260209081526040808320888452909152812080548d9290612e9e908490614faa565b9091555050600354600090815260136020908152604080832089845290915281208054849290612ecf908490614faa565b9091555050600354600090815260146020908152604080832088845290915281208054849290612f00908490614faa565b90915550506003546000908152600d6020908152604080832089845290915281208054849290612f31908490614faa565b90915550506003546000908152600e602052604081208054849290612f57908490614faa565b90915550612f7e90503330612f6c8486614faa565b6001600160a01b03881692919061415a565b8015612fb257612fb2612fa16d2332b2a234b9ba3934b13aba37b960911b610c77565b6001600160a01b0386169083613acb565b6003546000908152600a60209081526040808320898452909152902054612fe3906001600160a01b03168b8d613acb565b612ffd6d2932bbb0b9322937baba32b92b1960911b610c77565b6001600160a01b031663f3daeacc836040518263ffffffff1660e01b815260040161302a91815260200190565b600060405180830381600087803b15801561304457600080fd5b505af1158015613058573d6000803e3d6000fd5b505060035460408051918252602082018a905281018e905260608101859052608081018490526001600160a01b038d1660a08201523360c08201527f78de8c82973d11415ea2004f458680aa6d5826c3e8a798496a61db56fa66417b925060e001905060405180910390a1909b909a5098505050505050505050565b606082600081116130f75760405162461bcd60e51b8152600401610b7c90614dc8565b60008481526009602052604081205490816001600160401b0381111561311f5761311f614b97565b604051908082528060200260200182016040528015613148578160200160208202803683370190505b50905060005b828110156117e957600087815260096020526040812080548390811061317657613176614eea565b9060005260206000200154905060008782604051602001613198929190614f1d565b60408051601f19818403018152918152815160209283012060008c8152601284528281208282529093529120548551919250908590859081106131dd576131dd614eea565b602002602001018181525050505080806131f690614f3f565b91505061314e565b6000546001600160a01b031633146132285760405162461bcd60e51b8152600401610b7c90614e0f565b6001600160a01b03811661328d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b7c565b613296816140b2565b50565b60006132a760025460ff1690565b156132c45760405162461bcd60e51b8152600401610b7c90614de5565b60035460009081526007602052604090205460ff16156132f65760405162461bcd60e51b8152600401610b7c90614f8e565b60035460009081526008602052604090205460ff1661333d5760405162461bcd60e51b815260206004820152600360248201526204532360ec1b6044820152606401610b7c565b60006133596d2932bbb0b9322937baba32b92b1960911b610c77565b9050806001600160a01b031663f69e20466040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561339657600080fd5b505af11580156133aa573d6000803e3d6000fd5b50505050600191505090565b60006133ce69476f7665726e616e636560b01b610c77565b6001600160a01b0316336001600160a01b0316146133fe5760405162461bcd60e51b8152600401610b7c90614e61565b60025460ff16156134215760405162461bcd60e51b8152600401610b7c90614de5565b60035460009081526007602052604090205460ff16156134535760405162461bcd60e51b8152600401610b7c90614f8e565b6000613460600354611b80565b915050600454816134719190614faa565b42116134a45760405162461bcd60e51b8152602060048201526002602482015261114d60f21b6044820152606401610b7c565b60035460009081526015602052604090208390556134c26001613afb565b50506003546000908152600760205260409020805460ff19166001908117909155919050565b60006135016a466565537472617465677960a81b610c77565b604051637b95fc7f60e11b81526004810186905260248101859052604481018490526001600160a01b03919091169063f72bf8fe90606401612bf6565b600080546001600160a01b031633146135695760405162461bcd60e51b8152600401610b7c90614e0f565b60025460ff161561358c5760405162461bcd60e51b8152600401610b7c90614de5565b6000600354600161359d9190614faa565b60008181526008602052604090205490915060ff16156135e45760405162461bcd60e51b8152602060048201526002602482015261453560f01b6044820152606401610b7c565b6000818152600960205260409020546136245760405162461bcd60e51b8152602060048201526002602482015261229b60f11b6044820152606401610b7c565b600354156136725760035460009081526007602052604090205460ff166136725760405162461bcd60e51b8152602060048201526002602482015261453760f01b6044820152606401610b7c565b60005b60008281526009602052604090205481101561386c5760008281526009602052604081208054839081106136ab576136ab614eea565b9060005260206000200154905060006136ec6040518060400160405280600881526020016711d3560b50d0531360c21b8152506136e78461428f565b61438c565b905061371781604051806040016040528060078152602001662d45504f43482d60c81b81525061438c565b9050613726816136e78661428f565b905060006137537f00000000000000000000000000000000000000000000000000000000000000006143b8565b60405163266c45bb60e11b81529091506001600160a01b03821690634cd88b7690613784908590819060040161501a565b600060405180830381600087803b15801561379e57600080fd5b505af11580156137b2573d6000803e3d6000fd5b5050506000868152600a60209081526040808320878452825280832080546001600160a01b0319166001600160a01b038716908117909155898452600b8352818420888552909252918290205491516340c10f1960e01b8152306004820152602481019290925291506340c10f1990604401600060405180830381600087803b15801561383e57600080fd5b505af1158015613852573d6000803e3d6000fd5b50505050505050808061386490614f3f565b915050613675565b5060008181526008602052604090819020805460ff191660011790556003829055517fb5ca1ca1b7b47549eb8af476f3ef702fc63bcd8b8c01dc163b009bb818f97997906138bd9083815260200190565b60405180910390a1600191505090565b8015806139565750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561391c57600080fd5b505afa158015613930573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139549190614d50565b155b6139c15760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610b7c565b6040516001600160a01b038316602482015260448101829052613a2490849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614450565b505050565b6060610b518484600085614522565b60025460ff16613a815760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610b7c565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516001600160a01b038316602482015260448101829052613a2490849063a9059cbb60e01b906064016139ed565b6003546000908152600e602052604090205415613d4857600354600090815260096020908152604080832080548251818502810185019093528083529192909190830182828015613b6b57602002820191906000526020600020905b815481526020019060010190808311613b57575b5050505050905060005b8151811015613d45576000613bf860156000600354815260200190815260200160002054848481518110613bab57613bab614eea565b60200260200101516011600060035481526020019081526020016000206000878781518110613bdc57613bdc614eea565b6020026020010151815260200190815260200160002054611e69565b905080600b600060035481526020019081526020016000206000858581518110613c2457613c24614eea565b6020026020010151815260200190815260200160002054613c459190614f77565b6010600060035481526020019081526020016000206000858581518110613c6e57613c6e614eea565b602002602001015181526020019081526020016000206000828254613c939190614faa565b90915550508315613d32576013600060035481526020019081526020016000206000848481518110613cc757613cc7614eea565b60200260200101518152602001908152602001600020546010600060035481526020019081526020016000206000858581518110613d0757613d07614eea565b602002602001015181526020019081526020016000206000828254613d2c9190614faa565b90915550505b5080613d3d81614f3f565b915050613b75565b50505b6000613d5a630ae8aa8960e31b610c77565b90506000613d6f640cae68e9ab60db1b610c77565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015613db457600080fd5b505afa158015613dc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dec9190614d50565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015613e3157600080fd5b505afa158015613e45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e699190614d50565b9050613e856d2932bbb0b9322937baba32b92b1960911b610c77565b6003546000908152600e6020526040908190205490516303c2c06960e11b81526001600160a01b03929092169163078580d291613ec89160040190815260200190565b600060405180830381600087803b158015613ee257600080fd5b505af1158015613ef6573d6000803e3d6000fd5b50505050613f146d2932bbb0b9322937baba32b92b1960911b610c77565b6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613f4e57600080fd5b505af1158015613f62573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201528492506001600160a01b03871691506370a082319060240160206040518083038186803b158015613fa757600080fd5b505afa158015613fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fdf9190614d50565b613fe99190614f77565b6040516370a0823160e01b815230600482015290925081906001600160a01b038516906370a082319060240160206040518083038186803b15801561402d57600080fd5b505afa158015614041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140659190614d50565b61406f9190614f77565b90506000821180156140815750600081115b156140ab576003805460009081526016602090815260408083208690559254825260179052208190555b5050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460ff16156141255760405162461bcd60e51b8152600401610b7c90614de5565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613aae3390565b6040516001600160a01b03808516602483015283166044820152606481018290526141929085906323b872dd60e01b906084016139ed565b50505050565b60006141af6141aa6201518084614db4565b61463f565b50909392505050565b60006141ca6141aa6201518084614db4565b509392505050565b6000620151806141e38585856147b3565b610b519190614d7f565b6000806141fd6201518084614db4565b9050600761420c826003614faa565b614216919061503f565b611cf0906001614faa565b6000610b516141aa6201518084614db4565b600081614241603c85614d7f565b61424d610e1087614d7f565b6201518061425c8b8b8b6147b3565b6142669190614d7f565b6142709190614faa565b61427a9190614faa565b6142849190614faa565b979650505050505050565b6060816142b35750506040805180820190915260018152600360fc1b602082015290565b8160005b81156142dd57806142c781614f3f565b91506142d69050600a83614db4565b91506142b7565b6000816001600160401b038111156142f7576142f7614b97565b6040519080825280601f01601f191660200182016040528015614321576020820181803683370190505b5090505b8415610b5157614336600183614f77565b9150614343600a8661503f565b61434e906030614faa565b60f81b81838151811061436357614363614eea565b60200101906001600160f81b031916908160001a905350614385600a86614db4565b9450614325565b606082826040516020016143a1929190615053565b604051602081830303815290604052905092915050565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b0381166123b85760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b6044820152606401610b7c565b60006144a5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613a299092919063ffffffff16565b805190915015613a2457808060200190518101906144c39190615082565b613a245760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b7c565b6060824710156145835760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610b7c565b843b6145d15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b7c565b600080866001600160a01b031685876040516145ed91906150a4565b60006040518083038185875af1925050503d806000811461462a576040519150601f19603f3d011682016040523d82523d6000602084013e61462f565b606091505b50915091506142848282866148f0565b60008080838162253d8c6146568362010bd96150c0565b61466091906150c0565b9050600062023ab1614673836004615101565b61467d9190615186565b9050600461468e8262023ab1615101565b6146999060036150c0565b6146a39190615186565b6146ad90836151b4565b9150600062164b096146c08460016150c0565b6146cc90610fa0615101565b6146d69190615186565b905060046146e6826105b5615101565b6146f09190615186565b6146fa90846151b4565b61470590601f6150c0565b9250600061098f614717856050615101565b6147219190615186565b9050600060506147338361098f615101565b61473d9190615186565b61474790866151b4565b9050614754600b83615186565b945061476185600c615101565b61476c8360026150c0565b61477691906151b4565b915084836147856031876151b4565b614790906064615101565b61479a91906150c0565b6147a491906150c0565b9a919950975095505050505050565b60006107b28410156147c457600080fd5b838383600062253d8c60046064600c6147de600e886151b4565b6147e89190615186565b6147f4886113246150c0565b6147fe91906150c0565b6148089190615186565b614813906003615101565b61481d9190615186565b600c8061482b600e886151b4565b6148359190615186565b61484090600c615101565b61484b6002886151b4565b61485591906151b4565b6148619061016f615101565b61486b9190615186565b6004600c61487a600e896151b4565b6148849190615186565b614890896112c06150c0565b61489a91906150c0565b6148a6906105b5615101565b6148b09190615186565b6148bc617d4b876151b4565b6148c691906150c0565b6148d091906150c0565b6148da91906151b4565b6148e491906151b4565b98975050505050505050565b606083156148ff575081611cf0565b82511561490f5782518084602001fd5b8160405162461bcd60e51b8152600401610b7c91906151f3565b60405180604001604052806002906020820280368337509192915050565b828054828255906000526020600020908101928215614982579160200282015b82811115614982578251825591602001919060010190614967565b5061498e929150614992565b5090565b5b8082111561498e5760008155600101614993565b600080604083850312156149ba57600080fd5b50508035926020909101359150565b6000602082840312156149db57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015614a1a578351835292840192918401916001016149fe565b50909695505050505050565b80356001600160a01b03811681146123b857600080fd5b600060208284031215614a4f57600080fd5b611cf082614a26565b60008060408385031215614a6b57600080fd5b82359150614a7b60208401614a26565b90509250929050565b60408101818360005b6002811015614aac578151835260209283019290910190600101614a8d565b50505092915050565b60008083601f840112614ac757600080fd5b5081356001600160401b03811115614ade57600080fd5b6020830191508360208260051b8501011115614af957600080fd5b9250929050565b60008060008060408587031215614b1657600080fd5b84356001600160401b0380821115614b2d57600080fd5b614b3988838901614ab5565b90965094506020870135915080821115614b5257600080fd5b50614b5f87828801614ab5565b95989497509550505050565b600080600060608486031215614b8057600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112614bbe57600080fd5b813560206001600160401b0380831115614bda57614bda614b97565b8260051b604051601f19603f83011681018181108482111715614bff57614bff614b97565b604052938452858101830193838101925087851115614c1d57600080fd5b83870191505b8482101561428457813583529183019190830190614c23565b600080600060608486031215614c5157600080fd5b83356001600160401b0380821115614c6857600080fd5b614c7487838801614bad565b94506020860135915080821115614c8a57600080fd5b50614c9786828701614bad565b925050614ca660408501614a26565b90509250925092565b6020808252825182820181905260009190848201906040850190845b81811015614a1a5783516001600160a01b031683529284019291840191600101614ccb565b600080600060608486031215614d0557600080fd5b8335925060208401359150614ca660408501614a26565b600060208284031215614d2e57600080fd5b81356001600160401b03811115614d4457600080fd5b610b5184828501614bad565b600060208284031215614d6257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615614d9957614d99614d69565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614dc357614dc3614d9e565b500490565b60208082526003908201526245313360e81b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526003908201526245313760e81b604082015260600190565b60208082526003908201526222991960e91b604082015260600190565b6020808252602f908201527f436f6e747261637457686974656c6973743a20436f6e7472616374206d75737460408201526e081899481dda1a5d195b1a5cdd1959608a1b606082015260800190565b60208082526003908201526204531360ec1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60208082526003908201526222989960e91b604082015260600190565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000600019821415614f5357614f53614d69565b5060010190565b60208082526003908201526245313160e81b604082015260600190565b600082821015614f8957614f89614d69565b500390565b602080825260029082015261453360f01b604082015260600190565b60008219821115614fbd57614fbd614d69565b500190565b60005b83811015614fdd578181015183820152602001614fc5565b838111156141925750506000910152565b60008151808452615006816020860160208601614fc2565b601f01601f19169290920160200192915050565b60408152600061502d6040830185614fee565b828103602084015261232b8185614fee565b60008261504e5761504e614d9e565b500690565b60008351615065818460208801614fc2565b835190830190615079818360208801614fc2565b01949350505050565b60006020828403121561509457600080fd5b81518015158114611cf057600080fd5b600082516150b6818460208701614fc2565b9190910192915050565b600080821280156001600160ff1b03849003851316156150e2576150e2614d69565b600160ff1b83900384128116156150fb576150fb614d69565b50500190565b60006001600160ff1b038184138284138082168684048611161561512757615127614d69565b600160ff1b600087128281168783058912161561514657615146614d69565b6000871292508782058712848416161561516257615162614d69565b8785058712818416161561517857615178614d69565b505050929093029392505050565b60008261519557615195614d9e565b600160ff1b8214600019841416156151af576151af614d69565b500590565b60008083128015600160ff1b8501841216156151d2576151d2614d69565b6001600160ff1b03840183138116156151ed576151ed614d69565b50500390565b602081526000611cf06020830184614fee56fea26469706673582212200c67f35df16d7f5d0fff862860da4f679a5363469d2528304836b701d129db4464736f6c63430008090033608060405234801561001057600080fd5b50611eb6806100206000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80635c975abb11610104578063a217fddf116100a2578063d539139311610071578063d5391393146103ce578063d547741f146103f5578063dd62ed3e14610408578063e63ab1e91461044157600080fd5b8063a217fddf1461038d578063a457c2d714610395578063a9059cbb146103a8578063ca15c873146103bb57600080fd5b80638456cb59116100de5780638456cb591461033f5780639010d07c1461034757806391d148541461037257806395d89b411461038557600080fd5b80635c975abb146102f757806370a082311461030357806379cc67901461032c57600080fd5b8063313ce567116101715780633f4ba83a1161014b5780633f4ba83a146102b657806340c10f19146102be57806342966c68146102d15780634cd88b76146102e457600080fd5b8063313ce5671461028157806336568abe1461029057806339509351146102a357600080fd5b806318160ddd116101ad57806318160ddd1461022457806323b872dd14610236578063248a9ca3146102495780632f2ff15d1461026c57600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063095ea7b314610211575b600080fd5b6101e76101e23660046119fd565b610456565b60405190151581526020015b60405180910390f35b610204610481565b6040516101f39190611a53565b6101e761021f366004611aa2565b610513565b60cb545b6040519081526020016101f3565b6101e7610244366004611acc565b610529565b610228610257366004611b08565b60009081526065602052604090206001015490565b61027f61027a366004611b21565b6105d8565b005b604051601281526020016101f3565b61027f61029e366004611b21565b610603565b6101e76102b1366004611aa2565b610681565b61027f6106bd565b61027f6102cc366004611aa2565b610751565b61027f6102df366004611b08565b6107f0565b61027f6102f2366004611bf0565b6107fd565b61012d5460ff166101e7565b610228610311366004611c54565b6001600160a01b0316600090815260c9602052604090205490565b61027f61033a366004611aa2565b610874565b61027f6108f5565b61035a610355366004611c6f565b610987565b6040516001600160a01b0390911681526020016101f3565b6101e7610380366004611b21565b6109a6565b6102046109d1565b610228600081565b6101e76103a3366004611aa2565b6109e0565b6101e76103b6366004611aa2565b610a79565b6102286103c9366004611b08565b610a86565b6102287f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61027f610403366004611b21565b610a9d565b610228610416366004611c91565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b610228600080516020611e6183398151915281565b60006001600160e01b03198216635a05180f60e01b148061047b575061047b82610ac3565b92915050565b606060cc805461049090611cbb565b80601f01602080910402602001604051908101604052809291908181526020018280546104bc90611cbb565b80156105095780601f106104de57610100808354040283529160200191610509565b820191906000526020600020905b8154815290600101906020018083116104ec57829003601f168201915b5050505050905090565b6000610520338484610af8565b50600192915050565b6000610536848484610c1c565b6001600160a01b038416600090815260ca60209081526040808320338452909152902054828110156105c05760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6105cd8533858403610af8565b506001949350505050565b6000828152606560205260409020600101546105f48133610df7565b6105fe8383610e5b565b505050565b6001600160a01b03811633146106735760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016105b7565b61067d8282610e7d565b5050565b33600081815260ca602090815260408083206001600160a01b038716845290915281205490916105209185906106b8908690611d0c565b610af8565b6106d5600080516020611e61833981519152336109a6565b6107475760405162461bcd60e51b815260206004820152603960248201527f45524332305072657365744d696e7465725061757365723a206d75737420686160448201527f76652070617573657220726f6c6520746f20756e70617573650000000000000060648201526084016105b7565b61074f610e9f565b565b61077b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336109a6565b6107e65760405162461bcd60e51b815260206004820152603660248201527f45524332305072657365744d696e7465725061757365723a206d7573742068616044820152751d99481b5a5b9d195c881c9bdb19481d1bc81b5a5b9d60521b60648201526084016105b7565b61067d8282610f34565b6107fa338261101f565b50565b600054610100900460ff1680610816575060005460ff16155b6108325760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff16158015610854576000805461ffff19166101011790555b61085e8383611179565b80156105fe576000805461ff0019169055505050565b60006108808333610416565b9050818110156108de5760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b60648201526084016105b7565b6108eb8333848403610af8565b6105fe838361101f565b61090d600080516020611e61833981519152336109a6565b61097f5760405162461bcd60e51b815260206004820152603760248201527f45524332305072657365744d696e7465725061757365723a206d75737420686160448201527f76652070617573657220726f6c6520746f20706175736500000000000000000060648201526084016105b7565b61074f61121c565b600082815260976020526040812061099f9083611299565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd805461049090611cbb565b33600090815260ca602090815260408083206001600160a01b038616845290915281205482811015610a625760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016105b7565b610a6f3385858403610af8565b5060019392505050565b6000610520338484610c1c565b600081815260976020526040812061047b906112a5565b600082815260656020526040902060010154610ab98133610df7565b6105fe8383610e7d565b60006001600160e01b03198216637965db0b60e01b148061047b57506301ffc9a760e01b6001600160e01b031983161461047b565b6001600160a01b038316610b5a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016105b7565b6001600160a01b038216610bbb5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016105b7565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610c805760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016105b7565b6001600160a01b038216610ce25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016105b7565b610ced8383836112af565b6001600160a01b038316600090815260c9602052604090205481811015610d655760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016105b7565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610d9c908490611d0c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610de891815260200190565b60405180910390a35b50505050565b610e0182826109a6565b61067d57610e19816001600160a01b031660146112ba565b610e248360206112ba565b604051602001610e35929190611d72565b60408051601f198184030181529082905262461bcd60e51b82526105b791600401611a53565b610e658282611456565b60008281526097602052604090206105fe90826114dc565b610e8782826114f1565b60008281526097602052604090206105fe9082611558565b61012d5460ff16610ee95760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016105b7565b61012d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b038216610f8a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105b7565b610f96600083836112af565b8060cb6000828254610fa89190611d0c565b90915550506001600160a01b038216600090815260c9602052604081208054839290610fd5908490611d0c565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b03821661107f5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016105b7565b61108b826000836112af565b6001600160a01b038216600090815260c96020526040902054818110156110ff5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016105b7565b6001600160a01b038316600090815260c960205260408120838303905560cb805484929061112e908490611de7565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600054610100900460ff1680611192575060005460ff16155b6111ae5760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff161580156111d0576000805461ffff19166101011790555b6111d861156d565b6111e061156d565b6111e861156d565b6111f061156d565b6111fa83836115d8565b61120261156d565b61120a61166d565b61121261156d565b61085e83836116e3565b61012d5460ff16156112635760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016105b7565b61012d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610f173390565b600061099f8383611787565b600061047b825490565b6105fe8383836117b1565b606060006112c9836002611dfe565b6112d4906002611d0c565b67ffffffffffffffff8111156112ec576112ec611b4d565b6040519080825280601f01601f191660200182016040528015611316576020820181803683370190505b509050600360fc1b8160008151811061133157611331611e1d565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061136057611360611e1d565b60200101906001600160f81b031916908160001a9053506000611384846002611dfe565b61138f906001611d0c565b90505b6001811115611407576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106113c3576113c3611e1d565b1a60f81b8282815181106113d9576113d9611e1d565b60200101906001600160f81b031916908160001a90535060049490941c9361140081611e33565b9050611392565b50831561099f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016105b7565b61146082826109a6565b61067d5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556114983390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061099f836001600160a01b038416611818565b6114fb82826109a6565b1561067d5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061099f836001600160a01b038416611867565b600054610100900460ff1680611586575060005460ff16155b6115a25760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff161580156115c4576000805461ffff19166101011790555b80156107fa576000805461ff001916905550565b600054610100900460ff16806115f1575060005460ff16155b61160d5760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff1615801561162f576000805461ffff19166101011790555b82516116429060cc906020860190611964565b5081516116569060cd906020850190611964565b5080156105fe576000805461ff0019169055505050565b600054610100900460ff1680611686575060005460ff16155b6116a25760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff161580156116c4576000805461ffff19166101011790555b61012d805460ff1916905580156107fa576000805461ff001916905550565b600054610100900460ff16806116fc575060005460ff16155b6117185760405162461bcd60e51b81526004016105b790611d24565b600054610100900460ff1615801561173a576000805461ffff19166101011790555b61174560003361195a565b61176f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63361195a565b61085e600080516020611e618339815191523361195a565b600082600001828154811061179e5761179e611e1d565b9060005260206000200154905092915050565b61012d5460ff16156105fe5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b60648201526084016105b7565b600081815260018301602052604081205461185f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561047b565b50600061047b565b6000818152600183016020526040812054801561195057600061188b600183611de7565b855490915060009061189f90600190611de7565b90508181146119045760008660000182815481106118bf576118bf611e1d565b90600052602060002001549050808760000184815481106118e2576118e2611e1d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061191557611915611e4a565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061047b565b600091505061047b565b61067d8282610e5b565b82805461197090611cbb565b90600052602060002090601f01602090048101928261199257600085556119d8565b82601f106119ab57805160ff19168380011785556119d8565b828001600101855582156119d8579182015b828111156119d85782518255916020019190600101906119bd565b506119e49291506119e8565b5090565b5b808211156119e457600081556001016119e9565b600060208284031215611a0f57600080fd5b81356001600160e01b03198116811461099f57600080fd5b60005b83811015611a42578181015183820152602001611a2a565b83811115610df15750506000910152565b6020815260008251806020840152611a72816040850160208701611a27565b601f01601f19169190910160400192915050565b80356001600160a01b0381168114611a9d57600080fd5b919050565b60008060408385031215611ab557600080fd5b611abe83611a86565b946020939093013593505050565b600080600060608486031215611ae157600080fd5b611aea84611a86565b9250611af860208501611a86565b9150604084013590509250925092565b600060208284031215611b1a57600080fd5b5035919050565b60008060408385031215611b3457600080fd5b82359150611b4460208401611a86565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611b7457600080fd5b813567ffffffffffffffff80821115611b8f57611b8f611b4d565b604051601f8301601f19908116603f01168101908282118183101715611bb757611bb7611b4d565b81604052838152866020858801011115611bd057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215611c0357600080fd5b823567ffffffffffffffff80821115611c1b57600080fd5b611c2786838701611b63565b93506020850135915080821115611c3d57600080fd5b50611c4a85828601611b63565b9150509250929050565b600060208284031215611c6657600080fd5b61099f82611a86565b60008060408385031215611c8257600080fd5b50508035926020909101359150565b60008060408385031215611ca457600080fd5b611cad83611a86565b9150611b4460208401611a86565b600181811c90821680611ccf57607f821691505b60208210811415611cf057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115611d1f57611d1f611cf6565b500190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611daa816017850160208801611a27565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611ddb816028840160208801611a27565b01602801949350505050565b600082821015611df957611df9611cf6565b500390565b6000816000190483118215151615611e1857611e18611cf6565b500290565b634e487b7160e01b600052603260045260246000fd5b600081611e4257611e42611cf6565b506000190190565b634e487b7160e01b600052603160045260246000fdfe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862aa26469706673582212201e8e71d04321c61cbea798e0c220b88d5e37b921bdfb67b7e07db65b7fd1d00064736f6c63430008090033697e8381f00a7f3df6dd96caab109663285a5bca4805fbe06d6745a97b987c60000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000c474d5800000000000000000000000000000000000000000000000000000000006573474d580000000000000000000000000000000000000000000000000000005745544800000000000000000000000000000000000000000000000000000000526577617264526f7574657256320000000000000000000000000000000000005374616b6564476d78547261636b657200000000000000000000000000000000426f6e7573476d78547261636b65720000000000000000000000000000000000466565476d78547261636b6572000000000000000000000000000000000000004f7074696f6e50726963696e6700000000000000000000000000000000000000476d7850726963654f7261636c65000000000000000000000000000000000000566f6c6174696c6974794f7261636c65000000000000000000000000000000004665654469737472696275746f720000000000000000000000000000000000004665655374726174656779000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000fc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a000000000000000000000000f42ae1d54fd613c9bb14810b0588faaa09a426ca00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000a906f338cb21815cbc4bc87ace9e68c87ef8d8f1000000000000000000000000908c4d94d34924765f1edc22a1dd098397c59dd40000000000000000000000004d268a7d4c16ceb5a606c173bd974984343fea13000000000000000000000000d2d1162512f927a7e282ef43a362659e4f2a728f0000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b000000000000000000000000f92009a73d810798cb71651a73e4c33a3033c3e700000000000000000000000083a5b587ae36f342d405a7e5971941168e0adb5d00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c10000000000000000000000003f3c58ccb0655fa9161d0b4b49b217b3f6478d5a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000c474d5800000000000000000000000000000000000000000000000000000000006573474d580000000000000000000000000000000000000000000000000000005745544800000000000000000000000000000000000000000000000000000000526577617264526f7574657256320000000000000000000000000000000000005374616b6564476d78547261636b657200000000000000000000000000000000426f6e7573476d78547261636b65720000000000000000000000000000000000466565476d78547261636b6572000000000000000000000000000000000000004f7074696f6e50726963696e6700000000000000000000000000000000000000476d7850726963654f7261636c65000000000000000000000000000000000000566f6c6174696c6974794f7261636c65000000000000000000000000000000004665654469737472696275746f720000000000000000000000000000000000004665655374726174656779000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000fc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a000000000000000000000000f42ae1d54fd613c9bb14810b0588faaa09a426ca00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000a906f338cb21815cbc4bc87ace9e68c87ef8d8f1000000000000000000000000908c4d94d34924765f1edc22a1dd098397c59dd40000000000000000000000004d268a7d4c16ceb5a606c173bd974984343fea13000000000000000000000000d2d1162512f927a7e282ef43a362659e4f2a728f0000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b000000000000000000000000f92009a73d810798cb71651a73e4c33a3033c3e700000000000000000000000083a5b587ae36f342d405a7e5971941168e0adb5d00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c10000000000000000000000003f3c58ccb0655fa9161d0b4b49b217b3f6478d5a
-----Decoded View---------------
Arg [0] : sources (bytes32[]): System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[]
Arg [1] : destinations (address[]): 0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a,0xf42ae1d54fd613c9bb14810b0588faaa09a426ca,0x82af49447d8a07e3bd95bd0d56f35241523fbab1,0xa906f338cb21815cbc4bc87ace9e68c87ef8d8f1,0x908c4d94d34924765f1edc22a1dd098397c59dd4,0x4d268a7d4c16ceb5a606c173bd974984343fea13,0xd2d1162512f927a7e282ef43a362659e4f2a728f,0x2b99e3d67dad973c1b9747da742b7e26c8bdd67b,0xf92009a73d810798cb71651a73e4c33a3033c3e7,0x83a5b587ae36f342d405a7e5971941168e0adb5d,0x55594cce8cc0014ea08c49fd820d731308f204c1,0x3f3c58ccb0655fa9161d0b4b49b217b3f6478d5a
-----Encoded View---------------
28 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [2] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [3] : 474d580000000000000000000000000000000000000000000000000000000000
Arg [4] : 6573474d58000000000000000000000000000000000000000000000000000000
Arg [5] : 5745544800000000000000000000000000000000000000000000000000000000
Arg [6] : 526577617264526f757465725632000000000000000000000000000000000000
Arg [7] : 5374616b6564476d78547261636b657200000000000000000000000000000000
Arg [8] : 426f6e7573476d78547261636b65720000000000000000000000000000000000
Arg [9] : 466565476d78547261636b657200000000000000000000000000000000000000
Arg [10] : 4f7074696f6e50726963696e6700000000000000000000000000000000000000
Arg [11] : 476d7850726963654f7261636c65000000000000000000000000000000000000
Arg [12] : 566f6c6174696c6974794f7261636c6500000000000000000000000000000000
Arg [13] : 4665654469737472696275746f72000000000000000000000000000000000000
Arg [14] : 4665655374726174656779000000000000000000000000000000000000000000
Arg [15] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [16] : 000000000000000000000000fc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a
Arg [17] : 000000000000000000000000f42ae1d54fd613c9bb14810b0588faaa09a426ca
Arg [18] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [19] : 000000000000000000000000a906f338cb21815cbc4bc87ace9e68c87ef8d8f1
Arg [20] : 000000000000000000000000908c4d94d34924765f1edc22a1dd098397c59dd4
Arg [21] : 0000000000000000000000004d268a7d4c16ceb5a606c173bd974984343fea13
Arg [22] : 000000000000000000000000d2d1162512f927a7e282ef43a362659e4f2a728f
Arg [23] : 0000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b
Arg [24] : 000000000000000000000000f92009a73d810798cb71651a73e4c33a3033c3e7
Arg [25] : 00000000000000000000000083a5b587ae36f342d405a7e5971941168e0adb5d
Arg [26] : 00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c1
Arg [27] : 0000000000000000000000003f3c58ccb0655fa9161d0b4b49b217b3f6478d5a
Deployed ByteCode Sourcemap
116532:36048:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144516:562;;;;;;:::i;:::-;;:::i;:::-;;;413:25:1;;;401:2;386:18;144516:562:0;;;;;;;;146686:195;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;113202:188::-;;;;;;:::i;:::-;113329:17;113374:8;;;113202:188;;;;1805:14:1;;1798:22;1780:41;;1768:2;1753:18;113202:188:0;1640:187:1;151914:137:0;;;:::i;152213:105::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2181:32:1;;;2163:51;;2151:2;2136:18;152213:105:0;2017:203:1;119381:87:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;118516:52;;;;;;:::i;:::-;;;;;;;;;;;;;;111234;;;;;;:::i;:::-;;;;;;;;;;;;;;;;140872:772;;;;;;:::i;:::-;;:::i;122945:109::-;;;:::i;117480:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;138882:1921;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;117694:72::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;117694:72:0;;;123750:479;;;;;;:::i;:::-;;:::i;136710:1270::-;;;;;;:::i;:::-;;:::i;119816:71::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;107194:86;107265:7;;;;107194:86;;151244:603;;;;;;:::i;:::-;;:::i;116953:47::-;;;;;;148335:608;;;;;;:::i;:::-;;:::i;117072:44::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;117072:44:0;;;149074:540;;;;;;:::i;:::-;;:::i;125252:561::-;;;:::i;146271:298::-;;;;;;:::i;:::-;;:::i;:::-;;;;4881:25:1;;;4937:2;4922:18;;4915:34;;;;4854:18;146271:298:0;4707:248:1;110036:103:0;;;:::i;:::-;;116880:27;;;;;;117581:49;;;;;;:::i;:::-;;:::i;133313:383::-;;;;;;:::i;:::-;;:::i;146996:505::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;122652:148::-;;;:::i;144122:217::-;;;;;;:::i;:::-;;:::i;118716:72::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;109385:87;109431:7;109458:6;-1:-1:-1;;;;;109458:6:0;109385:87;;131373:1622;;;;;;:::i;:::-;;:::i;141878:1755::-;;;;;;:::i;:::-;;:::i;116790:44::-;;;;;117314:46;;;;;;:::i;:::-;;;;;;;;;;;;;;;;119936:51;;;;;;:::i;:::-;;;;;;;;;;;;;;120136:52;;;;;;:::i;:::-;;;;;;;;;;;;;;117169:50;;;;;;:::i;:::-;;;;;;;;;;;;;;120036:54;;;;;;:::i;:::-;;;;;;;;;;;;;;123237:288;;;;;;:::i;:::-;;:::i;111533:526::-;;;;;;:::i;:::-;;:::i;119589:72::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;117888:88;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;119137;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;147632:540;;;;;;:::i;:::-;;:::i;112291:378::-;;;;;;:::i;:::-;;:::i;150577:505::-;;;;;;:::i;:::-;;:::i;130318:739::-;;;;;;:::i;:::-;;:::i;118084:53::-;;;;;;:::i;:::-;;;;;;;;;;;;;;124423:722;;;:::i;145278:331::-;;;;;;:::i;:::-;;:::i;133981:2423::-;;;;;;:::i;:::-;;:::i;149784:670::-;;;;;;:::i;:::-;;:::i;110294:238::-;;;;;;:::i;:::-;;:::i;118290:87::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;138194:451;;;:::i;125920:524::-;;;;;;:::i;:::-;;:::i;145805:349::-;;;;;;:::i;:::-;;:::i;128647:1507::-;;;:::i;118925:90::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;144516:562;144624:15;144657:20;144680:13;:11;:13::i;:::-;144657:36;;145058:12;145034:7;144743:27;-1:-1:-1;;;144743:10:0;:27::i;:::-;-1:-1:-1;;;;;144728:58:0;;144805:5;144829:46;144859:15;144829:29;:46::i;:::-;144894:7;144920:12;144969:30;-1:-1:-1;;;144969:10:0;:30::i;:::-;-1:-1:-1;;;;;144951:63:0;;:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;144728:303;;-1:-1:-1;;;;;;144728:303:0;;;;;;;8483:14:1;;8476:22;144728:303:0;;;8458:41:1;8515:18;;;8508:34;;;;8558:18;;;8551:34;;;;8601:18;;;8594:34;8644:19;;;8637:35;8430:19;;144728:303:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:313;;;;:::i;:::-;144727:343;;;;:::i;:::-;144704:366;144516:562;-1:-1:-1;;;;144516:562:0:o;146686:195::-;146813:16;146788:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;;;;;;;;;146854:19:::1;::::0;;;:12:::1;:19;::::0;;;;;;;;146847:26;;;;;;::::1;::::0;;;;;;;;;;146854:19;;146847:26;::::1;146854:19:::0;146847:26;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;146686:195:::0;;;;:::o;151914:137::-;151958:7;151998:28;-1:-1:-1;;;151998:10:0;:28::i;:::-;-1:-1:-1;;;;;151985:56:0;;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;151978:65;;151914:137;:::o;152213:105::-;152268:7;152295:15;;;:9;:15;;;;;;-1:-1:-1;;;;;152295:15:0;;152213:105::o;140872:772::-;141018:7;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;109431:7;109458:6;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23:::1;109597:68;;;;-1:-1:-1::0;;;109597:68:0::1;;;;;;;:::i;:::-;141038:12:::2;141060:19;-1:-1:-1::0;;;141060:10:0::2;:19::i;:::-;141114:30;::::0;-1:-1:-1;;;141114:30:0;;141138:4:::2;141114:30;::::0;::::2;2163:51:1::0;141038:42:0;;-1:-1:-1;141091:20:0::2;::::0;-1:-1:-1;;;;;141114:15:0;::::2;::::0;::::2;::::0;2136:18:1;;141114:30:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;141209:29;::::0;;;:14:::2;:29;::::0;;;;;141091:53;;-1:-1:-1;141209:29:0::2;;141201:45;;;;-1:-1:-1::0;;;141201:45:0::2;;;;;;;:::i;:::-;141265:17:::0;141257:33:::2;;;::::0;-1:-1:-1;;;141257:33:0;;10815:2:1;141257:33:0::2;::::0;::::2;10797:21:1::0;10854:1;10834:18;;;10827:29;-1:-1:-1;;;10872:18:1;;;10865:33;10915:18;;141257:33:0::2;10613:326:1::0;141257:33:0::2;-1:-1:-1::0;;;;;141309:22:0;::::2;141301:66;;;::::0;-1:-1:-1;;;141301:66:0;;11146:2:1;141301:66:0::2;::::0;::::2;11128:21:1::0;11185:2;11165:18;;;11158:30;11224:33;11204:18;;;11197:61;11275:18;;141301:66:0::2;10944:355:1::0;141301:66:0::2;141380:28;141441;-1:-1:-1::0;;;141441:10:0::2;:28::i;:::-;141380:100;;141493:61;141511:28;-1:-1:-1::0;;;141511:10:0::2;:28::i;:::-;-1:-1:-1::0;;;;;141493:17:0;::::2;::::0;141541:12;141493:17:::2;:61::i;:::-;141567:37;::::0;-1:-1:-1;;;141567:37:0;;-1:-1:-1;;;;;2181:32:1;;;141567:37:0::2;::::0;::::2;2163:51:1::0;141567:27:0;::::2;::::0;::::2;::::0;2136:18:1;;141567:37:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;141624:12:0;;140872:772;-1:-1:-1;;;;;;;;140872:772:0:o;122945:109::-;122997:4;152416:24;-1:-1:-1;;;152416:10:0;:24::i;:::-;-1:-1:-1;;;;;152402:38:0;:10;-1:-1:-1;;;;;152402:38:0;;152394:54;;;;-1:-1:-1;;;152394:54:0;;;;;;;:::i;:::-;123014:10:::1;:8;:10::i;:::-;-1:-1:-1::0;123042:4:0::1;122945:109:::0;:::o;138882:1921::-;139029:17;;:::i;:::-;107265:7;;;;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;112821:10:::1;113329:17:::0;113374:8;112806:182:::1;;112894:10;112873:32;::::0;;;:20:::1;:32;::::0;;;;;::::1;;112847:141;;;;-1:-1:-1::0;;;112847:141:0::1;;;;;;;:::i;:::-;139072:29:::2;::::0;;;:14:::2;:29;::::0;;;;;::::2;;139064:45;;;;-1:-1:-1::0;;;139064:45:0::2;;;;;;;:::i;:::-;139142:27;::::0;;;:12:::2;:27;::::0;;;;:34;139128:48;::::2;139120:64;;;;-1:-1:-1::0;;;139120:64:0::2;;;;;;;:::i;:::-;139197:14;139214:27:::0;;;:12:::2;:27;::::0;;;;:40;;139242:11;;139214:40;::::2;;;;;:::i;:::-;;;;;;;;;139197:57;;139273:6;139283:1;139273:11;;139265:27;;;;-1:-1:-1::0;;;139265:27:0::2;;;;;;;:::i;:::-;139305:18;139353:10;139365:6;139336:36;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;139336:36:0;;::::2;::::0;;;;;;139326:47;;139336:36:::2;139326:47:::0;;::::2;::::0;139384:26:::2;139413:32:::0;;;:17:::2;:32:::0;;;;;:68;;;;;;;;;139326:47;;-1:-1:-1;139500:22:0;139492:38:::2;;;::::0;-1:-1:-1;;;139492:38:0;;13346:2:1;139492:38:0::2;::::0;::::2;13328:21:1::0;13385:1;13365:18;;;13358:29;-1:-1:-1;;;13403:18:1;;;13396:33;13446:18;;139492:38:0::2;13144:326:1::0;139492:38:0::2;139583:21;139719:39:::0;;;:24:::2;:39;::::0;;;;;;;:47;;;;;;;;;139608:41;;;:26:::2;:41:::0;;;;;:73;;;;;;;;;:94:::2;::::0;139684:18;;139608:94:::2;:::i;:::-;139607:159;;;;:::i;:::-;139826:1;139779:32:::0;;;:17:::2;:32;::::0;;;;;;;:44;;;;;;;;:48;;;139912:12:::2;::::0;139892:33;;:19:::2;:33:::0;;;;;;140107;;;:18:::2;:33:::0;;;;;;140043:24:::2;:39:::0;;;;;:47;;;;;;;;;;139583:183;;-1:-1:-1;139892:33:0;140016:74:::2;::::0;139892:33;140016:74:::2;:::i;:::-;140015:125;;;;:::i;:::-;140184:25;140286:39:::0;;;:24:::2;:39;::::0;;;;;;;:47;;;;;;;;;139982:158;;-1:-1:-1;140184:25:0;140213:56:::2;140251:18:::0;139982:158;140213:56:::2;:::i;:::-;140212:121;;;;:::i;:::-;140184:149;;140379:65;140418:10;140430:13;140386:17;-1:-1:-1::0;;;140386:10:0::2;:17::i;:::-;-1:-1:-1::0;;;;;140379:38:0::2;::::0;:65;:38:::2;:65::i;:::-;140496:70;140536:10;140548:17;140503:18;-1:-1:-1::0;;;140503:10:0::2;:18::i;140496:70::-;140584:157;::::0;;13734:25:1;;;13790:2;13775:18;;13768:34;;;140659:10:0::2;13818:18:1::0;;;13811:60;13902:2;13887:18;;13880:34;;;13945:3;13930:19;;13923:35;;;140584:157:0;;::::2;::::0;;;;13721:3:1;140584:157:0;;::::2;140754:41;::::0;;;;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;-1:-1:-1;140754:41:0;;138882:1921;-1:-1:-1;;;;;;;138882:1921:0:o;123750:479::-;123884:4;109458:6;;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;123909:35;;::::1;123901:50;;;::::0;-1:-1:-1;;;123901:50:0;;14171:2:1;123901:50:0::1;::::0;::::1;14153:21:1::0;14210:1;14190:18;;;14183:29;-1:-1:-1;;;14228:18:1;;;14221:32;14270:18;;123901:50:0::1;13969:325:1::0;123901:50:0::1;123967:9;123962:238;123982:16:::0;;::::1;123962:238;;;124020:12;124035:5;;124041:1;124035:8;;;;;;;:::i;:::-;;;;;;;124020:23;;124058:19;124080:12;;124093:1;124080:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;124110;::::0;;;:9:::1;:15;::::0;;;;;:29;;-1:-1:-1;;;;;;124110:29:0::1;-1:-1:-1::0;;;;;124110:29:0;::::1;::::0;;::::1;::::0;;;124159;;124110;;-1:-1:-1;124110:29:0;:15;;124159:29:::1;::::0;::::1;124005:195;;124000:3;;;;;:::i;:::-;;;;123962:238;;;-1:-1:-1::0;124217:4:0::1;::::0;123750:479;-1:-1:-1;;;;;123750:479:0:o;136710:1270::-;136870:11;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;112821:10:::1;113329:17:::0;113374:8;112806:182:::1;;112894:10;112873:32;::::0;;;:20:::1;:32;::::0;;;;;::::1;;112847:141;;;;-1:-1:-1::0;;;112847:141:0::1;;;;;;;:::i;:::-;136902:21:::2;::::0;;;:14:::2;:21;::::0;;;;;::::2;;136894:37;;;;-1:-1:-1::0;;;136894:37:0::2;;;;;;;:::i;:::-;136964:19;::::0;;;:12:::2;:19;::::0;;;;:26;136950:40;::::2;136942:56;;;;-1:-1:-1::0;;;136942:56:0::2;;;;;;;:::i;:::-;137026:1;137017:6;:10;137009:26;;;;-1:-1:-1::0;;;137009:26:0::2;;;;;;;:::i;:::-;137048:14;137065:19:::0;;;:12:::2;:19;::::0;;;;:32;;137085:11;;137065:32;::::2;;;;;:::i;:::-;;;;;;;;;137048:49;;137116:6;137126:1;137116:11;;137108:27;;;;-1:-1:-1::0;;;137108:27:0::2;;;;;;;:::i;:::-;137177:24;::::0;;;:17:::2;:24;::::0;;;;;;;:32;;;;;;;;;;;137170:62;;-1:-1:-1;;;137170:62:0;;137221:10:::2;137170:62;::::0;::::2;2163:51:1::0;137253:6:0;;-1:-1:-1;;;;;137177:32:0::2;::::0;137170:50:::2;::::0;2136:18:1;;137170:62:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;137148:142;;;::::0;-1:-1:-1;;;137148:142:0;;14972:2:1;137148:142:0::2;::::0;::::2;14954:21:1::0;15011:1;14991:18;;;14984:29;-1:-1:-1;;;15029:18:1;;;15022:33;15072:18;;137148:142:0::2;14770:326:1::0;137148:142:0::2;137357:23;::::0;;;:16:::2;:23;::::0;;;;;137344:53:::2;::::0;137382:6;137390;137344:12:::2;:53::i;:::-;137440:16;137497:23:::0;;;:16:::2;:23;::::0;;;;;137338:59;;-1:-1:-1;137440:16:0;137459:111:::2;::::0;137338:59;137553:6;137459:23:::2;:111::i;:::-;137440:130;;137597:1;137591:3;:7;137583:23;;;::::0;-1:-1:-1;;;137583:23:0;;15303:2:1;137583:23:0::2;::::0;::::2;15285:21:1::0;15342:1;15322:18;;;15315:29;-1:-1:-1;;;15360:18:1;;;15353:33;15403:18;;137583:23:0::2;15101:326:1::0;137583:23:0::2;137690:24;::::0;;;:17:::2;:24;::::0;;;;;;;:32;;;;;;;;;;;137655:111;;-1:-1:-1;;;137655:111:0;;137747:10:::2;137655:111;::::0;::::2;15606:51:1::0;15673:18;;;15666:34;;;-1:-1:-1;;;;;137690:32:0;;::::2;::::0;137655:91:::2;::::0;15579:18:1;;137655:111:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;137779:10;137799:17;-1:-1:-1::0;;;137799:10:0::2;:17::i;:::-;137779:38:::0;-1:-1:-1;137861:44:0::2;137878:10;137890:14;137896:8:::0;137890:3;:14:::2;:::i;:::-;-1:-1:-1::0;;;;;137861:16:0;::::2;::::0;:44;:16:::2;:44::i;:::-;137923:49;::::0;;13734:25:1;;;13790:2;13775:18;;13768:34;;;137948:10:0::2;13818:18:1::0;;;13811:60;13902:2;13887:18;;13880:34;;;13945:3;13930:19;;13923:35;;;137923:49:0;;::::2;::::0;;;;13721:3:1;137923:49:0;;::::2;136883:1097;;;136710:1270:::0;;;;;:::o;151244:603::-;151389:16;151364:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;151423:14:::1;151440:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;151514:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;151514:21:0::1;;151477:58;;151553:9;151548:255;151572:6;151568:1;:10;151548:255;;;151600:14;151617:19:::0;;;:12:::1;:19;::::0;;;;:22;;151637:1;;151617:22;::::1;;;;;:::i;:::-;;;;;;;;;151600:39;;151654:18;151702:4;151708:6;151685:30;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;151685:30:0;;::::1;::::0;;;;;;151675:41;;151685:30:::1;151675:41:::0;;::::1;::::0;151756:23:::1;::::0;;;:16:::1;:23:::0;;;;;:35;;;;;;;;;151733:20;;151675:41;;-1:-1:-1;151756:35:0;151733:17;;151751:1;;151733:20;::::1;;;;;:::i;:::-;;;;;;:58;;;::::0;::::1;151585:218;;151580:3;;;;;:::i;:::-;;;;151548:255;;;-1:-1:-1::0;151822:17:0;151244:603;-1:-1:-1;;;;;151244:603:0:o;148335:608::-;148481:16;148456:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;148515:14:::1;148532:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;148607:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;148607:21:0::1;;148569:59;;148646:9;148641:257;148665:6;148661:1;:10;148641:257;;;148693:14;148710:19:::0;;;:12:::1;:19;::::0;;;;:22;;148730:1;;148710:22;::::1;;;;;:::i;:::-;;;;;;;;;148693:39;;148747:18;148795:4;148801:6;148778:30;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;148778:30:0;;::::1;::::0;;;;;;148768:41;;148778:30:::1;148768:41:::0;;::::1;::::0;148850:24:::1;::::0;;;:17:::1;:24:::0;;;;;:36;;;;;;;;;148826:21;;148768:41;;-1:-1:-1;148850:36:0;148826:18;;148845:1;;148826:21;::::1;;;;;:::i;:::-;;;;;;:60;;;::::0;::::1;148678:220;;148673:3;;;;;:::i;:::-;;;;148641:257;;149074:540:::0;149213:16;149188:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;149247:14:::1;149264:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;149346:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;149346:21:0::1;;149301:66;;149385:9;149380:182;149404:6;149400:1;:10;149380:182;;;149463:31;::::0;;;:24:::1;:31;::::0;;;;;;;149513:12:::1;:19:::0;;;;;:22;;149463:31;;;149533:1;;149513:22;::::1;;;;;:::i;:::-;;;;;;;;;149463:87;;;;;;;;;;;;149432:25;149458:1;149432:28;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:118;149412:3;::::1;::::0;::::1;:::i;:::-;;;;149380:182;;;-1:-1:-1::0;149581:25:0;149074:540;-1:-1:-1;;;;149074:540:0:o;125252:561::-;125360:4;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;112821:10:::1;113329:17:::0;113374:8;112806:182:::1;;112894:10;112873:32;::::0;;;:20:::1;:32;::::0;;;;;::::1;;112847:141;;;;-1:-1:-1::0;;;112847:141:0::1;;;;;;;:::i;:::-;125406:12:::2;::::0;125391:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;125390:29;125382:44;;;;-1:-1:-1::0;;;125382:44:0::2;;;;;;;:::i;:::-;125442:19;125465:27;125479:12;;125465:13;:27::i;:::-;125439:53;;;125531:11;125512:15;:30;;125503:47;;;::::0;-1:-1:-1;;;125503:47:0;;16373:2:1;125503:47:0::2;::::0;::::2;16355:21:1::0;16412:1;16392:18;;;16385:29;-1:-1:-1;;;16430:18:1;;;16423:32;16472:18;;125503:47:0::2;16171:325:1::0;125503:47:0::2;125602:20;::::0;125588:34:::2;::::0;:11;:34:::2;:::i;:::-;125569:15;:53;;125561:69;;;::::0;-1:-1:-1;;;125561:69:0;;16836:2:1;125561:69:0::2;::::0;::::2;16818:21:1::0;16875:1;16855:18;;;16848:29;-1:-1:-1;;;16893:18:1;;;16886:33;16936:18;;125561:69:0::2;16634:326:1::0;125561:69:0::2;125676:13;:11;:13::i;:::-;125660:12;::::0;125643:30:::2;::::0;;;:16:::2;:30;::::0;;;;:46;125702:31:::2;125728:4;125702:25;:31::i;:::-;-1:-1:-1::0;;125761:12:0::2;::::0;125746:28:::2;::::0;;;:14:::2;:28;::::0;;;;:35;;-1:-1:-1;;125746:35:0::2;125777:4;125746:35:::0;;::::2;::::0;;;125252:561;:::o;146271:298::-;146394:13;146409:11;146369:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;146460:22:::1;::::0;;;:15:::1;:22;::::0;;;;;146497:53:::1;146460:22:::0;146497:29:::1;:53::i;:::-;146438:123;;;;146271:298:::0;;;;:::o;110036:103::-;109431:7;109458:6;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;110101:30:::1;110128:1;110101:18;:30::i;:::-;110036:103::o:0;117581:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;133313:383::-;133476:4;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;133525:7:::1;:14;133501:13;:20;:38;133493:53;;;::::0;-1:-1:-1;;;133493:53:0;;14171:2:1;133493:53:0::1;::::0;::::1;14153:21:1::0;14210:1;14190:18;;;14183:29;-1:-1:-1;;;14228:18:1;;;14221:32;14270:18;;133493:53:0::1;13969:325:1::0;133493:53:0::1;133564:9;133559:107;133583:13;:20;133579:1;:24;133559:107;;;133623:43;133631:13;133645:1;133631:16;;;;;;;;:::i;:::-;;;;;;;133649:7;133657:1;133649:10;;;;;;;;:::i;:::-;;;;;;;133661:4;133623:7;:43::i;:::-;-1:-1:-1::0;133605:3:0;::::1;::::0;::::1;:::i;:::-;;;;133559:107;;;;133684:4;133677:11;;107560:1;133313:383:::0;;;;;:::o;146996:505::-;147128:16;147103:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;147162:14:::1;147179:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;147254:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;147254:21:0::1;;147216:59;;147293:9;147288:168;147312:6;147308:1;:10;147288:168;;;147364:24;::::0;;;:17:::1;:24;::::0;;;;;;;147407:12:::1;:19:::0;;;;;:22;;147364:24;;;147427:1;;147407:22;::::1;;;;;:::i;:::-;;;;;;;;;147364:80;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;147364:80:0::1;147340:18;147359:1;147340:21;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;147340:104:0;;::::1;:21;::::0;;::::1;::::0;;;;;;;:104;147320:3;::::1;::::0;::::1;:::i;:::-;;;;147288:168;;122652:148:::0;122702:4;152416:24;-1:-1:-1;;;152416:10:0;:24::i;:::-;-1:-1:-1;;;;;152402:38:0;:10;-1:-1:-1;;;;;152402:38:0;;152394:54;;;;-1:-1:-1;;;152394:54:0;;;;;;;:::i;:::-;122719:8:::1;:6;:8::i;:::-;122738:32;122764:5;122738:25;:32::i;144122:217::-:0;144246:7;144281:6;144273:5;:14;:58;;144330:1;144273:58;;;144321:5;144311:6;144293:14;144301:6;144321:5;144293:14;:::i;131373:1622::-;131522:4;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;112821:10:::1;113329:17:::0;113374:8;112806:182:::1;;112894:10;112873:32;::::0;;;:20:::1;:32;::::0;;;;;::::1;;112847:141;;;;-1:-1:-1::0;;;112847:141:0::1;;;;;;;:::i;:::-;131539:17:::2;131559:12;;131574:1;131559:16;;;;:::i;:::-;131592:12;::::0;131539:36;;-1:-1:-1;131592:16:0;131588:170:::2;;131666:12;::::0;131651:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;:56:::0;::::2;;;-1:-1:-1::0;131684:23:0::2;::::0;;;:12:::2;:23;::::0;;;;;::::2;;131683:24;131651:56;131625:121;;;::::0;-1:-1:-1;;;131625:121:0;;17167:2:1;131625:121:0::2;::::0;::::2;17149:21:1::0;17206:1;17186:18;;;17179:29;-1:-1:-1;;;17224:18:1;;;17217:33;17267:18;;131625:121:0::2;16965:326:1::0;131625:121:0::2;131832:23;::::0;;;:12:::2;:23;::::0;;;;:30;131818:44;::::2;131810:60;;;;-1:-1:-1::0;;;131810:60:0::2;;;;;;;:::i;:::-;131928:1;131919:6;:10;131911:26;;;;-1:-1:-1::0;;;131911:26:0::2;;;;;;;:::i;:::-;131985:14;132002:23:::0;;;:12:::2;:23;::::0;;;;:36;;132026:11;;132002:36;::::2;;;;;:::i;:::-;;;;;;;;;131985:53;;132057:6;132067:1;132057:11;;132049:27;;;;-1:-1:-1::0;;;132049:27:0::2;;;;;;;:::i;:::-;132089:18;132137:4;132143:6;132120:30;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;132120:30:0;;::::2;::::0;;;;;;132110:41;;132120:30:::2;132110:41:::0;;::::2;::::0;132203:28:::2;::::0;;;:17:::2;:28:::0;;;;;:40;;;;;;;;;:50;;132110:41;;-1:-1:-1;132247:6:0;;132203:40;;:50:::2;::::0;132247:6;;132203:50:::2;:::i;:::-;::::0;;;-1:-1:-1;;132311:35:0::2;::::0;;;:24:::2;:35;::::0;;;;;;;:43;;;;;;;;:53;;132358:6;;132311:35;:53:::2;::::0;132358:6;;132311:53:::2;:::i;:::-;::::0;;;-1:-1:-1;;132415:29:0::2;::::0;;;:18:::2;:29;::::0;;;;:39;;132448:6;;132415:29;:39:::2;::::0;132448:6;;132415:39:::2;:::i;:::-;::::0;;;-1:-1:-1;;132512:34:0::2;::::0;;;:23:::2;:34;::::0;;;;;;;:42;;;;;;;;:52;;132558:6;;132512:34;:52:::2;::::0;132558:6;;132512:52:::2;:::i;:::-;::::0;;;-1:-1:-1;;132615:28:0::2;::::0;;;:17:::2;:28;::::0;;;;:38;;132647:6;;132615:28;:38:::2;::::0;132647:6;;132615:38:::2;:::i;:::-;::::0;;;-1:-1:-1;132666:127:0::2;::::0;-1:-1:-1;132723:10:0::2;132756:4;132776:6:::0;132673:17:::2;-1:-1:-1::0;;;132673:10:0::2;:17::i;:::-;-1:-1:-1::0;;;;;132666:42:0::2;::::0;:127;;:42:::2;:127::i;:::-;132844:28;-1:-1:-1::0;;;132844:10:0::2;:28::i;:::-;-1:-1:-1::0;;;;;132828:54:0::2;;132883:6;132828:62;;;;;;;;;;;;;413:25:1::0;;401:2;386:18;;267:177;132828:62:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;132908:55:0::2;::::0;;17555:25:1;;;17611:2;17596:18;;17589:34;;;17639:18;;;17632:34;;;-1:-1:-1;;;;;17740:15:1;;17735:2;17720:18;;17713:43;132952:10:0::2;17787:3:1::0;17772:19;;17765:44;132908:55:0::2;::::0;-1:-1:-1;17542:3:1;17527:19;;-1:-1:-1;132908:55:0::2;;;;;;;-1:-1:-1::0;132983:4:0::2;::::0;131373:1622;-1:-1:-1;;;;;;131373:1622:0:o;141878:1755::-;141984:7;142009:15;142027:145;142087:19;:9;:17;:19::i;:::-;142121:20;:9;:18;:20::i;:::-;:24;;142144:1;142121:24;:::i;:::-;142160:1;142027:45;:145::i;:::-;142009:163;;142214:1;142189:22;:7;:20;:22::i;:::-;:26;142185:241;;;142242:172;142306:17;:7;:15;:17::i;:::-;142342:18;:7;:16;:18::i;:::-;142398:1;142379:16;:7;:14;:16::i;:::-;:20;;;;:::i;:::-;142242:45;:172::i;:::-;142232:182;;142185:241;142438:25;142466:275;142548:17;:7;:15;:17::i;:::-;142584:18;:7;:16;:18::i;:::-;142644:22;:7;:20;:22::i;:::-;142621:16;:7;:14;:16::i;:::-;:20;;142640:1;142621:20;:::i;:::-;:45;;;;:::i;:::-;142685:1;142705;142725;142466:63;:275::i;:::-;142438:303;;142779:9;142758:17;:30;142754:837;;142805:12;142820:161;142884:19;:9;:17;:19::i;:::-;142922:20;:9;:18;:20::i;:::-;:24;;142945:1;142922:24;:::i;142820:161::-;142805:176;;143024:1;143002:19;:4;:17;:19::i;:::-;:23;142998:250;;;143053:179;143121:14;:4;:12;:14::i;143053:179::-;143046:186;;142998:250;143284:295;143374:14;:4;:12;:14::i;:::-;143411:15;:4;:13;:15::i;:::-;143469:19;:4;:17;:19::i;:::-;143449:13;:4;:11;:13::i;143284:295::-;143264:315;143608:17;-1:-1:-1;;;;;141878:1755:0:o;123237:288::-;123364:4;152416:24;-1:-1:-1;;;152416:10:0;:24::i;:::-;-1:-1:-1;;;;;152402:38:0;:10;-1:-1:-1;;;;;152402:38:0;;152394:54;;;;-1:-1:-1;;;152394:54:0;;;;;;;:::i;:::-;123386:20:::1;:44:::0;;;123446:49:::1;::::0;413:25:1;;;123446:49:0::1;::::0;401:2:1;386:18;123446:49:0::1;;;;;;;-1:-1:-1::0;123513:4:0::1;152459:1;123237:288:::0;;;:::o;111533:526::-;111639:4;109458:6;;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;113329:17;;111661:124:::1;;;::::0;-1:-1:-1;;;111661:124:0;;18022:2:1;111661:124:0::1;::::0;::::1;18004:21:1::0;18061:2;18041:18;;;18034:30;18100:34;18080:18;;;18073:62;-1:-1:-1;;;18151:18:1;;;18144:51;18212:19;;111661:124:0::1;17820:417:1::0;111661:124:0::1;-1:-1:-1::0;;;;;111819:31:0;::::1;;::::0;;;:20:::1;:31;::::0;;;;;::::1;;111818:32;111796:129;;;::::0;-1:-1:-1;;;111796:129:0;;18444:2:1;111796:129:0::1;::::0;::::1;18426:21:1::0;18483:2;18463:18;;;18456:30;18522:34;18502:18;;;18495:62;-1:-1:-1;;;18573:18:1;;;18566:45;18628:19;;111796:129:0::1;18242:411:1::0;111796:129:0::1;-1:-1:-1::0;;;;;111938:31:0;::::1;;::::0;;;111972:4:::1;111938:31;::::0;;;;;;;:38;;-1:-1:-1;;111938:38:0::1;::::0;;::::1;::::0;;;111994:33;::::1;::::0;111938:31;111994:33:::1;-1:-1:-1::0;112047:4:0::1;111533:526:::0;;;:::o;147632:540::-;147771:16;147746:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;147805:14:::1;147822:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;147904:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;147904:21:0::1;;147859:66;;147943:9;147938:182;147962:6;147958:1;:10;147938:182;;;148021:31;::::0;;;:24:::1;:31;::::0;;;;;;;148071:12:::1;:19:::0;;;;;:22;;148021:31;;;148091:1;;148071:22;::::1;;;;;:::i;:::-;;;;;;;;;148021:87;;;;;;;;;;;;147990:25;148016:1;147990:28;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:118;147970:3;::::1;::::0;::::1;:::i;:::-;;;;147938:182;;112291:378:::0;-1:-1:-1;;;;;112427:31:0;;112383:4;112427:31;;;:20;:31;;;;;;;;112405:124;;;;-1:-1:-1;;;112405:124:0;;18860:2:1;112405:124:0;;;18842:21:1;18899:2;18879:18;;;18872:30;18938:34;18918:18;;;18911:62;-1:-1:-1;;;18989:18:1;;;18982:41;19040:19;;112405:124:0;18658:407:1;112405:124:0;-1:-1:-1;;;;;112542:31:0;;112576:5;112542:31;;;:20;:31;;;;;;:39;;-1:-1:-1;;112542:39:0;;;112599:38;;;112576:5;112599:38;-1:-1:-1;112657:4:0;;112291:378;-1:-1:-1;112291:378:0:o;150577:505::-;150709:16;150684:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;150743:14:::1;150760:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;150835:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;150835:21:0::1;;150797:59;;150874:9;150869:168;150893:6;150889:1;:10;150869:168;;;150945:24;::::0;;;:17:::1;:24;::::0;;;;;;;150988:12:::1;:19:::0;;;;;:22;;150945:24;;;151008:1;;150988:22;::::1;;;;;:::i;:::-;;;;;;;;;150945:80;;;;;;;;;;;;150921:18;150940:1;150921:21;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:104;150901:3;::::1;::::0;::::1;:::i;:::-;;;;150869:168;;130318:739:::0;130442:4;109458:6;;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;107265:7;;;;107519:9:::1;107511:38;;;;-1:-1:-1::0;;;107511:38:0::1;;;;;;;:::i;:::-;130464:17:::2;130484:12;;130499:1;130484:16;;;;:::i;:::-;130521:29;::::0;;;:18:::2;:29;::::0;;;;;130464:36;;-1:-1:-1;130521:34:0;130513:49:::2;;;::::0;-1:-1:-1;;;130513:49:0;;19272:2:1;130513:49:0::2;::::0;::::2;19254:21:1::0;19311:1;19291:18;;;19284:29;-1:-1:-1;;;19329:18:1;;;19322:32;19371:18;;130513:49:0::2;19070:325:1::0;130513:49:0::2;130579:12;::::0;:16;130575:163:::2;;130615:19;130638:27;130652:12;;130638:13;:27::i;:::-;130612:53;;;130707:11;130689:15;:29;130680:46;;;::::0;-1:-1:-1;;;130680:46:0;;19602:2:1;130680:46:0::2;::::0;::::2;19584:21:1::0;19641:1;19621:18;;;19614:29;-1:-1:-1;;;19659:18:1;;;19652:32;19701:18;;130680:46:0::2;19400:325:1::0;130680:46:0::2;130597:141;130575:163;130789:23;::::0;;;:12:::2;:23;::::0;;;;;;;:33;;::::2;::::0;;::::2;::::0;::::2;:::i;:::-;-1:-1:-1::0;130875:26:0::2;::::0;;;:15:::2;:26;::::0;;;;130904:15:::2;130875:44:::0;;130932:95:::2;130956:7;:14;130952:1;:18;130932:95;;;130995:32;131005:9;131016:7;131024:1;131016:10;;;;;;;;:::i;:::-;;;;;;;130995:32;;;;;;4881:25:1::0;;;4937:2;4922:18;;4915:34;4869:2;4854:18;;4707:248;130995:32:0::2;;;;;;;;130972:3:::0;::::2;::::0;::::2;:::i;:::-;;;;130932:95;;;-1:-1:-1::0;131045:4:0::2;::::0;130318:739;-1:-1:-1;;;130318:739:0:o;124423:722::-;124532:4;152416:24;-1:-1:-1;;;152416:10:0;:24::i;:::-;-1:-1:-1;;;;;152402:38:0;:10;-1:-1:-1;;;;;152402:38:0;;152394:54;;;;-1:-1:-1;;;152394:54:0;;;;;;;:::i;:::-;107265:7;;;;107789:41:::1;;;::::0;-1:-1:-1;;;107789:41:0;;19932:2:1;107789:41:0::1;::::0;::::1;19914:21:1::0;19971:2;19951:18;;;19944:30;-1:-1:-1;;;19990:18:1;;;19983:50;20050:18;;107789:41:0::1;19730:344:1::0;107789:41:0::1;124554:10:::2;124574:17;-1:-1:-1::0;;;124574:10:0::2;:17::i;:::-;124554:38;;124659:11;124680:18;-1:-1:-1::0;;;124680:10:0::2;:18::i;:::-;124733:28;::::0;-1:-1:-1;;;124733:28:0;;124755:4:::2;124733:28;::::0;::::2;2163:51:1::0;124659:40:0;;-1:-1:-1;124712:18:0::2;::::0;-1:-1:-1;;;;;124733:13:0;::::2;::::0;::::2;::::0;2136:18:1;;124733:28:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;124861:29;::::0;-1:-1:-1;;;124861:29:0;;124884:4:::2;124861:29;::::0;::::2;2163:51:1::0;124712:49:0;;-1:-1:-1;124839:19:0::2;::::0;-1:-1:-1;;;;;124861:14:0;::::2;::::0;::::2;::::0;2136:18:1;;124861:29:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;124839:51:::0;-1:-1:-1;124903:40:0::2;-1:-1:-1::0;;;;;124903:16:0;::::2;124920:10;124932::::0;124903:16:::2;:40::i;:::-;125012:42;-1:-1:-1::0;;;;;125012:17:0;::::2;125030:10;125042:11:::0;125012:17:::2;:42::i;:::-;125072:41;::::0;;125090:10:::2;15606:51:1::0;;15688:2;15673:18;;15666:34;;;125072:41:0::2;::::0;15579:18:1;125072:41:0::2;;;;;;;125133:4;125126:11;;;;;;124423:722:::0;:::o;145278:331::-;145411:7;145464:25;-1:-1:-1;;;145464:10:0;:25::i;:::-;145451:150;;-1:-1:-1;;;145451:150:0;;;;;20281:25:1;;;20322:18;;;20315:34;;;20365:18;;;20358:34;;;-1:-1:-1;;;;;145451:61:0;;;;;;;20254:18:1;;145451:150:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;133981:2423::-;134133:7;134142;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;112821:10:::1;113329:17:::0;113374:8;112806:182:::1;;112894:10;112873:32;::::0;;;:20:::1;:32;::::0;;;;;::::1;;112847:141;;;;-1:-1:-1::0;;;112847:141:0::1;;;;;;;:::i;:::-;134165:19:::2;134188:27;134202:12;;134188:13;:27::i;:::-;134162:53;;;134253:11;134235:15;:29;134226:47;;;::::0;-1:-1:-1;;;134226:47:0;;20605:2:1;134226:47:0::2;::::0;::::2;20587:21:1::0;20644:1;20624:18;;;20617:29;-1:-1:-1;;;20662:18:1;;;20655:33;20705:18;;134226:47:0::2;20403:326:1::0;134226:47:0::2;134305:12;::::0;134292:26:::2;::::0;;;:12:::2;:26;::::0;;;;;::::2;;134284:42;;;::::0;-1:-1:-1;;;134284:42:0;;20936:2:1;134284:42:0::2;::::0;::::2;20918:21:1::0;20975:1;20955:18;;;20948:29;-1:-1:-1;;;20993:18:1;;;20986:33;21036:18;;134284:42:0::2;20734:326:1::0;134284:42:0::2;134372:12;::::0;134359:26:::2;::::0;;;:12:::2;:26;::::0;;;;:33;134345:47;::::2;134337:63;;;;-1:-1:-1::0;;;134337:63:0::2;;;;;;;:::i;:::-;134428:1;134419:6;:10;134411:26;;;;-1:-1:-1::0;;;134411:26:0::2;;;;;;;:::i;:::-;134480:12;::::0;134450:14:::2;134467:26:::0;;;:12:::2;:26;::::0;;;;:39;;134494:11;;134467:39;::::2;;;;;:::i;:::-;;;;;;;;;134450:56;;134525:6;134535:1;134525:11;;134517:27;;;;-1:-1:-1::0;;;134517:27:0::2;;;;;;;:::i;:::-;134555:18;134603:4;134609:6;134586:30;;;;;;;;;:::i;:::-;;;;;;;;;;;;;134576:41;;;;;;134555:62;;134630:15;134655:17;-1:-1:-1::0;;;134655:10:0::2;:17::i;:::-;134630:43;;134684:20;134707:13;:11;:13::i;:::-;134684:36;;134791:15;134809:32;134826:6;134834;134809:16;:32::i;:::-;134791:50;;134884:16;134903:51;134925:12;134939:6;134947;134903:21;:51::i;:::-;135039:12;::::0;135014:38:::2;::::0;;;:24:::2;:38;::::0;;;;;;;:46;;;;;;;;:56;;134884:70;;-1:-1:-1;135064:6:0;;135014:46;;:38;:56:::2;::::0;135064:6;;135014:56:::2;:::i;:::-;::::0;;;-1:-1:-1;;135151:12:0::2;::::0;135127:37:::2;::::0;;;:23:::2;:37;::::0;;;;;;;:49;;;;;;;;:59;;135180:6;;135127:37;:59:::2;::::0;135180:6;;135127:59:::2;:::i;:::-;::::0;;;-1:-1:-1;;135254:12:0::2;::::0;135236:31:::2;::::0;;;:17:::2;:31;::::0;;;;;;;:39;;;;;;;;:50;;135279:7;;135236:31;:50:::2;::::0;135279:7;;135236:50:::2;:::i;:::-;::::0;;;-1:-1:-1;;135352:12:0::2;::::0;135335:30:::2;::::0;;;:16:::2;:30;::::0;;;;;;;:42;;;;;;;;:53;;135381:7;;135335:30;:53:::2;::::0;135381:7;;135335:53:::2;:::i;:::-;::::0;;;-1:-1:-1;;135425:12:0::2;::::0;135401:37:::2;::::0;;;:23:::2;:37;::::0;;;;;;;:45;;;;;;;;:56;;135450:7;;135401:37;:56:::2;::::0;135450:7;;135401:56:::2;:::i;:::-;::::0;;;-1:-1:-1;;135488:12:0::2;::::0;135470:31:::2;::::0;;;:17:::2;:31;::::0;;;;:42;;135505:7;;135470:31;:42:::2;::::0;135505:7;;135470:42:::2;:::i;:::-;::::0;;;-1:-1:-1;135597:122:0::2;::::0;-1:-1:-1;135637:10:0::2;135670:4;135690:18;135700:8:::0;135690:7;:18:::2;:::i;:::-;-1:-1:-1::0;;;;;135597:25:0;::::2;::::0;:122;;:25:::2;:122::i;:::-;135736:12:::0;;135732:153:::2;;135812:61;135834:28;-1:-1:-1::0;;;135834:10:0::2;:28::i;:::-;-1:-1:-1::0;;;;;135812:21:0;::::2;::::0;135864:8;135812:21:::2;:61::i;:::-;135960:12;::::0;135942:31:::2;::::0;;;:17:::2;:31;::::0;;;;;;;:39;;;;;;;;;135935:111:::2;::::0;-1:-1:-1;;;;;135942:39:0::2;136010:4:::0;136029:6;135935:60:::2;:111::i;:::-;136112:28;-1:-1:-1::0;;;136112:10:0::2;:28::i;:::-;-1:-1:-1::0;;;;;136096:54:0::2;;136151:7;136096:63;;;;;;;;;;;;;413:25:1::0;;401:2;386:18;;267:177;136096:63:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;136203:12:0::2;::::0;136177:180:::2;::::0;;21380:25:1;;;21436:2;21421:18;;21414:34;;;21464:18;;21457:34;;;21522:2;21507:18;;21500:34;;;21565:3;21550:19;;21543:35;;;-1:-1:-1;;;;;21653:15:1;;21605:3;21632:19;;21625:44;136336:10:0::2;21700:3:1::0;21685:19;;21678:44;136177:180:0::2;::::0;-1:-1:-1;21367:3:1;21352:19;;-1:-1:-1;136177:180:0::2;;;;;;;136378:7:::0;;;;-1:-1:-1;133981:2423:0;-1:-1:-1;;;;;;;;;133981:2423:0:o;149784:670::-;149936:16;149911:5;152548:1;152540:5;:9;152532:25;;;;-1:-1:-1;;;152532:25:0;;;;;;;:::i;:::-;149970:14:::1;149987:19:::0;;;:12:::1;:19;::::0;;;;:26;;;-1:-1:-1;;;;;150068:21:0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;150068:21:0::1;;150024:65;;150107:9;150102:301;150126:6;150122:1;:10;150102:301;;;150154:14;150171:19:::0;;;:12:::1;:19;::::0;;;;:22;;150191:1;;150171:22;::::1;;;;;:::i;:::-;;;;;;;;;150154:39;;150208:18;150256:4;150262:6;150239:30;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;150239:30:0;;::::1;::::0;;;;;;150229:41;;150239:30:::1;150229:41:::0;;::::1;::::0;150317:30:::1;::::0;;;:23:::1;:30:::0;;;;;:74;;;;;;;;;150287:27;;150229:41;;-1:-1:-1;150317:74:0;150287:24;;150312:1;;150287:27;::::1;;;;;:::i;:::-;;;;;;:104;;;::::0;::::1;150139:264;;150134:3;;;;;:::i;:::-;;;;150102:301;;110294:238:::0;109431:7;109458:6;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;110397:22:0;::::1;110375:110;;;::::0;-1:-1:-1;;;110375:110:0;;21935:2:1;110375:110:0::1;::::0;::::1;21917:21:1::0;21974:2;21954:18;;;21947:30;22013:34;21993:18;;;21986:62;-1:-1:-1;;;22064:18:1;;;22057:36;22110:19;;110375:110:0::1;21733:402:1::0;110375:110:0::1;110496:28;110515:8;110496:18;:28::i;:::-;110294:238:::0;:::o;138194:451::-;138244:4;107520:8;107265:7;;;;;107194:86;107520:8;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;138285:12:::1;::::0;138270:28:::1;::::0;;;:14:::1;:28;::::0;;;;;::::1;;138269:29;138261:44;;;;-1:-1:-1::0;;;138261:44:0::1;;;;;;;:::i;:::-;138337:12;::::0;138324:26:::1;::::0;;;:12:::1;:26;::::0;;;;;::::1;;138316:42;;;::::0;-1:-1:-1;;;138316:42:0;;20936:2:1;138316:42:0::1;::::0;::::1;20918:21:1::0;20975:1;20955:18;;;20948:29;-1:-1:-1;;;20993:18:1;;;20986:33;21036:18;;138316:42:0::1;20734:326:1::0;138316:42:0::1;138371:28;138432;-1:-1:-1::0;;;138432:10:0::1;:28::i;:::-;138371:100;;138482:12;-1:-1:-1::0;;;;;138482:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;138633:4;138626:11;;;138194:451:::0;:::o;125920:524::-;126049:4;152416:24;-1:-1:-1;;;152416:10:0;:24::i;:::-;-1:-1:-1;;;;;152402:38:0;:10;-1:-1:-1;;;;;152402:38:0;;152394:54;;;;-1:-1:-1;;;152394:54:0;;;;;;;:::i;:::-;107265:7;;;;107519:9:::1;107511:38;;;;-1:-1:-1::0;;;107511:38:0::1;;;;;;;:::i;:::-;126095:12:::2;::::0;126080:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;126079:29;126071:44;;;;-1:-1:-1::0;;;126071:44:0::2;;;;;;;:::i;:::-;126129:19;126152:27;126166:12;;126152:13;:27::i;:::-;126126:53;;;126231:20;;126217:11;:34;;;;:::i;:::-;126199:15;:52;126190:69;;;::::0;-1:-1:-1;;;126190:69:0;;16373:2:1;126190:69:0::2;::::0;::::2;16355:21:1::0;16412:1;16392:18;;;16385:29;-1:-1:-1;;;16430:18:1;;;16423:32;16472:18;;126190:69:0::2;16171:325:1::0;126190:69:0::2;126289:12;::::0;126272:30:::2;::::0;;;:16:::2;:30;::::0;;;;:48;;;126333:31:::2;126359:4;126333:25;:31::i;:::-;-1:-1:-1::0;;126392:12:0::2;::::0;126377:28:::2;::::0;;;:14:::2;:28;::::0;;;;:35;;-1:-1:-1;;126377:35:0::2;126408:4;126377:35:::0;;::::2;::::0;;;125920:524;;;:::o;145805:349::-;145947:7;146000:25;-1:-1:-1;;;146000:10:0;:25::i;:::-;145987:159;;-1:-1:-1;;;145987:159:0;;;;;20281:25:1;;;20322:18;;;20315:34;;;20365:18;;;20358:34;;;-1:-1:-1;;;;;145987:63:0;;;;;;;20254:18:1;;145987:159:0;20079:319:1;128647:1507:0;128710:4;109458:6;;-1:-1:-1;;;;;109458:6:0;106013:10;109605:23;109597:68;;;;-1:-1:-1;;;109597:68:0;;;;;;;:::i;:::-;107265:7;;;;107519:9:::1;107511:38;;;;-1:-1:-1::0;;;107511:38:0::1;;;;;;;:::i;:::-;128727:17:::2;128747:12;;128762:1;128747:16;;;;:::i;:::-;128783:23;::::0;;;:12:::2;:23;::::0;;;;;128727:36;;-1:-1:-1;128783:23:0::2;;128782:24;128774:39;;;::::0;-1:-1:-1;;;128774:39:0;;22342:2:1;128774:39:0::2;::::0;::::2;22324:21:1::0;22381:1;22361:18;;;22354:29;-1:-1:-1;;;22399:18:1;;;22392:32;22441:18;;128774:39:0::2;22140:325:1::0;128774:39:0::2;128865:1;128832:23:::0;;;:12:::2;:23;::::0;;;;:30;128824:49:::2;;;::::0;-1:-1:-1;;;128824:49:0;;22672:2:1;128824:49:0::2;::::0;::::2;22654:21:1::0;22711:1;22691:18;;;22684:29;-1:-1:-1;;;22729:18:1;;;22722:32;22771:18;;128824:49:0::2;22470:325:1::0;128824:49:0::2;128890:12;::::0;:16;128886:139:::2;;128993:12;::::0;128978:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;128970:43;;;::::0;-1:-1:-1;;;128970:43:0;;23002:2:1;128970:43:0::2;::::0;::::2;22984:21:1::0;23041:1;23021:18;;;23014:29;-1:-1:-1;;;23059:18:1;;;23052:32;23101:18;;128970:43:0::2;22800:325:1::0;128970:43:0::2;129042:9;129037:889;129061:23;::::0;;;:12:::2;:23;::::0;;;;:30;129057:34;::::2;129037:889;;;129113:14;129130:23:::0;;;:12:::2;:23;::::0;;;;:26;;129154:1;;129130:26;::::2;;;;;:::i;:::-;;;;;;;;;129113:43;;129171:18;129192:42;;;;;;;;;;;;;;-1:-1:-1::0;;;129192:42:0::2;;::::0;129216:17:::2;:6;:15;:17::i;:::-;129192:11;:42::i;:::-;129171:63;;129256:28;129268:4;129256:28;;;;;;;;;;;;;-1:-1:-1::0;;;129256:28:0::2;;::::0;:11:::2;:28::i;:::-;129249:35;;129306:41;129318:4;129324:22;129325:9;129324:20;:22::i;129306:41::-;129299:48;;129442:41;129543:33;129556:19;129543:12;:33::i;:::-;129610:29;::::0;-1:-1:-1;;;129610:29:0;;129442:153;;-1:-1:-1;;;;;;129610:17:0;::::2;::::0;::::2;::::0;:29:::2;::::0;129628:4;;;;129610:29:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;129654:28:0::2;::::0;;;:17:::2;:28;::::0;;;;;;;:36;;;;;;;;:54;;-1:-1:-1;;;;;;129654:54:0::2;-1:-1:-1::0;;;;;129654:54:0;::::2;::::0;;::::2;::::0;;;129856:35;;;:24:::2;:35:::0;;;;;:43;;;;;;;;;;;129794:120;;-1:-1:-1;;;129794:120:0;;129832:4:::2;129794:120;::::0;::::2;15606:51:1::0;15673:18;;;15666:34;;;;129654:54:0;-1:-1:-1;129794:11:0::2;::::0;15579:18:1;;129794:120:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;129098:828;;;129093:3;;;;;:::i;:::-;;;;129037:889;;;-1:-1:-1::0;129980:23:0::2;::::0;;;:12:::2;:23;::::0;;;;;;:30;;-1:-1:-1;;129980:30:0::2;130006:4;129980:30;::::0;;130060:12:::2;:24:::0;;;130102:20;::::2;::::0;::::2;::::0;129993:9;413:25:1;;401:2;386:18;;267:177;130102:20:0::2;;;;;;;;130142:4;130135:11;;;128647:1507:::0;:::o;40573:707::-;40991:10;;;40990:62;;-1:-1:-1;41007:39:0;;-1:-1:-1;;;41007:39:0;;41031:4;41007:39;;;24256:34:1;-1:-1:-1;;;;;24326:15:1;;;24306:18;;;24299:43;41007:15:0;;;;;24191:18:1;;41007:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;40990:62;40968:166;;;;-1:-1:-1;;;40968:166:0;;24555:2:1;40968:166:0;;;24537:21:1;24594:2;24574:18;;;24567:30;24633:34;24613:18;;;24606:62;-1:-1:-1;;;24684:18:1;;;24677:52;24746:19;;40968:166:0;24353:418:1;40968:166:0;41199:62;;-1:-1:-1;;;;;15624:32:1;;41199:62:0;;;15606:51:1;15673:18;;;15666:34;;;41145:127:0;;41179:5;;-1:-1:-1;;;41222:22:0;15579:18:1;;41199:62:0;;;;-1:-1:-1;;41199:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;41199:62:0;-1:-1:-1;;;;;;41199:62:0;;;;;;;;;;41145:19;:127::i;:::-;40573:707;;;:::o;34255:229::-;34392:12;34424:52;34446:6;34454:4;34460:1;34463:12;34424:21;:52::i;108253:120::-;107265:7;;;;107789:41;;;;-1:-1:-1;;;107789:41:0;;19932:2:1;107789:41:0;;;19914:21:1;19971:2;19951:18;;;19944:30;-1:-1:-1;;;19990:18:1;;;19983:50;20050:18;;107789:41:0;19730:344:1;107789:41:0;108312:7:::1;:15:::0;;-1:-1:-1;;108312:15:0::1;::::0;;108343:22:::1;106013:10:::0;108352:12:::1;108343:22;::::0;-1:-1:-1;;;;;2181:32:1;;;2163:51;;2151:2;2136:18;108343:22:0::1;;;;;;;108253:120::o:0;39763:248::-;39934:58;;-1:-1:-1;;;;;15624:32:1;;39934:58:0;;;15606:51:1;15673:18;;;15666:34;;;39880:123:0;;39914:5;;-1:-1:-1;;;39957:23:0;15579:18:1;;39934:58:0;15432:274:1;126594:1873:0;126693:12;;126709:1;126675:31;;;:17;:31;;;;;;:35;126671:961;;126767:12;;126727:24;126754:26;;;:12;:26;;;;;;;;126727:53;;;;;;;;;;;;;;;;;;;126754:26;;126727:53;;;126754:26;126727:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126802:9;126797:824;126821:7;:14;126817:1;:18;126797:824;;;126914:18;126935:190;126970:16;:30;126987:12;;126970:30;;;;;;;;;;;;127023:7;127031:1;127023:10;;;;;;;;:::i;:::-;;;;;;;127056:24;:38;127081:12;;127056:38;;;;;;;;;;;:50;127095:7;127103:1;127095:10;;;;;;;;:::i;:::-;;;;;;;127056:50;;;;;;;;;;;;126935:12;:190::i;:::-;126914:211;;127364:10;127290:24;:38;127315:12;;127290:38;;;;;;;;;;;:50;127329:7;127337:1;127329:10;;;;;;;;:::i;:::-;;;;;;;127290:50;;;;;;;;;;;;:84;;;;:::i;:::-;127213:26;:40;127240:12;;127213:40;;;;;;;;;;;:52;127254:7;127262:1;127254:10;;;;;;;;:::i;:::-;;;;;;;127213:52;;;;;;;;;;;;:161;;;;;;;:::i;:::-;;;;-1:-1:-1;;127395:211:0;;;;127543:17;:31;127561:12;;127543:31;;;;;;;;;;;:43;127575:7;127583:1;127575:10;;;;;;;;:::i;:::-;;;;;;;127543:43;;;;;;;;;;;;127439:26;:40;127466:12;;127439:40;;;;;;;;;;;:100;127506:7;127514:1;127506:10;;;;;;;;:::i;:::-;;;;;;;127439:100;;;;;;;;;;;;:147;;;;;;;:::i;:::-;;;;-1:-1:-1;;127395:211:0;-1:-1:-1;126837:3:0;;;;:::i;:::-;;;;126797:824;;;;126712:920;126671:961;127644:11;127665:18;-1:-1:-1;;;127665:10:0;:18::i;:::-;127644:40;;127695:12;127717:19;-1:-1:-1;;;127717:10:0;:19::i;:::-;127774:29;;-1:-1:-1;;;127774:29:0;;127797:4;127774:29;;;2163:51:1;127695:42:0;;-1:-1:-1;127750:21:0;;-1:-1:-1;;;;;127774:14:0;;;;;2136:18:1;;127774:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;127846:30;;-1:-1:-1;;;127846:30:0;;127870:4;127846:30;;;2163:51:1;127750:53:0;;-1:-1:-1;127816:27:0;;-1:-1:-1;;;;;127846:15:0;;;;;2136:18:1;;127846:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;127816:60;;127905:28;-1:-1:-1;;;127905:10:0;:28::i;:::-;127978:12;;127960:31;;;;:17;:31;;;;;;;;127889:113;;-1:-1:-1;;;127889:113:0;;-1:-1:-1;;;;;127889:56:0;;;;;;;:113;;;;413:25:1;;;401:2;386:18;;267:177;127889:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128029:28;-1:-1:-1;;;128029:10:0;:28::i;:::-;-1:-1:-1;;;;;128013:51:0;;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;128095:29:0;;-1:-1:-1;;;128095:29:0;;128118:4;128095:29;;;2163:51:1;128127:13:0;;-1:-1:-1;;;;;;128095:14:0;;;-1:-1:-1;128095:14:0;;2136:18:1;;128095:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45;;;;:::i;:::-;128186:30;;-1:-1:-1;;;128186:30:0;;128210:4;128186:30;;;2163:51:1;128079:61:0;;-1:-1:-1;128232:19:0;;-1:-1:-1;;;;;128186:15:0;;;;;2136:18:1;;128186:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:65;;;;:::i;:::-;128151:100;;128284:1;128268:13;:17;:44;;;;;128311:1;128289:19;:23;128268:44;128264:196;;;128349:12;;;128329:33;;;;:19;:33;;;;;;;;:49;;;128413:12;;128395:31;;:17;:31;;;:53;;;128264:196;126660:1807;;;;126594:1873;:::o;110692:191::-;110766:16;110785:6;;-1:-1:-1;;;;;110802:17:0;;;-1:-1:-1;;;;;;110802:17:0;;;;;;110835:40;;110785:6;;;;;;;110835:40;;110766:16;110835:40;110755:128;110692:191;:::o;107994:118::-;107265:7;;;;107519:9;107511:38;;;;-1:-1:-1;;;107511:38:0;;;;;;;:::i;:::-;108054:7:::1;:14:::0;;-1:-1:-1;;108054:14:0::1;108064:4;108054:14;::::0;;108084:20:::1;108091:12;106013:10:::0;;105933:98;40019:285;40217:68;;-1:-1:-1;;;;;25034:15:1;;;40217:68:0;;;25016:34:1;25086:15;;25066:18;;;25059:43;25118:18;;;25111:34;;;40163:133:0;;40197:5;;-1:-1:-1;;;40240:27:0;24951:18:1;;40217:68:0;24776:375:1;40163:133:0;40019:285;;;;:::o;14731:145::-;14790:12;14828:40;14840:27;7050:12;14840:9;:27;:::i;:::-;14828:11;:40::i;:::-;-1:-1:-1;14815:53:0;;14731:145;-1:-1:-1;;;14731:145:0:o;14884:148::-;14944:13;14984:40;14996:27;7050:12;14996:9;:27;:::i;14984:40::-;-1:-1:-1;14970:54:0;14884:148;-1:-1:-1;;;14884:148:0:o;10319:225::-;10445:17;7050:12;10487:31;10501:4;10507:5;10514:3;10487:13;:31::i;:::-;:49;;;;:::i;14223:221::-;14314:17;;14365:27;7050:12;14365:9;:27;:::i;:::-;14349:43;-1:-1:-1;14430:1:0;14417:9;14349:43;14425:1;14417:9;:::i;:::-;14416:15;;;;:::i;:::-;14415:21;;14435:1;14415:21;:::i;15040:142::-;15098:11;15134:40;15146:27;7050:12;15146:9;:27;:::i;10552:458::-;10755:17;10996:6;10940:40;7157:2;10940:6;:40;:::i;:::-;10888:36;7105:7;10888:4;:36;:::i;:::-;7050:12;10810:31;10824:4;10830:5;10837:3;10810:13;:31::i;:::-;:62;;;;:::i;:::-;:114;;;;:::i;:::-;:170;;;;:::i;:::-;:192;;;;:::i;:::-;10785:217;10552:458;-1:-1:-1;;;;;;;10552:458:0:o;293:723::-;349:13;570:10;566:53;;-1:-1:-1;;597:10:0;;;;;;;;;;;;-1:-1:-1;;;597:10:0;;;;;293:723::o;566:53::-;644:5;629:12;685:78;692:9;;685:78;;718:8;;;;:::i;:::-;;-1:-1:-1;741:10:0;;-1:-1:-1;749:2:0;741:10;;:::i;:::-;;;685:78;;;773:19;805:6;-1:-1:-1;;;;;795:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;795:17:0;;773:39;;823:154;830:10;;823:154;;857:11;867:1;857:11;;:::i;:::-;;-1:-1:-1;926:10:0;934:2;926:5;:10;:::i;:::-;913:24;;:2;:24;:::i;:::-;900:39;;883:6;890;883:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;883:56:0;;;;;;;;-1:-1:-1;954:11:0;963:2;954:11;;:::i;:::-;;;823:154;;143768:181;143873:13;143935:1;143938;143918:22;;;;;;;;;:::i;:::-;;;;;;;;;;;;;143904:37;;143768:181;;;;:::o;3010:622::-;3067:16;3137:4;3131:11;-1:-1:-1;;;3181:3:0;3156:128;3331:14;3325:4;3321:25;3314:4;3309:3;3305:14;3298:49;-1:-1:-1;;;3395:4:0;3390:3;3386:14;3361:139;3541:4;3536:3;3533:1;3526:20;3514:32;-1:-1:-1;;;;;;;3575:22:0;;3567:57;;;;-1:-1:-1;;;3567:57:0;;25950:2:1;3567:57:0;;;25932:21:1;25989:2;25969:18;;;25962:30;-1:-1:-1;;;26008:18:1;;;26001:52;26070:18;;3567:57:0;25748:346:1;42639:860:0;43063:23;43089:106;43131:4;43089:106;;;;;;;;;;;;;;;;;43097:5;-1:-1:-1;;;;;43089:27:0;;;:106;;;;;:::i;:::-;43210:17;;43063:132;;-1:-1:-1;43210:21:0;43206:286;;43383:10;43372:30;;;;;;;;;;;;:::i;:::-;43346:134;;;;-1:-1:-1;;;43346:134:0;;26583:2:1;43346:134:0;;;26565:21:1;26622:2;26602:18;;;26595:30;26661:34;26641:18;;;26634:62;-1:-1:-1;;;26712:18:1;;;26705:40;26762:19;;43346:134:0;26381:406:1;35471:571:0;35641:12;35713:5;35688:21;:30;;35666:118;;;;-1:-1:-1;;;35666:118:0;;26994:2:1;35666:118:0;;;26976:21:1;27033:2;27013:18;;;27006:30;27072:34;27052:18;;;27045:62;-1:-1:-1;;;27123:18:1;;;27116:36;27169:19;;35666:118:0;26792:402:1;35666:118:0;113329:17;;35795:60;;;;-1:-1:-1;;;35795:60:0;;27401:2:1;35795:60:0;;;27383:21:1;27440:2;27420:18;;;27413:30;27479:31;27459:18;;;27452:59;27528:18;;35795:60:0;27199:353:1;35795:60:0;35869:12;35883:23;35910:6;-1:-1:-1;;;;;35910:11:0;35929:5;35950:4;35910:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35868:97;;;;35983:51;36000:7;36009:10;36021:12;35983:16;:51::i;9555:756::-;9655:12;;;9772:5;9655:12;7199:7;9802:14;9772:5;9811;9802:14;:::i;:::-;:31;;;;:::i;:::-;9791:42;-1:-1:-1;9844:8:0;9865:6;9856:5;9791:42;9856:1;:5;:::i;:::-;9855:16;;;;:::i;:::-;9844:27;-1:-1:-1;9909:1:0;9891:10;9844:27;9891:6;:10;:::i;:::-;:14;;9904:1;9891:14;:::i;:::-;9890:20;;;;:::i;:::-;9886:24;;:1;:24;:::i;:::-;9882:28;-1:-1:-1;9921:12:0;9955:7;9945:5;9882:28;9949:1;9945:5;:::i;:::-;9937:14;;:4;:14;:::i;:::-;9936:26;;;;:::i;:::-;9921:41;-1:-1:-1;9998:1:0;9982:12;9921:41;9982:4;:12;:::i;:::-;9981:18;;;;:::i;:::-;9977:22;;:1;:22;:::i;:::-;:27;;10002:2;9977:27;:::i;:::-;9973:31;-1:-1:-1;10015:13:0;10042:4;10032:6;9973:31;10032:2;:6;:::i;:::-;10031:15;;;;:::i;:::-;10015:31;-1:-1:-1;10057:11:0;10093:2;10076:13;10015:31;10076:4;:13;:::i;:::-;10075:20;;;;:::i;:::-;10071:24;;:1;:24;:::i;:::-;10057:38;-1:-1:-1;10110:11:0;10119:2;10110:6;:11;:::i;:::-;10106:15;-1:-1:-1;10154:6:0;10106:15;10154:2;:6;:::i;:::-;10141:10;:6;10150:1;10141:10;:::i;:::-;:19;;;;:::i;:::-;10132:28;-1:-1:-1;10204:1:0;10196:5;10186:6;10190:2;10186:1;:6;:::i;:::-;10179:14;;:3;:14;:::i;:::-;:22;;;;:::i;:::-;:26;;;;:::i;:::-;10171:34;10266:6;;-1:-1:-1;10298:4:0;-1:-1:-1;9555:756:0;-1:-1:-1;;;;;;9555:756:0:o;8131:652::-;8253:13;8295:4;8287;:12;;8279:21;;;;;;8333:4;8372:5;8410:3;8311:12;7199:7;8708:1;8687:3;8681:2;8666:11;8675:2;8372:5;8666:11;:::i;:::-;8665:18;;;;:::i;:::-;8650:12;:5;8658:4;8650:12;:::i;:::-;:33;;;;:::i;:::-;8649:41;;;;:::i;:::-;8644:47;;:1;:47;:::i;:::-;8643:66;;;;:::i;:::-;8625:2;;8584:11;8593:2;8584:6;:11;:::i;:::-;8583:18;;;;:::i;:::-;8582:25;;8605:2;8582:25;:::i;:::-;8569:10;8578:1;8569:6;:10;:::i;:::-;:38;;;;:::i;:::-;8562:46;;:3;:46;:::i;:::-;8561:66;;;;:::i;:::-;8544:1;8524:2;8509:11;8518:2;8509:6;:11;:::i;:::-;8508:18;;;;:::i;:::-;8493:12;:5;8501:4;8493:12;:::i;:::-;:33;;;;:::i;:::-;8485:42;;:4;:42;:::i;:::-;8484:61;;;;:::i;:::-;8443:25;8463:5;8443:4;:25;:::i;:::-;:102;;;;:::i;:::-;:184;;;;:::i;:::-;:266;;;;:::i;:::-;:296;;;;:::i;:::-;8427:312;8131:652;-1:-1:-1;;;;;;;;8131:652:0:o;38431:712::-;38581:12;38610:7;38606:530;;;-1:-1:-1;38641:10:0;38634:17;;38606:530;38755:17;;:21;38751:374;;38953:10;38947:17;39014:15;39001:10;38997:2;38993:19;38986:44;38751:374;39096:12;39089:20;;-1:-1:-1;;;39089:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:248:1;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:1;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:1:o;449:180::-;508:6;561:2;549:9;540:7;536:23;532:32;529:52;;;577:1;574;567:12;529:52;-1:-1:-1;600:23:1;;449:180;-1:-1:-1;449:180:1:o;634:632::-;805:2;857:21;;;927:13;;830:18;;;949:22;;;776:4;;805:2;1028:15;;;;1002:2;987:18;;;776:4;1071:169;1085:6;1082:1;1079:13;1071:169;;;1146:13;;1134:26;;1215:15;;;;1180:12;;;;1107:1;1100:9;1071:169;;;-1:-1:-1;1257:3:1;;634:632;-1:-1:-1;;;;;;634:632:1:o;1271:173::-;1339:20;;-1:-1:-1;;;;;1388:31:1;;1378:42;;1368:70;;1434:1;1431;1424:12;1449:186;1508:6;1561:2;1549:9;1540:7;1536:23;1532:32;1529:52;;;1577:1;1574;1567:12;1529:52;1600:29;1619:9;1600:29;:::i;2478:254::-;2546:6;2554;2607:2;2595:9;2586:7;2582:23;2578:32;2575:52;;;2623:1;2620;2613:12;2575:52;2659:9;2646:23;2636:33;;2688:38;2722:2;2711:9;2707:18;2688:38;:::i;:::-;2678:48;;2478:254;;;;;:::o;2737:494::-;2917:2;2902:18;;2906:9;2997:6;2875:4;3031:194;3045:4;3042:1;3039:11;3031:194;;;3104:13;;3092:26;;3141:4;3165:12;;;;3200:15;;;;3065:1;3058:9;3031:194;;;3035:3;;;2737:494;;;;:::o;3236:367::-;3299:8;3309:6;3363:3;3356:4;3348:6;3344:17;3340:27;3330:55;;3381:1;3378;3371:12;3330:55;-1:-1:-1;3404:20:1;;-1:-1:-1;;;;;3436:30:1;;3433:50;;;3479:1;3476;3469:12;3433:50;3516:4;3508:6;3504:17;3492:29;;3576:3;3569:4;3559:6;3556:1;3552:14;3544:6;3540:27;3536:38;3533:47;3530:67;;;3593:1;3590;3583:12;3530:67;3236:367;;;;;:::o;3608:773::-;3730:6;3738;3746;3754;3807:2;3795:9;3786:7;3782:23;3778:32;3775:52;;;3823:1;3820;3813:12;3775:52;3863:9;3850:23;-1:-1:-1;;;;;3933:2:1;3925:6;3922:14;3919:34;;;3949:1;3946;3939:12;3919:34;3988:70;4050:7;4041:6;4030:9;4026:22;3988:70;:::i;:::-;4077:8;;-1:-1:-1;3962:96:1;-1:-1:-1;4165:2:1;4150:18;;4137:32;;-1:-1:-1;4181:16:1;;;4178:36;;;4210:1;4207;4200:12;4178:36;;4249:72;4313:7;4302:8;4291:9;4287:24;4249:72;:::i;:::-;3608:773;;;;-1:-1:-1;4340:8:1;-1:-1:-1;;;;3608:773:1:o;4386:316::-;4463:6;4471;4479;4532:2;4520:9;4511:7;4507:23;4503:32;4500:52;;;4548:1;4545;4538:12;4500:52;-1:-1:-1;;4571:23:1;;;4641:2;4626:18;;4613:32;;-1:-1:-1;4692:2:1;4677:18;;;4664:32;;4386:316;-1:-1:-1;4386:316:1:o;4960:127::-;5021:10;5016:3;5012:20;5009:1;5002:31;5052:4;5049:1;5042:15;5076:4;5073:1;5066:15;5092:902;5146:5;5199:3;5192:4;5184:6;5180:17;5176:27;5166:55;;5217:1;5214;5207:12;5166:55;5253:6;5240:20;5279:4;-1:-1:-1;;;;;5339:2:1;5335;5332:10;5329:36;;;5345:18;;:::i;:::-;5391:2;5388:1;5384:10;5423:2;5417:9;5486:2;5482:7;5477:2;5473;5469:11;5465:25;5457:6;5453:38;5541:6;5529:10;5526:22;5521:2;5509:10;5506:18;5503:46;5500:72;;;5552:18;;:::i;:::-;5588:2;5581:22;5638:18;;;5714:15;;;5710:24;;;5672:15;;;;-1:-1:-1;5746:15:1;;;5743:35;;;5774:1;5771;5764:12;5743:35;5810:2;5802:6;5798:15;5787:26;;5822:142;5838:6;5833:3;5830:15;5822:142;;;5904:17;;5892:30;;5942:12;;;;5855;;;;5822:142;;5999:669;6126:6;6134;6142;6195:2;6183:9;6174:7;6170:23;6166:32;6163:52;;;6211:1;6208;6201:12;6163:52;6251:9;6238:23;-1:-1:-1;;;;;6321:2:1;6313:6;6310:14;6307:34;;;6337:1;6334;6327:12;6307:34;6360:61;6413:7;6404:6;6393:9;6389:22;6360:61;:::i;:::-;6350:71;;6474:2;6463:9;6459:18;6446:32;6430:48;;6503:2;6493:8;6490:16;6487:36;;;6519:1;6516;6509:12;6487:36;;6542:63;6597:7;6586:8;6575:9;6571:24;6542:63;:::i;:::-;6532:73;;;6624:38;6658:2;6647:9;6643:18;6624:38;:::i;:::-;6614:48;;5999:669;;;;;:::o;6673:658::-;6844:2;6896:21;;;6966:13;;6869:18;;;6988:22;;;6815:4;;6844:2;7067:15;;;;7041:2;7026:18;;;6815:4;7110:195;7124:6;7121:1;7118:13;7110:195;;;7189:13;;-1:-1:-1;;;;;7185:39:1;7173:52;;7280:15;;;;7245:12;;;;7221:1;7139:9;7110:195;;7336:322;7413:6;7421;7429;7482:2;7470:9;7461:7;7457:23;7453:32;7450:52;;;7498:1;7495;7488:12;7450:52;7534:9;7521:23;7511:33;;7591:2;7580:9;7576:18;7563:32;7553:42;;7614:38;7648:2;7637:9;7633:18;7614:38;:::i;7663:348::-;7747:6;7800:2;7788:9;7779:7;7775:23;7771:32;7768:52;;;7816:1;7813;7806:12;7768:52;7856:9;7843:23;-1:-1:-1;;;;;7881:6:1;7878:30;7875:50;;;7921:1;7918;7911:12;7875:50;7944:61;7997:7;7988:6;7977:9;7973:22;7944:61;:::i;8016:184::-;8086:6;8139:2;8127:9;8118:7;8114:23;8110:32;8107:52;;;8155:1;8152;8145:12;8107:52;-1:-1:-1;8178:16:1;;8016:184;-1:-1:-1;8016:184:1:o;8683:127::-;8744:10;8739:3;8735:20;8732:1;8725:31;8775:4;8772:1;8765:15;8799:4;8796:1;8789:15;8815:168;8855:7;8921:1;8917;8913:6;8909:14;8906:1;8903:21;8898:1;8891:9;8884:17;8880:45;8877:71;;;8928:18;;:::i;:::-;-1:-1:-1;8968:9:1;;8815:168::o;8988:127::-;9049:10;9044:3;9040:20;9037:1;9030:31;9080:4;9077:1;9070:15;9104:4;9101:1;9094:15;9120:120;9160:1;9186;9176:35;;9191:18;;:::i;:::-;-1:-1:-1;9225:9:1;;9120:120::o;9245:326::-;9447:2;9429:21;;;9486:1;9466:18;;;9459:29;-1:-1:-1;;;9519:2:1;9504:18;;9497:33;9562:2;9547:18;;9245:326::o;9576:340::-;9778:2;9760:21;;;9817:2;9797:18;;;9790:30;-1:-1:-1;;;9851:2:1;9836:18;;9829:46;9907:2;9892:18;;9576:340::o;9921:356::-;10123:2;10105:21;;;10142:18;;;10135:30;10201:34;10196:2;10181:18;;10174:62;10268:2;10253:18;;9921:356::o;10282:326::-;10484:2;10466:21;;;10523:1;10503:18;;;10496:29;-1:-1:-1;;;10556:2:1;10541:18;;10534:33;10599:2;10584:18;;10282:326::o;11304:::-;11506:2;11488:21;;;11545:1;11525:18;;;11518:29;-1:-1:-1;;;11578:2:1;11563:18;;11556:33;11621:2;11606:18;;11304:326::o;11635:411::-;11837:2;11819:21;;;11876:2;11856:18;;;11849:30;11915:34;11910:2;11895:18;;11888:62;-1:-1:-1;;;11981:2:1;11966:18;;11959:45;12036:3;12021:19;;11635:411::o;12051:326::-;12253:2;12235:21;;;12292:1;12272:18;;;12265:29;-1:-1:-1;;;12325:2:1;12310:18;;12303:33;12368:2;12353:18;;12051:326::o;12382:127::-;12443:10;12438:3;12434:20;12431:1;12424:31;12474:4;12471:1;12464:15;12498:4;12495:1;12488:15;12514:326;12716:2;12698:21;;;12755:1;12735:18;;;12728:29;-1:-1:-1;;;12788:2:1;12773:18;;12766:33;12831:2;12816:18;;12514:326::o;12845:294::-;13022:2;13018:15;;;;-1:-1:-1;;13014:53:1;13002:66;;13093:2;13084:12;;13077:28;13130:2;13121:12;;12845:294::o;14299:135::-;14338:3;-1:-1:-1;;14359:17:1;;14356:43;;;14379:18;;:::i;:::-;-1:-1:-1;14426:1:1;14415:13;;14299:135::o;14439:326::-;14641:2;14623:21;;;14680:1;14660:18;;;14653:29;-1:-1:-1;;;14713:2:1;14698:18;;14691:33;14756:2;14741:18;;14439:326::o;15711:125::-;15751:4;15779:1;15776;15773:8;15770:34;;;15784:18;;:::i;:::-;-1:-1:-1;15821:9:1;;15711:125::o;15841:325::-;16043:2;16025:21;;;16082:1;16062:18;;;16055:29;-1:-1:-1;;;16115:2:1;16100:18;;16093:32;16157:2;16142:18;;15841:325::o;16501:128::-;16541:3;16572:1;16568:6;16565:1;16562:13;16559:39;;;16578:18;;:::i;:::-;-1:-1:-1;16614:9:1;;16501:128::o;23130:258::-;23202:1;23212:113;23226:6;23223:1;23220:13;23212:113;;;23302:11;;;23296:18;23283:11;;;23276:39;23248:2;23241:10;23212:113;;;23343:6;23340:1;23337:13;23334:48;;;-1:-1:-1;;23378:1:1;23360:16;;23353:27;23130:258::o;23393:::-;23435:3;23473:5;23467:12;23500:6;23495:3;23488:19;23516:63;23572:6;23565:4;23560:3;23556:14;23549:4;23542:5;23538:16;23516:63;:::i;:::-;23633:2;23612:15;-1:-1:-1;;23608:29:1;23599:39;;;;23640:4;23595:50;;23393:258;-1:-1:-1;;23393:258:1:o;23656:383::-;23853:2;23842:9;23835:21;23816:4;23879:45;23920:2;23909:9;23905:18;23897:6;23879:45;:::i;:::-;23972:9;23964:6;23960:22;23955:2;23944:9;23940:18;23933:50;24000:33;24026:6;24018;24000:33;:::i;25156:112::-;25188:1;25214;25204:35;;25219:18;;:::i;:::-;-1:-1:-1;25253:9:1;;25156:112::o;25273:470::-;25452:3;25490:6;25484:13;25506:53;25552:6;25547:3;25540:4;25532:6;25528:17;25506:53;:::i;:::-;25622:13;;25581:16;;;;25644:57;25622:13;25581:16;25678:4;25666:17;;25644:57;:::i;:::-;25717:20;;25273:470;-1:-1:-1;;;;25273:470:1:o;26099:277::-;26166:6;26219:2;26207:9;26198:7;26194:23;26190:32;26187:52;;;26235:1;26232;26225:12;26187:52;26267:9;26261:16;26320:5;26313:13;26306:21;26299:5;26296:32;26286:60;;26342:1;26339;26332:12;27557:274;27686:3;27724:6;27718:13;27740:53;27786:6;27781:3;27774:4;27766:6;27762:17;27740:53;:::i;:::-;27809:16;;;;;27557:274;-1:-1:-1;;27557:274:1:o;27836:265::-;27875:3;27903:9;;;27928:10;;-1:-1:-1;;;;;27947:27:1;;;27940:35;;27924:52;27921:78;;;27979:18;;:::i;:::-;-1:-1:-1;;;28026:19:1;;;28019:27;;28011:36;;28008:62;;;28050:18;;:::i;:::-;-1:-1:-1;;28086:9:1;;27836:265::o;28106:553::-;28145:7;-1:-1:-1;;;;;28215:9:1;;;28243;;;28268:11;;;28287:10;;;28281:17;;28264:35;28261:61;;;28302:18;;:::i;:::-;-1:-1:-1;;;28378:1:1;28371:9;;28396:11;;;28416;;;28409:19;;28392:37;28389:63;;;28432:18;;:::i;:::-;28478:1;28475;28471:9;28461:19;;28525:1;28521:2;28516:11;28513:1;28509:19;28504:2;28500;28496:11;28492:37;28489:63;;;28532:18;;:::i;:::-;28597:1;28593:2;28588:11;28585:1;28581:19;28576:2;28572;28568:11;28564:37;28561:63;;;28604:18;;:::i;:::-;-1:-1:-1;;;28644:9:1;;;;;28106:553;-1:-1:-1;;;28106:553:1:o;28664:193::-;28703:1;28729;28719:35;;28734:18;;:::i;:::-;-1:-1:-1;;;28770:18:1;;-1:-1:-1;;28790:13:1;;28766:38;28763:64;;;28807:18;;:::i;:::-;-1:-1:-1;28841:10:1;;28664:193::o;28862:267::-;28901:4;28930:9;;;28955:10;;-1:-1:-1;;;28974:19:1;;28967:27;;28951:44;28948:70;;;28998:18;;:::i;:::-;-1:-1:-1;;;;;29045:27:1;;29038:35;;29030:44;;29027:70;;;29077:18;;:::i;:::-;-1:-1:-1;;29114:9:1;;28862:267::o;29134:220::-;29283:2;29272:9;29265:21;29246:4;29303:45;29344:2;29333:9;29329:18;29321:6;29303:45;:::i
Swarm Source
ipfs://1e8e71d04321c61cbea798e0c220b88d5e37b921bdfb67b7e07db65b7fd1d000
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.