ETH Price: $3,629.78 (+1.26%)

Token

ERC-20: OnChainDonald (OCD)
 

Overview

Max Total Supply

110 OCD

Holders

46

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
xatarrer.eth
Balance
1 OCD
0x2b7841c71f2866E5E0c7E66f27cE6cdC0182dab8
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
OnChainDonald

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-01
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

/*

   /$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  | $DOCDOCDOCDOCDOOWWNNNXXXNNWCDOCDOCDOCDO$
  | $OCDOCDOCOOWXOdc:,'......',:ld0NDOCDOCO$     /$$$$$$             /$$$$$$  /$$                 /$$          
  | $CDOCDOCDKo;.                 .;0OCDOCD$    /$$__  $$           /$$__  $$| $$                |__/   
  | $DOCDOOO0;                    .:0CDOCDO$   | $$  \ $$ /$$$$$$$ | $$  \__/| $$$$$$$   /$$$$$$  /$$ /$$$$$$$ 
  | $OCDOCONc    ';,'..........';o0NDOCDOCO$   | $$  | $$| $$__  $$| $$      | $$__  $$ |____  $$| $$| $$__  $$
  | $CDOCDO0,   .cxxdddddddddddxx0NOCDOCDOC$   | $$  | $$| $$  \ $$| $$      | $$  \ $$  /$$$$$$$| $$| $$  \ $$
  | $DOCDOO0'   ,ddc::cdxxxo:;:oxOXCDOCDOCD$   | $$  | $$| $$  | $$| $$    $$| $$  | $$ /$$__  $$| $$| $$  | $$
  | $OCDOCONl..,oxxxddxxxxxxdddxxkXDOCDOCDO$   |  $$$$$$/| $$  | $$|  $$$$$$/| $$  | $$|  $$$$$$$| $$| $$  | $$
  | $CDOCDOON0kxxxxxxxxxdddxxxxxxONOCDOCDOC$    \______/ |__/  |__/ \______/ |__/  |__/ \_______/|__/|__/  |__/
  | $DOCDOCDOON0xxxxxxxxxxxxxxxxkKWCDOCDOCD$
  | $OCDOCDOCOON0xxxxxdxxxxxxxxkKWDOCDOCDOC$              /$$$$$$$                                /$$       /$$
  | $CDOCDOCDOCDKddxxxxxxxxxxdd0WOCDOCDOCDO$             | $$__  $$                              | $$      | $$
  | $DOCDOCDOON0c'oK0kxxdxkO0o'cKWCDOCDOCDO$             | $$  \ $$  /$$$$$$  /$$$$$$$   /$$$$$$ | $$  /$$$$$$$
  | $OCDOCNKxl;...,0W0occo0WK:..'ckNWDOCDOC$             | $$  | $$ /$$__  $$| $$__  $$ |____  $$| $$ /$$__  $$
  | $OWKkl,.   ....cKKdccdKNd.... .'o0WOCDO$             | $$  | $$| $$  \ $$| $$  \ $$  /$$$$$$$| $$| $$  | $$
  | $l,.       .....o0d::o0k,...     .;xXWO$             | $$  | $$| $$  | $$| $$  | $$ /$$__  $$| $$| $$  | $$
  | $          .....,lc::cdc.....       .cO$             | $$$$$$$/|  $$$$$$/| $$  | $$|  $$$$$$$| $$|  $$$$$$$
  | $           .....';:::;......         .$             |_______/  \______/ |__/  |__/ \_______/|__/ \_______/
  | $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  |________________________________________/

  OnChainDonald (OCD) is a collection of 2024 unique Donalds:
  - Built with long term preservation and decentralization in mind
  - All metadata and images are generated and stored 100% on-chain
  - Each Donald is unique and is composed from 9 traits with 73 values
  - In addition, there is an optional special trait with 17 values (opt-in on mint)
  - Extensive API surface to build on

*/

// File: base64-sol/base64.sol

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol

// OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol)

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/Counters.sol

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol

// 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 no longer needed starting with Solidity 0.8. 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/Strings.sol

/**
 * @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/utils/Context.sol

/**
 * @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/access/Ownable.sol

/**
 * @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() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol

/**
 * @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: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol

/**
 * @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 IERC165 {
    /**
     * @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/utils/introspection/ERC165.sol

/**
 * @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 ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` 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 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/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 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'
        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) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _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
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: @openzeppelin/contracts/finance/PaymentSplitter.sol


// OpenZeppelin Contracts v4.4.1 (finance/PaymentSplitter.sol)

/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleased(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function released(IERC20 token, address account) public view returns (uint256) {
        return _erc20Released[token][account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(account, totalReceived, released(account));

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _released[account] += payment;
        _totalReleased += payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function release(IERC20 token, address account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        uint256 payment = _pendingPayment(account, totalReceived, released(token, account));

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _erc20Released[token][account] += payment;
        _erc20TotalReleased[token] += payment;

        SafeERC20.safeTransfer(token, account, payment);
        emit ERC20PaymentReleased(token, account, payment);
    }

    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) private {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }
}

// File: contracts/OnChainDonald.sol

contract OnChainDonald is
    ERC721,
    ERC721Enumerable,
    Ownable,
    ReentrancyGuard,
    PaymentSplitter
{
    using SafeMath for uint256;
    using Counters for Counters.Counter;

    // State
    uint256 public state;
    uint256 internal constant STATE_INIT = 0;
    uint256 internal constant STATE_MINTING = 1;
    uint256 internal constant STATE_MINTING_REVEALED = 2;
    uint256 internal constant STATE_MINTED = 3;
    uint256 internal constant STATE_LOCKED = 4;

    // Nifties
    Counters.Counter public numMinted;
    uint256 public constant MAX_MINTS = 2024;
    uint256 internal constant MAX_MINTS_PER_TX = 5;
    uint256 internal constant MINT_PRICE = 0.02024 ether;
    uint256 internal constant SPECIAL_MINT_PRICE = 0.045 ether;
    uint256 internal constant MAX_WHITELIST_MINTS_PER_TX = 2;
    mapping (address => bool) public whitelist;
    mapping(uint256 => bool) internal special;
    uint256 internal seed;
    string internal description =
        "OnChainDonald is a collection of 2024 unique Donalds. "
        "The artwork and metadata are fully on-chain, in a single contract.";

    // Traits
    string internal constant COLOR_BLACK = "#000000";
    string internal constant COLOR_WHITE = "#ffffff";
    string internal constant ATTRIBUTE_NAME_EYES = "Eyes";
    string internal constant ATTRIBUTE_NAME_EXPRESSION = "Expression";
    string internal constant ATTRIBUTE_NAME_SKIN = "Skin";
    string internal constant ATTRIBUTE_NAME_LOCATION = "Location";
    string internal constant ATTRIBUTE_NAME_HAIR = "Hair";
    string internal constant ATTRIBUTE_NAME_TIE = "Tie";
    string internal constant ATTRIBUTE_NAME_MOUTH = "Mouth";
    string internal constant ATTRIBUTE_NAME_SUIT = "Suit";
    string internal constant ATTRIBUTE_NAME_PIN = "Pin";
    string internal constant ATTRIBUTE_NAME_SPECIALITY = "Speciality";

    string[] internal locations = [
        "",
        "Red Room",
        "Blue Room",
        "Office",
        "Boardroom",
        "Beach Villa",
        "Golf Resort",
        "Casino",
        "Penthouse",
        "Podium",
        "Mars",
        "Swamp"
    ];

    uint256[] internal locationColors = [
        0xb31942, 0xb31942, 0xb31942,
        0x54000c, 0x54000c, 0x54000c,
        0x000c54, 0x000c54, 0x000c54,
        0xb22234, 0xffffff, 0x3c3b6e,
        0xd98922, 0xf9c35d, 0xa83809,
        0x3e91a3, 0x718e73, 0xbba58f,
        0x93dbdf, 0x52a9bb, 0x8daf23,
        0xfbd946, 0xf55022, 0xff98b0,
        0xb38728, 0xfbf5b8, 0xcfb162,
        0xb5a084, 0x9c815d, 0x957d64,
        0x0e0a22, 0xcb3927, 0xf8b37c,
        0xe5d059, 0x6dba3c, 0x42063c
    ];

    string[] internal expressions = [
        "",
        "Neutral",
        "Wink",
        "Squint",
        "Surprised"
    ];

    uint256 internal NEUTRAL_EXPRESSION_INDEX = 1;
    uint256 internal WINK_EXPRESSION_INDEX = 2;
    uint256 internal SQUINT_EXPRESSION_INDEX = 3;
    uint256 internal SURPRISED_EXPRESSION_INDEX = 4;

    string[] internal eyes = [
        "",
        "Brown",
        "Dark Grey",
        "Black",
        "Hollow",
        "Pearl",
        "Blue",
        "Green",
        "Pepe",
        "Patriot",
        "Laser",
        "Hollow Blue",
        "Candy Apple"
    ];

    uint256[] internal eyeRarities = [
        0, // Unrevealed
        120, // Brown
        410, // Dark Grey
        30, // Black
        60, // Hollow
        50, // Pearl
        60, // Blue
        60, // Green
        30, // Pepe
        50, // Patriot
        40, // Laser
        40, // Hollow Blue
        50  // Candy Apple
    ];

    uint256 internal HOLLOW_EYES_INDEX = 4;
    uint256 internal PEPE_EYES_INDEX = 8;
    uint256 internal PATRIOT_EYES_INDEX = 9;
    uint256 internal LASER_EYES_INDEX = 10;

    uint256[] internal eyeColors = [
        0x000000,
        0x804800, // Brown
        0x394545, // Dark Grey
        0x111111, // Black
        0x000000, // Hollow
        0x6e695f, // Pearl
        0x3d4dcb, // Blue
        0x55ab35, // Green
        0x000000, // Regular
        0x0000ff, // Patriot
        0xff0000, // Laser
        0x2222d8, // Hollow Blue
        0xf51600  // Candy Apple
    ];

    bool[] internal pupils = [
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        false,
        false,
        false,
        true
    ];

    string[] internal skins = [
        "",
        "Pale",
        "Warm Pale",
        "Toned Pale",
        "Glow",
        "Mahogany",
        "Orange",
        "Carrot",
        "Burned",
        "Mango",
        "Alien",
        "Pepe",
        "Nyan",
        "White"
    ];

    uint256[] internal skinRarities = [
        0, // Unrevealed
        110, // Pale
        170, // Warm Pale
        176, // Toned Pale
        163, // Glow
        30, // Mahogany
        85, // Orange
        85, // Carrot
        80, // Burned
        65, // Mango
        7, // Alien
        5, // Pepe
        4, // Nyan
        20 // White
    ];

    uint256[] internal skinFaceColors = [
        0x000000,
        0xfee2da,
        0xfecebe,
        0xf0be9b,
        0xf6a685,
        0xb55e45,
        0xffa500,
        0xec9332,
        0xe5887c,
        0xfd844e,        
        0x98aa9c,
        0x69804d,
        0xf391f2,
        0xfff0ea
    ];

    uint256[] internal skinNoseColors = [
        0x000000,
        0xfdf6f6,
        0xffe0e0,
        0xf6ccc6,
        0xffc0a0,
        0xc56e55,
        0xffd020,
        0xe9793c,
        0xf5988c,
        0xff995e,
        0xb2beb5,
        0x89a06d,
        0xf361c1,
        0xfffbfb
    ];

    uint256[] internal skinLipsColors = [
        0x000000,
        0xf0c4b9,
        0xca848a,
        0xb56d69,
        0xc86070,
        0x803d3e,
        0xa06000,
        0xcc6332,
        0xc5685c,
        0xfd541e,
        0x648688,
        0x9a3828,
        0xf33191,
        0xf4c8bc
    ];

    string[] internal mouths = [
        "",
        "Teethy",
        "Closed",
        "Yelling",
        "Taunting",
        "Stern",
        "Pursed",
        "Pepe"
    ];

    uint256[] internal mouthRarities = [
        0,
        175, // Teethy
        150, // Closed
        225, // Yelling
        100, // Taunting
        150, // Stern
        100, // Pursed
        100  // Pepe
    ];

    uint256 internal TEETHY_MOUTH_INDEX = 1;
    uint256 internal CLOSED_MOUTH_INDEX = 2;
    uint256 internal OPEN_MOUTH_INDEX = 3;
    uint256 internal TAUNTING_MOUTH_INDEX = 4;
    uint256 internal STERN_MOUTH_INDEX = 5;
    uint256 internal PURSED_MOUTH_INDEX = 6;
    uint256 internal PEPE_MOUTH_INDEX = 7;

    string[] internal hairs = [
        "",
        "Brown",
        "Copper",
        "Maga",
        "Blonde",
        "White",
        "Cream",
        "Platinum",
        "Silver",
        "Punk",
        "Black",
        "Bald",
        "Gold Flame"
    ];

    uint256[] internal hairRarities = [
        0,
        100, // Brown
        60, // Copper
        160, // Maga
        140, // Blonde
        100, // White
        100, // Cream
        60, // Platinum
        70, // Silver
        20, // Punk
        60, // Black
        100, // Bald,
        30 // Gold Flame
    ];

    uint256[] internal hairColors = [
        0x000000,
        0xd7a183,
        0xef9655,
        0xefc680,
        0xfad799,
        0xf8f8f8,
        0xfaebd7,
        0xdfdad0,
        0xbabfc8,
        0xc46ce9,
        0x080808,
        0x000000,
        0xe46029,
        0xef8045
    ];

    uint256 internal BALD_HAIR_INDEX = 11;

    string[] internal ties = [
        "",
        "Red",
        "Black",
        "Blue",
        "Yellow",
        "Gold",
        "Red Stripes",
        "Blue Stripes",
        "Black Stripes",
        "True Patriot"
    ];

    uint256 internal TIE_STRIPES_START_INDEX = 6;
    uint256 internal PATRIOT_TIE_INDEX = 9;

    uint256[] internal tieColors = [
        0x000000,
        0xd7282a,
        0x000000,
        0x0000ff,
        0xfff642,
        0xffd700,
        0xff0000,
        0x0000ff,
        0x000000,
        0x1010e0
    ];

    string[] internal suits = [
        "",
        "Black",
        "Navy",
        "None"
    ];

    uint256[] internal suitRarities = [
        0,
        400,
        400,
        200
    ];

    uint256[] internal suitColors = [
        0x000000,
        0x080808,
        0x193059,
        0x000000
    ];

    uint256[] internal suitLapelColors = [
        0x000000,
        0x161616,
        0x203865,
        0x000000
    ];

    uint256 internal SUIT_NONE_INDEX = 3;

    string[] internal pins = [
        "",
        "None",
        "Patriot"
    ];

    uint256 internal PIN_NONE_INDEX = 1;
    uint256 internal PIN_PATRIOT_INDEX = 2;

    string[] internal specialities = [
        "None",
        "Covfefe",
        "Hamberder",
        "Macho",
        "Dancer",
        "Big Hands",
        "Golfer",
        "Honest",
        "Dealmaker",
        "Rich",
        "Genius",
        "Patriot",
        "Strong",
        "Great",
        "Humble",
        "Big League",
        "Winner",
        "Handsome"
    ];

    uint256 internal SPECIALITY_NONE_INDEX = 0;

    struct Don {
        uint256 tokenId;
        bool revealed;
        bool special;
        uint256 eyes;
        uint256 expression;
        uint256 skin;
        uint256 location;
        uint256 hair;
        uint256 tie;
        uint256 mouth;
        uint256 suit;
        uint256 pin;
        uint256 speciality;
    }

    constructor(address[] memory _payees, uint256[] memory _shares)
        payable
        ERC721("OnChainDonald", "OCD")
        PaymentSplitter(_payees, _shares) {}

    function _safeMint(uint256 _quantity, bool _special) private {
        require(_quantity > 0);
        require(
            numMinted.current().add(_quantity) <= MAX_MINTS,
            "Cannot exceed total supply"
        );

        for (uint256 i = 0; i < _quantity; i++) {
            numMinted.increment();
            uint256 mintIndex = numMinted.current();

            if (mintIndex <= MAX_MINTS) {
                _safeMint(msg.sender, mintIndex);
                if (_special) {
                    special[mintIndex] = true;
                }
            }
        }
    }

    function mint(uint256 _quantity, bool _special)
        external
        payable
        nonReentrant
    {
        require(
            state == STATE_MINTING || state == STATE_MINTING_REVEALED,
            "Mint closed"
        );
        require(_quantity > 0 && _quantity <= MAX_MINTS_PER_TX);
        require(
            msg.value >=
                (_special ? SPECIAL_MINT_PRICE : MINT_PRICE).mul(_quantity),
            "Payment too small"
        );

        _safeMint(_quantity, _special);
    }

    function whitelistMint(uint256 _quantity)
        external
        payable
        nonReentrant
    {
        require(state == STATE_MINTING || state == STATE_MINTING);
        require(whitelist[msg.sender], "Not whitelisted");
        require(_quantity > 0 && _quantity <= MAX_WHITELIST_MINTS_PER_TX);
        require(msg.value >= MINT_PRICE.mul(_quantity), "Payment too small");

        _safeMint(_quantity, true);
        whitelist[msg.sender] = false;
    }

    function whitelistAddresses(address[] memory _addresses) external onlyOwner {
        require(state == STATE_INIT || state == STATE_MINTING);

        for (uint256 i = 0; i < _addresses.length; i++) {
            whitelist[_addresses[i]] = true;
        }
    }

    function startMint() external onlyOwner {
        require(state == STATE_INIT);

        state = STATE_MINTING;
    }

    function reveal(uint256 _seed) external onlyOwner {
        require(state == STATE_MINTING);
        require(_seed != 0);

        state = STATE_MINTING_REVEALED;
        seed = _seed + 0x201620202024c0fefe;
    }

    function closeMint() external onlyOwner {
        require(state == STATE_MINTING_REVEALED);

        state = STATE_MINTED;
    }

    function lock() external onlyOwner {
        require(state == STATE_MINTED);

        state = STATE_LOCKED;
    }

    function setMeta(string memory _description) external onlyOwner {
        require(state != STATE_LOCKED);

        description = _description;
    }

    function random(uint256 _seed, string memory input)
        private
        pure
        returns (uint256)
    {
        return _seed + uint256(keccak256(abi.encodePacked(input)));
    }

    function pluck(
        uint256 _seed,
        uint256 tokenId,
        string memory keyPrefix,
        string[] memory sourceArray
    ) private pure returns (uint256) {
        uint256 rand = random(
            _seed,
            string(abi.encodePacked(keyPrefix, Strings.toString(tokenId)))
        );
        return (rand % (sourceArray.length - 1)) + 1;
    }

    function pluckRarities(
        uint256 _seed,
        uint256 tokenId,
        string memory keyPrefix,
        uint256[] memory rarityArray
    ) private pure returns (uint256) {

        uint256 rand = random(
            _seed,
            string(abi.encodePacked(keyPrefix, Strings.toString(tokenId)))
        ) % 1000;

        uint256 i = 0;
        uint256 acc = 0;

        while (i < rarityArray.length - 1) {
            acc += rarityArray[i];
            if(rand < acc) break;
            i++;
        }

        return i;
    }

    function makeFilledEllipse(
        uint256 cx,
        uint256 cy,
        uint256 rx,
        uint256 ry,
        string memory fill,
        string memory extras
    ) private pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    '<ellipse cx="',
                    Strings.toString(cx),
                    '" cy="',
                    Strings.toString(cy),
                    '" rx="',
                    Strings.toString(rx),
                    '" ry="',
                    Strings.toString(ry),
                    '" fill="',
                    fill,
                    '" ',
                    extras,
                    "/>"
                )
            );
    }

    function makePolygon(string memory points, string memory fill)
        private
        pure
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    '<polygon points="',
                    points,
                    '" fill="',
                    fill,
                    '" />'
                )
            );
    }

    function uint8tohexchar(uint8 i) private pure returns (uint8) {
        return
            (i > 9)
                ? (i + 87) // ascii a-f
                : (i + 48); // ascii 0-9
    }

    function hexColorToString(uint256 i) private pure returns (string memory) {
        bytes memory o = new bytes(7);
        uint24 mask = 0x00000f;

        uint256 j;
        for (j = 6; j > 0; --j) {
            o[j] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
        }
        o[0] = "#";
        return string(o);
    }

    function getSuitSVG(Don memory don) private view returns (string memory) {
        uint256 suitIndex = don.suit;
        uint256 pinIndex = don.pin;
        string memory suitColor = hexColorToString(suitColors[suitIndex]);
        string memory suitLapelColor = hexColorToString(
            suitLapelColors[suitIndex]
        );

        return
            string(
                abi.encodePacked(
                    suitIndex < SUIT_NONE_INDEX
                        ? makePolygon(
                            "0 220 80 180 90 160 122 256 0 256",
                            suitColor
                        )
                        : "",
                    suitIndex < SUIT_NONE_INDEX
                        ? makePolygon(
                            "256 240 176 180 166 160 138 256 256 256",
                            suitColor
                        )
                        : "",
                    suitIndex < SUIT_NONE_INDEX
                        ? makePolygon(
                            "90 160 122 256 83 256 65 225 78 218 64 210",
                            suitLapelColor
                        )
                        : "",
                    suitIndex < SUIT_NONE_INDEX
                        ? makePolygon(
                            "166 160 138 256 173 256 191 225 178 218 192 210",
                            suitLapelColor
                        )
                        : "",
                    pinIndex == PIN_PATRIOT_INDEX
                        ? '<text x="226" y="175" transform="rotate(18 0 0)" font-family="Tahoma, sans-serif" font-size="14" fill="#FFD700">&#127482;&#127480;</text>'
                        : ""
                )
            );
    }

    function getShirtAndTieSVG(Don memory don)
        private
        view
        returns (string memory)
    {
        uint256 tieIndex = don.tie;
        uint256 suitIndex = don.suit;
        string memory tieColor = hexColorToString(tieColors[tieIndex]);
        string memory shirtCollarColor = hexColorToString(0xffffff);
        string memory shirtBodyColor = hexColorToString(0xeaeaea);
        string
            memory shirtWithSuit = "92 160 160 160 180 190 220 256 190 256 168 220 170 256 85 256 85 220 66 256 38 256";
        string
            memory shirtWithoutSuit = "92 160 160 160 220 180 240 256 170 256 85 256 20 256 30 180";
        string
            memory tiePolygon = "129, 160, 141, 190, 133, 200, 150, 256, 110, 256, 123, 200, 115, 190";

        return
            string(
                abi.encodePacked(
                    makePolygon(
                        suitIndex < SUIT_NONE_INDEX
                            ? shirtWithSuit
                            : shirtWithoutSuit,
                        shirtBodyColor
                    ),
                    makePolygon("130 160 105 210 90 165", shirtCollarColor),
                    makePolygon("126 160 151 210 166 165", shirtCollarColor),
                    makePolygon(tiePolygon, tieColor),
                    tieIndex >= TIE_STRIPES_START_INDEX
                        ? makePolygon(tiePolygon, "url(#p1)")
                        : ""
                )
            );
    }

    function getEyesSVG(Don memory don, string memory eyelashColor) private view returns (string memory) {
        uint256 eyeIndex = don.eyes;
        bool hasPupils = pupils[eyeIndex];
        uint256 expressionIndex = don.expression;
        uint256 eyeWidth = 12;
        uint256 eyeHeight = 5;
        uint256 pupilHeight = 4;
        uint256 pupilWidth = 4;
        uint256 laserWidth = 7;
        string memory lEyeColor = hasPupils ? COLOR_WHITE : hexColorToString(eyeColors[eyeIndex]);
        string memory rEyeColor = lEyeColor;
        string memory pupilColor = hexColorToString(eyeColors[eyeIndex]);
        string memory extras = "";
        string memory extraAttrs = "";
        string memory rEyeEmptyStr = "";

        if (expressionIndex == SQUINT_EXPRESSION_INDEX) {
            eyeHeight -= 2;
            pupilHeight--;
            laserWidth = 4;
        } else if (expressionIndex == WINK_EXPRESSION_INDEX) {
            rEyeEmptyStr = string(
                abi.encodePacked(
                    '<path d="M 150 100 C 155 99, 165 99, 170 100" stroke="',
                    hasPupils ? eyelashColor : rEyeColor,
                    '" stroke-linecap="round" stroke-width="4"',
                    (eyeIndex == HOLLOW_EYES_INDEX) ? ' opacity="0.5"' : "",
                    " />"
                )
            );
        } else if (expressionIndex == SURPRISED_EXPRESSION_INDEX) {
            eyeWidth -= 4;
            eyeHeight++;
            laserWidth += 5;
            pupilWidth++;
        }

        if(eyeIndex == PEPE_EYES_INDEX && expressionIndex != SQUINT_EXPRESSION_INDEX) {
            pupilHeight++;
            pupilWidth++;
        }

        if (expressionIndex == SURPRISED_EXPRESSION_INDEX && eyeIndex == PEPE_EYES_INDEX) {
            eyeWidth++;
            eyeHeight++;
        }

        if (hasPupils) {
            extras = string(
                abi.encodePacked(
                    makeFilledEllipse(
                        112,
                        100,
                        pupilWidth,
                        pupilHeight,
                        pupilColor,
                        extraAttrs
                    ),
                    (expressionIndex != WINK_EXPRESSION_INDEX)
                        ? makeFilledEllipse(
                            160,
                            100,
                            pupilWidth,
                            pupilHeight,
                            pupilColor,
                            extraAttrs
                        )
                        : ""
                )
            );

            lEyeColor = COLOR_WHITE;
            rEyeColor = COLOR_WHITE;
        }

        if (eyeIndex == PATRIOT_EYES_INDEX) {
            lEyeColor = hexColorToString(0xff0000);
        } else if (eyeIndex == LASER_EYES_INDEX) {
            if (laserWidth > 0) {
                extras = string(
                    abi.encodePacked(
                        '<line x1="112" y1="100" x2="266" y2="36" style="stroke:',
                        lEyeColor,
                        ";stroke-width:",
                        Strings.toString(laserWidth),
                        '" opacity="0.8" />'
                    )
                );
            }
            if (laserWidth > 0 && expressionIndex != WINK_EXPRESSION_INDEX) {
                extras = string(
                    abi.encodePacked(
                        extras,
                        '<line x1="160" y1="100" x2="266" y2="56" style="stroke:',
                        lEyeColor,
                        ";stroke-width:",
                        Strings.toString(laserWidth),
                        '" opacity="0.8" />'
                    )
                );
            }
        } else if (eyeIndex == HOLLOW_EYES_INDEX) {
            extraAttrs = 'fill-opacity="0.5"';
        }

        return
            string(
                abi.encodePacked(
                    makeFilledEllipse(
                        112,
                        100,
                        eyeWidth,
                        eyeHeight,
                        lEyeColor,
                        extraAttrs
                    ),
                    (expressionIndex != WINK_EXPRESSION_INDEX)
                        ? makeFilledEllipse(
                            160,
                            100,
                            eyeWidth,
                            eyeHeight,
                            rEyeColor,
                            extraAttrs
                        )
                        : rEyeEmptyStr,
                    extras
                )
            );
    }

    function getSkinSVG(Don memory don) private view returns (string memory) {
        uint256 skinIndex = don.skin;
        uint256 mouthIndex = don.mouth;
        string memory skinFaceColorStr = hexColorToString(
            skinFaceColors[skinIndex]
        );
        string memory skinNoseColorStr = hexColorToString(
            skinNoseColors[skinIndex]
        );
        string memory skinLipsColorStr = hexColorToString(
            skinLipsColors[skinIndex]
        );
        string memory mouthStr = "";

        if (mouthIndex == TEETHY_MOUTH_INDEX) {
            mouthStr = string(
                abi.encodePacked(
                    makeFilledEllipse(135, 156, 16, 8, skinLipsColorStr, ""),
                    makeFilledEllipse(135, 156, 12, 2, COLOR_WHITE, "")
                )
            );
        } else if (mouthIndex == CLOSED_MOUTH_INDEX) {
            mouthStr = makeFilledEllipse(135, 156, 16, 4, skinLipsColorStr, "");
        } else if (mouthIndex == OPEN_MOUTH_INDEX) {
            mouthStr = string(
                abi.encodePacked(
                    makeFilledEllipse(135, 156, 18, 9, skinLipsColorStr, ""),
                    makeFilledEllipse(135, 149, 11, 2, COLOR_WHITE, ""),
                    makeFilledEllipse(135, 163, 11, 2, COLOR_WHITE, "")
                )
            );
        } else if (mouthIndex == TAUNTING_MOUTH_INDEX) {
            mouthStr = makeFilledEllipse(135, 156, 8, 8, skinLipsColorStr, "");
        } else if (mouthIndex == STERN_MOUTH_INDEX) {
            mouthStr = string(
                abi.encodePacked(
                    '<path d="M 121 156 C 126 153, 147 152, 151 155" stroke="',
                    skinLipsColorStr,
                    '" stroke-linecap="round" stroke-width="4" fill="transparent" />'
                )
            );
        } else if (mouthIndex == PURSED_MOUTH_INDEX) {
            mouthStr = string(
                abi.encodePacked(
                    '<ellipse cx="3" cy="206" rx="11" ry="7" fill="',
                    skinLipsColorStr,
                    '" transform="rotate(-40 0 0)" />'
                )
            );
        } else if (mouthIndex == PEPE_MOUTH_INDEX) {
            mouthStr = string(
                abi.encodePacked(
                    '<path d="M 110 150 C 118 155, 154 155, 162 150" stroke="',
                    skinLipsColorStr,
                    '" stroke-linecap="round" stroke-width="6" fill="transparent" />'
                )
            );
        } 

        return
            string(
                abi.encodePacked(
                    makeFilledEllipse(130, 108, 60, 75, skinFaceColorStr, ""),
                    makeFilledEllipse(138, 124, 8, 12, skinNoseColorStr, ""),
                    mouthStr
                )
            );
    }

    function getHairSVG(Don memory don) private view returns (string memory) {
        uint256 hairIndex = don.hair;
        string memory hairColorStr = hexColorToString(hairColors[hairIndex]);

        if (hairIndex == BALD_HAIR_INDEX) {
            return "";
        } else {
            return
                string(
                    abi.encodePacked(
                        makeFilledEllipse(140, 55, 64, 24, hairColorStr, ""),
                        makeFilledEllipse(
                            85,
                            70,
                            16,
                            38,
                            hairColorStr,
                            'transform="rotate(10 0 0)"'
                        )
                    )
                );
        }
    }

    function getLocationSVG(Don memory don, bool transparent)
        private
        view
        returns (string memory)
    {
        uint256 index = don.location * 3;
        string memory fill = transparent ? 'none' : 'url(#gr1)';
        
        return
            string(
                abi.encodePacked(
                    '<linearGradient id="gr1" x1="0" x2="0" y1="0" y2="1">'
                    '<stop offset="0%" stop-color="',
                    hexColorToString(locationColors[index]),
                    '"/>'
                    '<stop offset="40%" stop-color="',
                    hexColorToString(locationColors[index + 1]),
                    '"/>'
                    '<stop offset="80%" stop-color="',
                    hexColorToString(locationColors[index + 2]),
                    '"/>'
                    "</linearGradient>"
                    '<rect x="0" y="0" rx="0" ry="0" width="256" height="256" fill="', fill, '" />'
                )
            );
    }

    function getDefsSVG(Don memory don) private view returns (string memory) {
        string memory stroke = (don.tie == PATRIOT_TIE_INDEX)
            ? "#e01010"
            : COLOR_WHITE;
        string memory strokeOpacity = (don.tie == PATRIOT_TIE_INDEX)
            ? ""
            : 'stroke-opacity="0.7" ';

        return
            string(
                abi.encodePacked(
                    '<pattern id="p1" patternUnits="userSpaceOnUse" width="8" height="8" patternTransform="rotate(-55)">'
                    '<line x1="0" y="0" x2="0" y2="30" stroke="',
                    stroke,
                    '" ',
                    strokeOpacity,
                    'stroke-width="6" /></pattern>'
                )
            );
    }

    function getSVG(Don memory don, bool transparent) private view returns (string memory) {
        return
            string(
                abi.encodePacked(
                    '<svg xmlns="http://www.w3.org/2000/svg" preserveaspectratio="xMidYMid meet" viewBox="0 0 256 256">',
                    getDefsSVG(don),
                    getLocationSVG(don, transparent),
                    getShirtAndTieSVG(don),
                    getSuitSVG(don),
                    getSkinSVG(don),
                    getHairSVG(don),
                    getEyesSVG(don, hexColorToString(skinLipsColors[don.skin])),
                    "</svg>"
                )
            );
    }

    function makeAttributeJson(string memory name, string memory value)
        private
        pure
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    '{"trait_type": "',
                    name,
                    '", "value": "',
                    value,
                    '"},'
                )
            );
    }

    function makeCoreAttributesJson(Don memory don)
        private
        view
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    makeAttributeJson(ATTRIBUTE_NAME_EYES, eyes[don.eyes]),
                    makeAttributeJson(
                        ATTRIBUTE_NAME_EXPRESSION,
                        expressions[don.expression]
                    ),
                    makeAttributeJson(ATTRIBUTE_NAME_SKIN, skins[don.skin]),
                    makeAttributeJson(
                        ATTRIBUTE_NAME_LOCATION,
                        locations[don.location]
                    ),
                    makeAttributeJson(ATTRIBUTE_NAME_HAIR, hairs[don.hair]),
                    makeAttributeJson(ATTRIBUTE_NAME_TIE, ties[don.tie]),
                    makeAttributeJson(ATTRIBUTE_NAME_MOUTH, mouths[don.mouth]),
                    makeAttributeJson(ATTRIBUTE_NAME_SUIT, suits[don.suit]),
                    makeAttributeJson(ATTRIBUTE_NAME_PIN, pins[don.pin])
                )
            );
    }

    function pluckPin(
        uint256 _seed,
        uint256 tokenId,
        uint256 suit
    ) internal view returns (uint256) {
        if (suit == SUIT_NONE_INDEX) {
            return PIN_NONE_INDEX;
        }

        uint256 val = random(
            _seed,
            string(
                abi.encodePacked(ATTRIBUTE_NAME_PIN, Strings.toString(tokenId))
            )
        ) % 4;
        if (val == 1) {
            return PIN_PATRIOT_INDEX;
        } else {
            return PIN_NONE_INDEX;
        }
    }

    function randomDon(
        uint256 _tokenId,
        uint256 _seed,
        bool _special,
        bool _revealed
    ) internal view returns (Don memory) {
        if (_revealed == false) {
            return Don(_tokenId, false, _special, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        }

        uint256 suit = pluckRarities(
            _seed,
            _tokenId,
            ATTRIBUTE_NAME_SUIT,
            suitRarities
        );
        uint256 speciality = _special
            ? pluck(
                _seed,
                _tokenId,
                ATTRIBUTE_NAME_SPECIALITY,
                specialities
            )
            : SPECIALITY_NONE_INDEX;

        return
            Don({
                tokenId: _tokenId,
                special: _special,
                revealed: true,
                eyes: pluckRarities(_seed, _tokenId, ATTRIBUTE_NAME_EYES, eyeRarities),
                expression: pluck(
                    _seed,
                    _tokenId,
                    ATTRIBUTE_NAME_EXPRESSION,
                    expressions
                ),
                skin: pluckRarities(_seed, _tokenId, ATTRIBUTE_NAME_SKIN, skinRarities),
                location: pluck(
                    _seed,
                    _tokenId,
                    ATTRIBUTE_NAME_LOCATION,
                    locations
                ),
                hair: pluckRarities(_seed, _tokenId, ATTRIBUTE_NAME_HAIR, hairRarities),
                tie: pluck(_seed, _tokenId, ATTRIBUTE_NAME_TIE, ties),
                mouth: pluckRarities(
                    _seed,
                    _tokenId,
                    ATTRIBUTE_NAME_MOUTH,
                    mouthRarities
                ),
                suit: suit,
                pin: pluckPin(_seed, _tokenId, suit),
                speciality: speciality
            });
    }

    function attrs(uint256 tokenId) public view returns (Don memory) {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        return
            randomDon(
                tokenId,
                seed,
                special[tokenId],
                state != STATE_INIT && state != STATE_MINTING
            );
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        return encodedMetadata(attrs(tokenId), false);
    }

    function namePrefix(Don memory don) internal view returns (string memory) {
        if (!don.revealed && don.special) {
            return "Special ";
        } else if (don.revealed && don.speciality != SPECIALITY_NONE_INDEX) {
            return string(abi.encodePacked(specialities[don.speciality], " "));
        } else {
            return "";
        }
    }

    function metadata(Don memory don, bool transparent)
        internal
        view
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    '{"name":"',
                    namePrefix(don),
                    "Donald #",
                    Strings.toString(don.tokenId),
                    '","description":"',
                    description,
                    '","attributes":[',
                    makeCoreAttributesJson(don),
                    makeAttributeJson(
                        ATTRIBUTE_NAME_SPECIALITY,
                        specialities[don.speciality]
                    ),
                    '{"trait_type": "Special", "value": "',
                    (don.special ? "Yes" : "No"),
                    '"}'
                    '],"image": "data:image/svg+xml;base64,',
                    Base64.encode(bytes(getSVG(don, transparent))),
                    '"}'
                )
            );
    }

    function encodedMetadata(Don memory don, bool transparent)
        internal
        view
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(bytes(metadata(don, transparent)))
                )
            );
    }

    function render(Don memory don, bool transparent)
        external
        view
        returns (string memory)
    {
        return encodedMetadata(don, transparent);
    }

    // The following functions are overrides required by Solidity.
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"_payees","type":"address[]"},{"internalType":"uint256[]","name":"_shares","type":"uint256[]"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","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"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_MINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"attrs","outputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"revealed","type":"bool"},{"internalType":"bool","name":"special","type":"bool"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"expression","type":"uint256"},{"internalType":"uint256","name":"skin","type":"uint256"},{"internalType":"uint256","name":"location","type":"uint256"},{"internalType":"uint256","name":"hair","type":"uint256"},{"internalType":"uint256","name":"tie","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"suit","type":"uint256"},{"internalType":"uint256","name":"pin","type":"uint256"},{"internalType":"uint256","name":"speciality","type":"uint256"}],"internalType":"struct OnChainDonald.Don","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bool","name":"_special","type":"bool"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numMinted","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"revealed","type":"bool"},{"internalType":"bool","name":"special","type":"bool"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"expression","type":"uint256"},{"internalType":"uint256","name":"skin","type":"uint256"},{"internalType":"uint256","name":"location","type":"uint256"},{"internalType":"uint256","name":"hair","type":"uint256"},{"internalType":"uint256","name":"tie","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"suit","type":"uint256"},{"internalType":"uint256","name":"pin","type":"uint256"},{"internalType":"uint256","name":"speciality","type":"uint256"}],"internalType":"struct OnChainDonald.Don","name":"don","type":"tuple"},{"internalType":"bool","name":"transparent","type":"bool"}],"name":"render","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_seed","type":"uint256"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_description","type":"string"}],"name":"setMeta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"whitelistAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

61012060405260786080818152906200804460a03980516200002a91601891602090910190620019e9565b50604080516101a08101825260006101808201908152815281518083018352600881526752656420526f6f6d60c01b6020828101919091528083019190915282518084018452600980825268426c756520526f6f6d60b81b8284015283850191909152835180850185526006808252654f666669636560d01b8285015260608501919091528451808601865282815268426f617264726f6f6d60b81b81850152608085015284518086018652600b8082526a42656163682056696c6c6160a81b8286015260a0860191909152855180870187529081526a11dbdb198814995cdbdc9d60aa1b8185015260c08501528451808601865281815265436173696e6f60d01b8185015260e0850152845180860186529182526850656e74686f75736560b81b828401526101008401919091528351808501855290815265506f6469756d60d01b818301526101208301528251808401845260048152634d61727360e01b818301526101408301528251808401909352600583526405377616d760dc1b90830152610160810191909152620001c690601990600c62001a78565b50604080516104808101825262b3194280825260208201819052918101919091526254000c606082018190526080820181905260a0820152610c5460c0820181905260e0820181905261010082015262b2223461012082015262ffffff610140820152623c3b6e61016082015262d9892261018082015262f9c35d6101a082015262a838096101c0820152623e91a36101e082015262718e7361020082015262bba58f6102208201526293dbdf6102408201526252a9bb610260820152628daf2361028082015262fbd9466102a082015262f550226102c082015262ff98b06102e082015262b3872861030082015262fbf5b861032082015262cfb16261034082015262b5a084610360820152629c815d61038082015262957d646103a0820152620e0a226103c082015262cb39276103e082015262f8b37c61040082015262e5d059610420820152626dba3c6104408201526242063c6104608201526200033390601a90602462001ad8565b506040805160c081018252600060a08201908152815281518083018352600781526613995d5d1c985b60ca1b6020828101919091528083019190915282518084018452600481526357696e6b60e01b818301528284015282518084018452600681526514dc5d5a5b9d60d21b8183015260608301528251808401909352600983526814dd5c9c1c9a5cd95960ba1b908301526080810191909152620003dd90601b90600562001b1d565b506001601c556002601d556003601e556004601f819055604080516101c08101825260006101a08201908152815281518083018352600580825264213937bbb760d91b602083810191909152808401929092528351808501855260098152684461726b204772657960b81b81840152838501528351808501855281815264426c61636b60d81b818401526060840152835180850185526006815265486f6c6c6f7760d01b81840152608084015283518085018552818152641419585c9b60da1b8184015260a08401528351808501855285815263426c756560e01b8184015260c0840152835180850185528181526423b932b2b760d91b8184015260e084015283518085018552948552635065706560e01b8583015261010083019490945282518084018452600781526614185d1c9a5bdd60ca1b8183015261012083015282518084018452938452642630b9b2b960d91b8482015261014082019390935281518083018352600b8082526a486f6c6c6f7720426c756560a81b82860152610160830191909152825180840190935282526a43616e6479204170706c6560a81b82840152610180810191909152620005989190600d62001b6f565b50604080516101a081018252600081526078602082015261019a91810191909152601e60608201819052603c60808301819052603260a0840181905260c0840182905260e08401919091526101008301919091526101208201819052602861014083018190526101608301526101808201526200061a90602190600d62001bc1565b50600460225560086023556009602455600a602555604080516101a0810182526000808252628048006020830152623945459282019290925262111111606082015260808101829052626e695f60a0820152623d4dcb60c08201526255ab3560e082015261010081019190915260ff61012082015262ff0000610140820152622222d861016082015262f51600610180820152620006bd90602690600d62001ad8565b50604080516101a0810182526000808252600160208301819052928201839052606082018190526080820181905260a0820183905260c0820183905260e082018390526101008201839052610120820181905261014082018190526101608201526101808101919091526200073790602790600d62001c05565b50604080516101e08101825260006101c0820190815281528151808301835260048082526350616c6560e01b602083810191909152808401929092528351808501855260098152685761726d2050616c6560b81b818401528385015283518085018552600a815269546f6e65642050616c6560b01b8184015260608401528351808501855281815263476c6f7760e01b8184015260808401528351808501855260088152674d61686f67616e7960c01b8184015260a0840152835180850185526006808252654f72616e676560d01b8285015260c0850191909152845180860186528181526510d85c9c9bdd60d21b8185015260e08501528451808601865290815265109d5c9b995960d21b81840152610100840152835180850185526005808252644d616e676f60d81b82850152610120850191909152845180860186528181526420b634b2b760d91b8185015261014085015284518086018652828152635065706560e01b818501526101608501528451808601865291825263273cb0b760e11b828401526101808401919091528351808501909452835264576869746560d81b908301526101a0810191909152620008f790602890600e62001cac565b50604080516101c08101825260008152606e602082015260aa9181019190915260b0606082015260a36080820152601e60a0820152605560c0820181905260e08201526050610100820152604161012082015260076101408201526005610160820152600461018082015260146101a08201526200097a90602990600e62001cfe565b50604080516101c0810182526000815262fee2da602082015262fecebe9181019190915262f0be9b606082015262f6a685608082015262b55e4560a082015262ffa50060c082015262ec933260e082015262e5887c61010082015262fd844e6101208201526298aa9c6101408201526269804d61016082015262f391f261018082015262fff0ea6101a082015262000a1790602a90600e62001ad8565b50604080516101c0810182526000815262fdf6f6602082015262ffe0e09181019190915262f6ccc6606082015262ffc0a0608082015262c56e5560a082015262ffd02060c082015262e9793c60e082015262f5988c61010082015262ff995e61012082015262b2beb56101408201526289a06d61016082015262f361c161018082015262fffbfb6101a082015262000ab490602b90600e62001ad8565b50604080516101c0810182526000815262f0c4b9602082015262ca848a9181019190915262b56d69606082015262c86070608082015262803d3e60a082015262a0600060c082015262cc633260e082015262c5685c61010082015262fd541e61012082015262648688610140820152629a382861016082015262f3319161018082015262f4c8bc6101a082015262000b5190602c90600e62001ad8565b506040518061010001604052806040518060200160405280600081525081526020016040518060400160405280600681526020016554656574687960d01b81525081526020016040518060400160405280600681526020016510db1bdcd95960d21b81525081526020016040518060400160405280600781526020016659656c6c696e6760c81b8152508152602001604051806040016040528060088152602001675461756e74696e6760c01b81525081526020016040518060400160405280600581526020016429ba32b93760d91b815250815260200160405180604001604052806006815260200165141d5c9cd95960d21b8152508152602001604051806040016040528060048152602001635065706560e01b815250815250602d90600862000c7f92919062001d41565b5060408051610100810182526000815260af6020820152609691810182905260e1606082015260646080820181905260a082019290925260c0810182905260e081019190915262000cd590602e90600862001cfe565b506001602f55600260305560036031556004603281905560056033819055600660348190556007603555604080516101c08101825260006101a0820190815281528151808301835284815264213937bbb760d91b60208281019190915280830191909152825180840184528481526521b7b83832b960d11b818301528284015282518084018452868152634d61676160e01b8183015260608301528251808401845284815265426c6f6e646560d01b8183015260808301528251808401845285815264576869746560d81b8183015260a08301528251808401845285815264437265616d60d81b8183015260c0830152825180840184526008815267506c6174696e756d60c01b8183015260e0830152825180840184529384526529b4b63b32b960d11b84820152610100820193909352815180830183528581526350756e6b60e01b818501526101208201528151808301835293845264426c61636b60d81b84840152610140810193909352805180820182529384526310985b1960e21b848301526101608301939093528251808401909352600a835269476f6c6420466c616d6560b01b9083015261018081019190915262000e9890603690600d62001b6f565b50604080516101a08101825260008152606460208201819052603c92820183905260a060608301819052608c6080840152820181905260c0820181905260e0820183905260466101008301526014610120830152610140820192909252610160810191909152601e61018082015262000f1690603790600d62001cfe565b50604080516101c081018252600080825262d7a183602083015262ef96559282019290925262efc680606082015262fad799608082015262f8f8f860a082015262faebd760c082015262dfdad060e082015262babfc861010082015262c46ce96101208201526208080861014082015261016081019190915262e4602961018082015262ef80456101a082015262000fb390603890600e62001ad8565b50600b6039819055604080516101608101825260006101408201908152815281518083018352600381526214995960ea1b60208281019190915280830191909152825180840184526005815264426c61636b60d81b818301528284015282518084018452600480825263426c756560e01b82840152606084019190915283518085018552600681526559656c6c6f7760d01b818401526080840152835180850185529081526311dbdb1960e21b8183015260a0830152825180840184529384526a526564205374726970657360a81b8482015260c082019390935281518083018352600c8082526b426c7565205374726970657360a01b8286015260e083019190915282518084018452600d81526c426c61636b205374726970657360981b81860152610100830152825180840190935282526b151c9d594814185d1c9a5bdd60a21b928201929092526101208201526200111390603a90600a62001d93565b506006603b556009603c556040805161014081018252600080825262d7282a602083015291810182905260ff6060820181905262fff642608083015262ffd70060a083015262ff000060c083015260e0820152610100810191909152621010e06101208201526200118990603d90600a62001ad8565b50604051806080016040528060405180602001604052806000815250815260200160405180604001604052806005815260200164426c61636b60d81b8152508152602001604051806040016040528060048152602001634e61767960e01b8152508152602001604051806040016040528060048152602001634e6f6e6560e01b815250815250603e9060046200122192919062001de5565b506040805160808101825260008152610190602082018190529181019190915260c860608201526200125890603f90600462001bc1565b50604080516080810182526000808252620808086020830152621930598284015260608201526200128c9190600462001ad8565b5060408051608081018252600080825262161616602083015262203865928201929092526060810191909152620012c890604190600462001ad8565b5060036042556040518060600160405280604051806020016040528060008152508152602001604051806040016040528060048152602001634e6f6e6560e01b81525081526020016040518060400160405280600781526020016614185d1c9a5bdd60ca1b81525081525060439060036200134592919062001e37565b5060016044556002604555604080516102808101825260046102408201818152634e6f6e6560e01b610260840152825282518084018452600780825266436f766665666560c81b60208381019190915280850192909252845180860186526009808252682430b6b132b93232b960b91b8285015285870191909152855180870187526005808252644d6163686f60d81b828601526060870191909152865180880188526006808252652230b731b2b960d11b82870152608088019190915287518089018952838152684269672048616e647360b81b8187015260a0880152875180890189528181526523b7b63332b960d11b8187015260c08801528751808901895281815265121bdb995cdd60d21b8187015260e088015287518089018952928352682232b0b636b0b5b2b960b91b8386015261010087019290925286518088018852948552630a4d2c6d60e31b85850152610120860194909452855180870187528181526547656e69757360d01b81850152610140860152855180870187529182526614185d1c9a5bdd60ca1b8284015261016085019190915284518086018652818152655374726f6e6760d01b81840152610180850152845180860186529283526411dc99585d60da1b838301526101a0840192909252835180850185528281526548756d626c6560d01b818301526101c084015283518085018552600a815269426967204c656167756560b01b818301526101e084015283518085018552918252652bb4b73732b960d11b828201526102008301919091528251808401909352600883526748616e64736f6d6560c01b90830152610220810191909152620015b590604690601262001e89565b506000604755604051620080bc380380620080bc833981016040819052620015dd9162002037565b604080518082018252600d81526c13db90da185a5b911bdb985b19609a1b60208083019182528351808501909452600384526213d0d160ea1b908401528151859385939290916200163191600091620019e9565b50805162001647906001906020840190620019e9565b505050620016646200165e620017a560201b60201c565b620017a9565b6001600b558051825114620016db5760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b60008251116200172e5760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f207061796565730000000000006044820152606401620016d2565b60005b82518110156200179a576200178583828151811062001754576200175462002115565b602002602001015183838151811062001771576200177162002115565b6020026020010151620017fb60201b60201c565b80620017918162002141565b91505062001731565b5050505050620021b7565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216620018685760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b6064820152608401620016d2565b60008111620018ba5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401620016d2565b6001600160a01b0382166000908152600e602052604090205415620019365760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b6064820152608401620016d2565b60108054600181019091557f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720180546001600160a01b0319166001600160a01b0384169081179091556000908152600e60205260409020819055600c54620019a09082906200215f565b600c55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b828054620019f7906200217a565b90600052602060002090601f01602090048101928262001a1b576000855562001a66565b82601f1062001a3657805160ff191683800117855562001a66565b8280016001018555821562001a66579182015b8281111562001a6657825182559160200191906001019062001a49565b5062001a7492915062001edb565b5090565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001ab9918491602090910190620019e9565b509160200191906001019062001a99565b5062001a7492915062001ef2565b82805482825590600052602060002090810192821562001a66579160200282015b8281111562001a66578251829062ffffff1690559160200191906001019062001af9565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001b5e918491602090910190620019e9565b509160200191906001019062001b3e565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001bb0918491602090910190620019e9565b509160200191906001019062001b90565b82805482825590600052602060002090810192821562001a66579160200282015b8281111562001a66578251829061ffff1690559160200191906001019062001be2565b82805482825590600052602060002090601f0160209004810192821562001a665791602002820160005b8382111562001c6e57835183826101000a81548160ff021916908315150217905550926020019260010160208160000104928301926001030262001c2f565b801562001c9d5782816101000a81549060ff021916905560010160208160000104928301926001030262001c6e565b505062001a7492915062001edb565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001ced918491602090910190620019e9565b509160200191906001019062001ccd565b82805482825590600052602060002090810192821562001a66579160200282015b8281111562001a66578251829060ff1690559160200191906001019062001d1f565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001d82918491602090910190620019e9565b509160200191906001019062001d62565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001dd4918491602090910190620019e9565b509160200191906001019062001db4565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001e26918491602090910190620019e9565b509160200191906001019062001e06565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001e78918491602090910190620019e9565b509160200191906001019062001e58565b82805482825590600052602060002090810192821562001aca579160200282015b8281111562001aca578251805162001eca918491602090910190620019e9565b509160200191906001019062001eaa565b5b8082111562001a74576000815560010162001edc565b8082111562001a7457600062001f09828262001f13565b5060010162001ef2565b50805462001f21906200217a565b6000825580601f1062001f32575050565b601f01602090049060005260206000209081019062001f52919062001edb565b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562001f965762001f9662001f55565b604052919050565b60006001600160401b0382111562001fba5762001fba62001f55565b5060051b60200190565b600082601f83011262001fd657600080fd5b8151602062001fef62001fe98362001f9e565b62001f6b565b82815260059290921b840181019181810190868411156200200f57600080fd5b8286015b848110156200202c578051835291830191830162002013565b509695505050505050565b600080604083850312156200204b57600080fd5b82516001600160401b03808211156200206357600080fd5b818501915085601f8301126200207857600080fd5b815160206200208b62001fe98362001f9e565b82815260059290921b84018101918181019089841115620020ab57600080fd5b948201945b83861015620020e25785516001600160a01b0381168114620020d25760008081fd5b82529482019490820190620020b0565b91880151919650909350505080821115620020fc57600080fd5b506200210b8582860162001fc4565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156200215857620021586200212b565b5060010190565b600082198211156200217557620021756200212b565b500190565b600181811c908216806200218f57607f821691505b60208210811415620021b157634e487b7160e01b600052602260045260246000fd5b50919050565b615e7d80620021c76000396000f3fe6080604052600436106102555760003560e01c8063715018a611610139578063c19d93fb116100b6578063d52079b41161007a578063d52079b41461075b578063d79779b214610772578063e33b7de3146107a8578063e985e9c5146107bd578063f2fde38b14610806578063f83d08ba1461082657600080fd5b8063c19d93fb146106b9578063c2ca0ac5146106cf578063c87b56dd146106ef578063cce132d11461070f578063ce7c2ac21461072557600080fd5b80639852595c116100fd5780639852595c146105e65780639b19251a1461061c5780639ebd36f31461064c578063a22cb46514610679578063b88d4fde1461069957600080fd5b8063715018a61461056b578063868ff4a2146105805780638b83209b146105935780638da5cb5b146105b357806395d89b41146105d157600080fd5b80633a98ef39116101d25780634dfc1abc116101965780634dfc1abc146104c35780634f6ccce7146104e35780636352211e1461050357806364f101f01461052357806367f68fac1461053857806370a082311461054b57600080fd5b80633a98ef3914610408578063406072a91461041d57806342842e0e1461046357806348b75044146104835780634952603d146104a357600080fd5b80631916558711610219578063191655871461037357806323b872dd146103935780632be09561146103b35780632bf04304146103c85780632f745c59146103e857600080fd5b806301ffc9a7146102a357806306fdde03146102d8578063081812fc146102fa578063095ea7b31461033257806318160ddd1461035457600080fd5b3661029e577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b3480156102af57600080fd5b506102c36102be3660046144ee565b61083b565b60405190151581526020015b60405180910390f35b3480156102e457600080fd5b506102ed61084c565b6040516102cf9190614563565b34801561030657600080fd5b5061031a610315366004614576565b6108de565b6040516001600160a01b0390911681526020016102cf565b34801561033e57600080fd5b5061035261034d3660046145a4565b610978565b005b34801561036057600080fd5b506008545b6040519081526020016102cf565b34801561037f57600080fd5b5061035261038e3660046145d0565b610a8e565b34801561039f57600080fd5b506103526103ae3660046145ed565b610bbc565b3480156103bf57600080fd5b50610352610bed565b3480156103d457600080fd5b506103526103e336600461469f565b610c2b565b3480156103f457600080fd5b506103656104033660046145a4565b610cdb565b34801561041457600080fd5b50600c54610365565b34801561042957600080fd5b50610365610438366004614751565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b34801561046f57600080fd5b5061035261047e3660046145ed565b610d71565b34801561048f57600080fd5b5061035261049e366004614751565b610d8c565b3480156104af57600080fd5b506102ed6104be3660046147a3565b610f65565b3480156104cf57600080fd5b506103526104de3660046148d7565b610f78565b3480156104ef57600080fd5b506103656104fe366004614576565b610fc5565b34801561050f57600080fd5b5061031a61051e366004614576565b611058565b34801561052f57600080fd5b506103526110cf565b610352610546366004614920565b61110f565b34801561055757600080fd5b506103656105663660046145d0565b611249565b34801561057757600080fd5b506103526112d0565b61035261058e366004614576565b611306565b34801561059f57600080fd5b5061031a6105ae366004614576565b611463565b3480156105bf57600080fd5b50600a546001600160a01b031661031a565b3480156105dd57600080fd5b506102ed611493565b3480156105f257600080fd5b506103656106013660046145d0565b6001600160a01b03166000908152600f602052604090205490565b34801561062857600080fd5b506102c36106373660046145d0565b60156020526000908152604090205460ff1681565b34801561065857600080fd5b5061066c610667366004614576565b6114a2565b6040516102cf9190614945565b34801561068557600080fd5b506103526106943660046149eb565b61155f565b3480156106a557600080fd5b506103526106b4366004614a19565b611624565b3480156106c557600080fd5b5061036560135481565b3480156106db57600080fd5b506103526106ea366004614576565b61165c565b3480156106fb57600080fd5b506102ed61070a366004614576565b6116bd565b34801561071b57600080fd5b506103656107e881565b34801561073157600080fd5b506103656107403660046145d0565b6001600160a01b03166000908152600e602052604090205490565b34801561076757600080fd5b506014546103659081565b34801561077e57600080fd5b5061036561078d3660046145d0565b6001600160a01b031660009081526011602052604090205490565b3480156107b457600080fd5b50600d54610365565b3480156107c957600080fd5b506102c36107d8366004614751565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561081257600080fd5b506103526108213660046145d0565b6116d2565b34801561083257600080fd5b5061035261176d565b6000610846826117ad565b92915050565b60606000805461085b90614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461088790614a99565b80156108d45780601f106108a9576101008083540402835291602001916108d4565b820191906000526020600020905b8154815290600101906020018083116108b757829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661095c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061098382611058565b9050806001600160a01b0316836001600160a01b031614156109f15760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610953565b336001600160a01b0382161480610a0d5750610a0d81336107d8565b610a7f5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610953565b610a8983836117d2565b505050565b6001600160a01b0381166000908152600e6020526040902054610ac35760405162461bcd60e51b815260040161095390614ad4565b6000610ace600d5490565b610ad89047614b30565b90506000610b058383610b00866001600160a01b03166000908152600f602052604090205490565b611840565b905080610b245760405162461bcd60e51b815260040161095390614b48565b6001600160a01b0383166000908152600f602052604081208054839290610b4c908490614b30565b9250508190555080600d6000828254610b659190614b30565b90915550610b7590508382611886565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b610bc6338261199f565b610be25760405162461bcd60e51b815260040161095390614b93565b610a89838383611a95565b600a546001600160a01b03163314610c175760405162461bcd60e51b815260040161095390614be4565b60135415610c2457600080fd5b6001601355565b600a546001600160a01b03163314610c555760405162461bcd60e51b815260040161095390614be4565b6013541580610c6657506001601354145b610c6f57600080fd5b60005b8151811015610cd757600160156000848481518110610c9357610c93614c19565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610ccf81614c2f565b915050610c72565b5050565b6000610ce683611249565b8210610d485760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610953565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610a8983838360405180602001604052806000815250611624565b6001600160a01b0381166000908152600e6020526040902054610dc15760405162461bcd60e51b815260040161095390614ad4565b6001600160a01b0382166000908152601160205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610e1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e429190614c4a565b610e4c9190614b30565b90506000610e858383610b0087876001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b905080610ea45760405162461bcd60e51b815260040161095390614b48565b6001600160a01b03808516600090815260126020908152604080832093871683529290529081208054839290610edb908490614b30565b90915550506001600160a01b03841660009081526011602052604081208054839290610f08908490614b30565b90915550610f199050848483611c40565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6060610f718383611c92565b9392505050565b600a546001600160a01b03163314610fa25760405162461bcd60e51b815260040161095390614be4565b60046013541415610fb257600080fd5b8051610cd79060189060208401906143d3565b6000610fd060085490565b82106110335760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610953565b6008828154811061104657611046614c19565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806108465760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610953565b600a546001600160a01b031633146110f95760405162461bcd60e51b815260040161095390614be4565b60026013541461110857600080fd5b6003601355565b6002600b5414156111625760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610953565b6002600b556013546001148061117a57506002601354145b6111b45760405162461bcd60e51b815260206004820152600b60248201526a135a5b9d0818db1bdcd95960aa1b6044820152606401610953565b6000821180156111c5575060058211155b6111ce57600080fd5b6111f382826111e4576647e82c3a4100006111ed565b669fdf42f6e480005b90611ccd565b3410156112365760405162461bcd60e51b815260206004820152601160248201527014185e5b595b9d081d1bdbc81cdb585b1b607a1b6044820152606401610953565b6112408282611cd9565b50506001600b55565b60006001600160a01b0382166112b45760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610953565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146112fa5760405162461bcd60e51b815260040161095390614be4565b6113046000611db6565b565b6002600b5414156113595760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610953565b6002600b556013546001148061137157506001601354145b61137a57600080fd5b3360009081526015602052604090205460ff166113cb5760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610953565b6000811180156113dc575060028111155b6113e557600080fd5b6113f66647e82c3a41000082611ccd565b3410156114395760405162461bcd60e51b815260206004820152601160248201527014185e5b595b9d081d1bdbc81cdb585b1b607a1b6044820152606401610953565b611444816001611cd9565b50336000908152601560205260409020805460ff191690556001600b55565b60006010828154811061147857611478614c19565b6000918252602090912001546001600160a01b031692915050565b60606001805461085b90614a99565b6114aa614457565b6000828152600260205260409020546001600160a01b03166115265760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610953565b601754600083815260166020526040902054601354610846928592909160ff909116901580159061155a5750600160135414155b611e08565b6001600160a01b0382163314156115b85760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610953565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61162e338361199f565b61164a5760405162461bcd60e51b815260040161095390614b93565b6116568484848461252b565b50505050565b600a546001600160a01b031633146116865760405162461bcd60e51b815260040161095390614be4565b60016013541461169557600080fd5b8061169f57600080fd5b60026013556116b78168201620202024c0fefe614b30565b60175550565b60606108466116cb836114a2565b6000611c92565b600a546001600160a01b031633146116fc5760405162461bcd60e51b815260040161095390614be4565b6001600160a01b0381166117615760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610953565b61176a81611db6565b50565b600a546001600160a01b031633146117975760405162461bcd60e51b815260040161095390614be4565b6003601354146117a657600080fd5b6004601355565b60006001600160e01b0319821663780e9d6360e01b148061084657506108468261255e565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061180782611058565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600c546001600160a01b0384166000908152600e60205260408120549091839161186a9086614c63565b6118749190614c98565b61187e9190614cac565b949350505050565b804710156118d65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610953565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611923576040519150601f19603f3d011682016040523d82523d6000602084013e611928565b606091505b5050905080610a895760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610953565b6000818152600260205260408120546001600160a01b0316611a185760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610953565b6000611a2383611058565b9050806001600160a01b0316846001600160a01b03161480611a5e5750836001600160a01b0316611a53846108de565b6001600160a01b0316145b8061187e57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16949350505050565b826001600160a01b0316611aa882611058565b6001600160a01b031614611b105760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610953565b6001600160a01b038216611b725760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610953565b611b7d8383836125ae565b611b886000826117d2565b6001600160a01b0383166000908152600360205260408120805460019290611bb1908490614cac565b90915550506001600160a01b0382166000908152600360205260408120805460019290611bdf908490614b30565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610a899084906125b9565b6060611ca6611ca1848461268b565b6127eb565b604051602001611cb69190614cdf565b604051602081830303815290604052905092915050565b6000610f718284614c63565b60008211611ce657600080fd5b6107e8611cfc83611cf660145490565b90612951565b1115611d4a5760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742065786365656420746f74616c20737570706c790000000000006044820152606401610953565b60005b82811015610a8957611d63601480546001019055565b6000611d6e60145490565b90506107e88111611da357611d83338261295d565b8215611da3576000818152601660205260409020805460ff191660011790555b5080611dae81614c2f565b915050611d4d565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e10614457565b81611e8357604051806101a0016040528086815260200160001515815260200184151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250905061187e565b6000611efd85876040518060400160405280600481526020016314dd5a5d60e21b815250603f805480602002602001604051908101604052809291908181526020018280548015611ef357602002820191906000526020600020905b815481526020019060010190808311611edf575b5050505050612977565b9050600084611f0e5760475461200d565b61200d86886040518060400160405280600a8152602001695370656369616c69747960b01b8152506046805480602002602001604051908101604052809291908181526020016000905b82821015612004578382906000526020600020018054611f7790614a99565b80601f0160208091040260200160405190810160405280929190818152602001828054611fa390614a99565b8015611ff05780601f10611fc557610100808354040283529160200191611ff0565b820191906000526020600020905b815481529060010190602001808311611fd357829003601f168201915b505050505081526020019060010190611f58565b50505050612a26565b9050604051806101a0016040528088815260200160011515815260200186151581526020016120a8888a604051806040016040528060048152602001634579657360e01b8152506021805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b81526020016121a3888a6040518060400160405280600a81526020016922bc383932b9b9b4b7b760b11b815250601b805480602002602001604051908101604052809291908181526020016000905b8282101561200457838290600052602060002001805461211690614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461214290614a99565b801561218f5780601f106121645761010080835404028352916020019161218f565b820191906000526020600020905b81548152906001019060200180831161217257829003601f168201915b5050505050815260200190600101906120f7565b815260200161221e888a6040518060400160405280600481526020016329b5b4b760e11b8152506029805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001612317888a604051806040016040528060088152602001672637b1b0ba34b7b760c11b8152506019805480602002602001604051908101604052809291908181526020016000905b8282101561200457838290600052602060002001805461228a90614a99565b80601f01602080910402602001604051908101604052809291908181526020018280546122b690614a99565b80156123035780601f106122d857610100808354040283529160200191612303565b820191906000526020600020905b8154815290600101906020018083116122e657829003601f168201915b50505050508152602001906001019061226b565b8152602001612392888a604051806040016040528060048152602001632430b4b960e11b8152506037805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001612486888a6040518060400160405280600381526020016254696560e81b815250603a805480602002602001604051908101604052809291908181526020016000905b828210156120045783829060005260206000200180546123f990614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461242590614a99565b80156124725780601f1061244757610100808354040283529160200191612472565b820191906000526020600020905b81548152906001019060200180831161245557829003601f168201915b5050505050815260200190600101906123da565b8152602001612502888a6040518060400160405280600581526020016409adeeae8d60db1b815250602e805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001838152602001612518888a86612a66565b8152602001919091529695505050505050565b612536848484611a95565b61254284848484612ad1565b6116565760405162461bcd60e51b815260040161095390614d24565b60006001600160e01b031982166380ac58cd60e01b148061258f57506001600160e01b03198216635b5e139f60e01b145b8061084657506301ffc9a760e01b6001600160e01b0319831614610846565b610a89838383612bcc565b600061260e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612c849092919063ffffffff16565b805190915015610a89578080602001905181019061262c9190614d76565b610a895760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610953565b606061269683612c93565b83516126a190612d4f565b60186126ac86612e4d565b6127826040518060400160405280600a8152602001695370656369616c69747960b01b8152506046896101800151815481106126ea576126ea614c19565b9060005260206000200180546126ff90614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461272b90614a99565b80156127785780601f1061274d57610100808354040283529160200191612778565b820191906000526020600020905b81548152906001019060200180831161275b57829003601f168201915b5050505050613063565b87604001516127ab57604051806040016040528060028152602001614e6f60f01b8152506127c8565b6040518060400160405280600381526020016259657360e81b8152505b6127d5611ca18a8a613078565b604051602001611cb69796959493929190614e2d565b606081516000141561280b57505060408051602081019091526000815290565b6000604051806060016040528060408152602001615d2e604091399050600060038451600261283a9190614b30565b6128449190614c98565b61284f906004614c63565b9050600061285e826020614b30565b67ffffffffffffffff8111156128765761287661462e565b6040519080825280601f01601f1916602001820160405280156128a0576020820181803683370190505b509050818152600183018586518101602084015b8183101561290c576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f81168501518253506001016128b4565b600389510660018114612926576002811461293757612943565b613d3d60f01b600119830152612943565b603d60f81b6000198301525b509398975050505050505050565b6000610f718284614b30565b610cd78282604051806020016040528060008152506130fa565b6000806103e86129b0878661298b89612d4f565b60405160200161299c929190614f92565b60405160208183030381529060405261312d565b6129ba9190614fc1565b90506000805b600185516129ce9190614cac565b821015612a1b578482815181106129e7576129e7614c19565b6020026020010151816129fa9190614b30565b905080831015612a0957612a1b565b81612a1381614c2f565b9250506129c0565b509695505050505050565b600080612a37868561298b88612d4f565b905060018351612a479190614cac565b612a519082614fc1565b612a5c906001614b30565b9695505050505050565b6000604254821415612a7b5750604454610f71565b60006004612aa886604051806040016040528060038152602001622834b760e91b81525061298b88612d4f565b612ab29190614fc1565b90508060011415612ac7575050604554610f71565b5050604454610f71565b60006001600160a01b0384163b15612bc457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612b15903390899088908890600401614fd5565b6020604051808303816000875af1925050508015612b50575060408051601f3d908101601f19168201909252612b4d91810190615008565b60015b612baa573d808015612b7e576040519150601f19603f3d011682016040523d82523d6000602084013e612b83565b606091505b508051612ba25760405162461bcd60e51b815260040161095390614d24565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061187e565b50600161187e565b6001600160a01b038316612c2757612c2281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612c4a565b816001600160a01b0316836001600160a01b031614612c4a57612c4a8382613162565b6001600160a01b038216612c6157610a89816131ff565b826001600160a01b0316826001600160a01b031614610a8957610a8982826132ae565b606061187e84846000856132f2565b60608160200151158015612ca8575081604001515b15612cd1575050604080518082019091526008815267029b832b1b4b0b6160c51b602082015290565b81602001518015612ce9575060475482610180015114155b15612d3657604682610180015181548110612d0657612d06614c19565b90600052602060002001604051602001612d209190615025565b6040516020818303038152906040529050919050565b505060408051602081019091526000815290565b919050565b606081612d735750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612d9d5780612d8781614c2f565b9150612d969050600a83614c98565b9150612d77565b60008167ffffffffffffffff811115612db857612db861462e565b6040519080825280601f01601f191660200182016040528015612de2576020820181803683370190505b5090505b841561187e57612df7600183614cac565b9150612e04600a86614fc1565b612e0f906030614b30565b60f81b818381518110612e2457612e24614c19565b60200101906001600160f81b031916908160001a905350612e46600a86614c98565b9450612de6565b6060612e86604051806040016040528060048152602001634579657360e01b81525060208460600151815481106126ea576126ea614c19565b612ec36040518060400160405280600a81526020016922bc383932b9b9b4b7b760b11b815250601b8560800151815481106126ea576126ea614c19565b612efa6040518060400160405280600481526020016329b5b4b760e11b81525060288660a00151815481106126ea576126ea614c19565b612f35604051806040016040528060088152602001672637b1b0ba34b7b760c11b81525060198760c00151815481106126ea576126ea614c19565b612f6c604051806040016040528060048152602001632430b4b960e11b81525060368860e00151815481106126ea576126ea614c19565b612fa36040518060400160405280600381526020016254696560e81b815250603a896101000151815481106126ea576126ea614c19565b612fdc6040518060400160405280600581526020016409adeeae8d60db1b815250602d8a6101200151815481106126ea576126ea614c19565b6130146040518060400160405280600481526020016314dd5a5d60e21b815250603e8b6101400151815481106126ea576126ea614c19565b61304b604051806040016040528060038152602001622834b760e91b81525060438c6101600151815481106126ea576126ea614c19565b604051602001612d2099989796959493929190615042565b60608282604051602001611cb6929190615103565b60606130838361341a565b61308d84846134f5565b613096856135cd565b61309f8661378a565b6130a88761393a565b6130b188613c2d565b6130e4896130df602c8c60a00151815481106130cf576130cf614c19565b9060005260206000200154613cec565b613da7565b604051602001611cb69796959493929190615178565b61310483836141b7565b6131116000848484612ad1565b610a895760405162461bcd60e51b815260040161095390614d24565b60008160405160200161314091906152a1565b60408051601f198184030181529190528051602090910120610f719084614b30565b6000600161316f84611249565b6131799190614cac565b6000838152600760205260409020549091508082146131cc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061321190600190614cac565b6000838152600960205260408120546008805493945090928490811061323957613239614c19565b90600052602060002001549050806008838154811061325a5761325a614c19565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613292576132926152bd565b6001900381819060005260206000200160009055905550505050565b60006132b983611249565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6060824710156133535760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610953565b843b6133a15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610953565b600080866001600160a01b031685876040516133bd91906152a1565b60006040518083038185875af1925050503d80600081146133fa576040519150601f19603f3d011682016040523d82523d6000602084013e6133ff565b606091505b509150915061340f828286614305565b979650505050505050565b60606000603c5483610100015114613451576040518060400160405280600781526020016611b3333333333360c91b815250613472565b604051806040016040528060078152602001660236530313031360cc1b8152505b90506000603c54846101000151146134b75760405180604001604052806015815260200174039ba3937b5b296b7b830b1b4ba3c9e9118171b911605d1b8152506134c8565b604051806020016040528060008152505b905081816040516020016134dd9291906152d3565b60405160208183030381529060405292505050919050565b606060008360c00151600361350a9190614c63565b905060008361353a576040518060400160405280600981526020016875726c28236772312960b81b815250613558565b604051806040016040528060048152602001636e6f6e6560e01b8152505b9050613570601a83815481106130cf576130cf614c19565b613590601a613580856001614b30565b815481106130cf576130cf614c19565b6135a0601a613580866002614b30565b836040516020016135b494939291906153eb565b6040516020818303038152906040529250505092915050565b6060600082610100015190506000836101400151905060006135fb603d84815481106130cf576130cf614c19565b9050600061360b62ffffff613cec565b9050600061361b62eaeaea613cec565b90506000604051806080016040528060528152602001615cbb60529139905060006040518060600160405280603b8152602001615c80603b913990506000604051806080016040528060448152602001615c0d60449139905061368e60425488106136865782613688565b835b8561433e565b6136c6604051806040016040528060168152602001753133302031363020313035203231302039302031363560501b8152508761433e565b6137056040518060400160405280601781526020017f31323620313630203135312032313020313636203136350000000000000000008152508861433e565b61370f848a61433e565b603b548c101561372e5760405180602001604052806000815250613758565b613758856040518060400160405280600881526020016775726c282370312960c01b81525061433e565b60405160200161376c95949392919061557f565b60405160208183030381529060405298505050505050505050919050565b6060600082610140015190506000836101600151905060006137b8604084815481106130cf576130cf614c19565b905060006137d2604185815481106130cf576130cf614c19565b905060425484106137f25760405180602001604052806000815250613814565b613814604051806060016040528060218152602001615d0d602191398361433e565b60425485106138325760405180602001604052806000815250613854565b613854604051806060016040528060278152602001615df7602791398461433e565b60425486106138725760405180602001604052806000815250613894565b6138946040518060600160405280602a8152602001615e1e602a91398461433e565b60425487106138b257604051806020016040528060008152506138d4565b6138d46040518060600160405280602f8152602001615c51602f91398561433e565b60455487146138f2576040518060200160405280600081525061390c565b6040518060c0016040528060898152602001615d6e608991395b60405160200161392095949392919061557f565b604051602081830303815290604052945050505050919050565b606060008260a001519050600083610120015190506000613967602a84815481106130cf576130cf614c19565b90506000613981602b85815481106130cf576130cf614c19565b9050600061399b602c86815481106130cf576130cf614c19565b604080516020810190915260008152602f5491925090851415613a40576139d96087609c601060088660405180602001604052806000815250614353565b613a196087609c600c60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b604051602001613a2a929190614f92565b6040516020818303038152906040529050613bbc565b603054851415613a7257613a6b6087609c601060048660405180602001604052806000815250614353565b9050613bbc565b603154851415613b2f57613a9d6087609c601260098660405180602001604052806000815250614353565b613add60876095600b60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b613b1d608760a3600b60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b604051602001613a2a939291906155ea565b603254851415613b5957613a6b6087609c6008808660405180602001604052806000815250614353565b603354851415613b745781604051602001613a2a919061562d565b603454851415613b8f5781604051602001613a2a91906156e5565b603554851415613bbc5781604051602001613baa9190615768565b60405160208183030381529060405290505b613bdd6082606c603c604b8860405180602001604052806000815250614353565b613bfe608a607c6008600c8860405180602001604052806000815250614353565b82604051602001613c11939291906155ea565b6040516020818303038152906040529650505050505050919050565b606060008260e0015190506000613c50603883815481106130cf576130cf614c19565b9050603954821415613c7357505060408051602081019091526000815292915050565b613c94608c6037604060188560405180602001604052806000815250614353565b613cdb6055604660106026866040518060400160405280601a81526020017f7472616e73666f726d3d22726f74617465283130203020302922000000000000815250614353565b6040516020016134dd929190614f92565b60408051600780825281830190925260609160009190602082018180368337019050509050600f60065b8015613d6f57613d2c8262ffffff1686166143ab565b60f81b838281518110613d4157613d41614c19565b60200101906001600160f81b031916908160001a90535060049490941c93613d6881615820565b9050613d16565b602360f81b83600081518110613d8757613d87614c19565b60200101906001600160f81b031916908160001a90535091949350505050565b6060600083606001519050600060278281548110613dc757613dc7614c19565b6000918252602080832090820401546080880151601f9092166101000a900460ff16925090600c90600590600490819060079087613e1a57613e1560268a815481106130cf576130cf614c19565b613e3b565b6040518060400160405280600781526020016611b3333333333360c91b8152505b905060008190506000613e5a60268c815481106130cf576130cf614c19565b604080516020808201835260008083528351808301855281815284519283019094528152601e5493945090928c1415613eb057613e9860028b614cac565b995088613ea481615820565b99505060049650613f74565b601d548c1415613f34578c613ec55784613ec7565b8f5b6022548f14613ee55760405180602001604052806000815250613f0d565b6040518060400160405280600e81526020016d1037b830b1b4ba3c9e9118171a9160911b8152505b604051602001613f1e929190615837565b6040516020818303038152906040529050613f74565b601f548c1415613f7457613f4960048c614cac565b9a5089613f5581614c2f565b9a50613f649050600588614b30565b965087613f7081614c2f565b9850505b6023548e148015613f875750601e548c14155b15613fa85788613f9681614c2f565b9950508780613fa490614c2f565b9850505b601f548c148015613fba57506023548e145b15613fdb578a613fc981614c2f565b9b50508980613fd790614c2f565b9a50505b8c1561407257613ff1607060648a8c8887614353565b601d548d14156140105760405180602001604052806000815250614020565b61402060a060648b8d8988614353565b604051602001614031929190614f92565b60408051601f19818403018152828201825260078084526611b3333333333360c91b6020858101829052845180860190955291845290830152919750955092505b6024548e141561408f5761408862ff0000613cec565b955061414f565b6025548e14156141175786156140cc57856140a988612d4f565b6040516020016140ba9291906158f9565b60405160208183030381529060405292505b6000871180156140de5750601d548c14155b156141125782866140ee89612d4f565b604051602001614100939291906159b0565b60405160208183030381529060405292505b61414f565b6022548e141561414f57604051806040016040528060128152602001713334b63616b7b830b1b4ba3c9e9118171a9160711b81525091505b61415f607060648d8d8a87614353565b601d548d141561416f578161417f565b61417f60a060648e8e8a88614353565b84604051602001614192939291906155ea565b6040516020818303038152906040529e50505050505050505050505050505092915050565b6001600160a01b03821661420d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610953565b6000818152600260205260409020546001600160a01b0316156142725760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610953565b61427e600083836125ae565b6001600160a01b03821660009081526003602052604081208054600192906142a7908490614b30565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608315614314575081610f71565b8251156143245782518084602001fd5b8160405162461bcd60e51b81526004016109539190614563565b60608282604051602001611cb6929190615a7e565b606061435e87612d4f565b61436787612d4f565b61437087612d4f565b61437987612d4f565b868660405160200161439096959493929190615af0565b60405160208183030381529060405290509695505050505050565b600060098260ff16116143c8576143c3826030615be7565b610846565b610846826057615be7565b8280546143df90614a99565b90600052602060002090601f0160209004810192826144015760008555614447565b82601f1061441a57805160ff1916838001178555614447565b82800160010185558215614447579182015b8281111561444757825182559160200191906001019061442c565b506144539291506144c3565b5090565b604051806101a0016040528060008152602001600015158152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b8082111561445357600081556001016144c4565b6001600160e01b03198116811461176a57600080fd5b60006020828403121561450057600080fd5b8135610f71816144d8565b60005b8381101561452657818101518382015260200161450e565b838111156116565750506000910152565b6000815180845261454f81602086016020860161450b565b601f01601f19169290920160200192915050565b602081526000610f716020830184614537565b60006020828403121561458857600080fd5b5035919050565b6001600160a01b038116811461176a57600080fd5b600080604083850312156145b757600080fd5b82356145c28161458f565b946020939093013593505050565b6000602082840312156145e257600080fd5b8135610f718161458f565b60008060006060848603121561460257600080fd5b833561460d8161458f565b9250602084013561461d8161458f565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff811182821017156146685761466861462e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156146975761469761462e565b604052919050565b600060208083850312156146b257600080fd5b823567ffffffffffffffff808211156146ca57600080fd5b818501915085601f8301126146de57600080fd5b8135818111156146f0576146f061462e565b8060051b915061470184830161466e565b818152918301840191848101908884111561471b57600080fd5b938501935b8385101561474557843592506147358361458f565b8282529385019390850190614720565b98975050505050505050565b6000806040838503121561476457600080fd5b823561476f8161458f565b9150602083013561477f8161458f565b809150509250929050565b801515811461176a57600080fd5b8035612d4a8161478a565b6000808284036101c08112156147b857600080fd5b6101a0808212156147c857600080fd5b6147d0614644565b9150843582526147e260208601614798565b60208301526147f360408601614798565b6040830152606085013560608301526080850135608083015260a085013560a083015260c085013560c083015260e085013560e0830152610100808601358184015250610120808601358184015250610140808601358184015250610160808601358184015250610180808601358184015250819350614874818601614798565b925050509250929050565b600067ffffffffffffffff8311156148995761489961462e565b6148ac601f8401601f191660200161466e565b90508281528383830111156148c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156148e957600080fd5b813567ffffffffffffffff81111561490057600080fd5b8201601f8101841361491157600080fd5b61187e8482356020840161487f565b6000806040838503121561493357600080fd5b82359150602083013561477f8161478a565b815181526020808301516101a08301916149629084018215159052565b506040830151614976604084018215159052565b50606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525061016080840151818401525061018080840151818401525092915050565b600080604083850312156149fe57600080fd5b8235614a098161458f565b9150602083013561477f8161478a565b60008060008060808587031215614a2f57600080fd5b8435614a3a8161458f565b93506020850135614a4a8161458f565b925060408501359150606085013567ffffffffffffffff811115614a6d57600080fd5b8501601f81018713614a7e57600080fd5b614a8d8782356020840161487f565b91505092959194509250565b600181811c90821680614aad57607f821691505b60208210811415614ace57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614b4357614b43614b1a565b500190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614c4357614c43614b1a565b5060010190565b600060208284031215614c5c57600080fd5b5051919050565b6000816000190483118215151615614c7d57614c7d614b1a565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ca757614ca7614c82565b500490565b600082821015614cbe57614cbe614b1a565b500390565b60008151614cd581856020860161450b565b9290920192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614d1781601d85016020870161450b565b91909101601d0192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600060208284031215614d8857600080fd5b8151610f718161478a565b8054600090600181811c9080831680614dad57607f831692505b6020808410821415614dcf57634e487b7160e01b600052602260045260246000fd5b818015614de35760018114614df457614e21565b60ff19861689528489019650614e21565b60008881526020902060005b86811015614e195781548b820152908501908301614e00565b505084890196505b50505050505092915050565b683d913730b6b2911d1160b91b81528751600090614e52816009850160208d0161450b565b67446f6e616c64202360c01b6009918401918201528851614e7a816011840160208d0161450b565b701116113232b9b1b934b83a34b7b7111d1160791b60119290910191820152614ea66022820189614d93565b6f222c2261747472696275746573223a5b60801b81528751909150614ed2816010840160208b0161450b565b8651910190614ee8816010840160208a0161450b565b7f7b2274726169745f74797065223a20225370656369616c222c202276616c75656010929091019182015263111d101160e11b6030820152614f84614f76614f70614f366034850189614cc3565b7f227d5d2c22696d616765223a2022646174613a696d6167652f7376672b786d6c8152670ed8985cd94d8d0b60c21b602082015260280190565b86614cc3565b61227d60f01b815260020190565b9a9950505050505050505050565b60008351614fa481846020880161450b565b835190830190614fb881836020880161450b565b01949350505050565b600082614fd057614fd0614c82565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612a5c90830184614537565b60006020828403121561501a57600080fd5b8151610f71816144d8565b60006150318284614d93565b600160fd1b81526001019392505050565b60008a51615054818460208f0161450b565b8a516150668183860160208f0161450b565b8a51918401019061507b818360208e0161450b565b895161508d8183850160208e0161450b565b89519290910101906150a3818360208c0161450b565b87516150b58183850160208c0161450b565b87519290910101906150cb818360208a0161450b565b85516150dd8183850160208a0161450b565b85519290910101906150f381836020880161450b565b019b9a5050505050505050505050565b6f3d913a3930b4ba2fba3cb832911d101160811b8152825160009061512f81601085016020880161450b565b6c111610113b30b63ab2911d101160991b601091840191820152835161515c81601d84016020880161450b565b62089f4b60ea1b601d9290910191820152602001949350505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32308152600060207f30302f73766722207072657365727665617370656374726174696f3d22784d69818401527f64594d6964206d656574222076696577426f783d223020302032353620323536604084015261111f60f11b606084015260628a5161520881838701858f0161450b565b8a519085019061521d81848401868f0161450b565b8a5191019061523181848401868e0161450b565b895191019061524581848401868d0161450b565b885191019061525981848401868c0161450b565b875191019061526d81848401868b0161450b565b61529061527e848385010189614cc3565b651e17b9bb339f60d11b815260060190565b9d9c50505050505050505050505050565b600082516152b381846020870161450b565b9190910192915050565b634e487b7160e01b600052603160045260246000fd5b7f3c7061747465726e2069643d22703122207061747465726e556e6974733d227581527f73657253706163654f6e557365222077696474683d223822206865696768743d60208201527f223822207061747465726e5472616e73666f726d3d22726f74617465282d353560408201527f29223e3c6c696e652078313d22302220793d2230222078323d2230222079323d60608201526c111998111039ba3937b5b29e9160991b60808201526000835161539381608d85016020880161450b565b61011160f51b608d9184019182015283516153b581608f84016020880161450b565b7f7374726f6b652d77696474683d223622202f3e3c2f7061747465726e3e000000608f929091019182015260ac01949350505050565b7f3c6c696e6561724772616469656e742069643d22677231222078313d2230222081527f78323d2230222079313d2230222079323d2231223e3c73746f70206f666673656020820152723a1e911812911039ba37b816b1b7b637b91e9160691b604082015260008551615465816053850160208a0161450b565b7f222f3e3c73746f70206f66667365743d22343025222073746f702d636f6c6f72605391840191820152611e9160f11b6073820181905286516154af816075850160208b0161450b565b7f222f3e3c73746f70206f66667365743d22383025222073746f702d636f6c6f7260759390910192830152609582015284516154f281609784016020890161450b565b7f222f3e3c2f6c696e6561724772616469656e743e3c7265637420783d22302220609792909101918201527f793d2230222072783d2230222072793d2230222077696474683d22323536222060b7820152723432b4b3b43a1e91191a9b11103334b6361e9160691b60d782015261340f61556f60ea830186614cc3565b631110179f60e11b815260040190565b60008651615591818460208b0161450b565b8651908301906155a5818360208b0161450b565b86519101906155b8818360208a0161450b565b85519101906155cb81836020890161450b565b84519101906155de81836020880161450b565b01979650505050505050565b600084516155fc81846020890161450b565b84519083019061561081836020890161450b565b845191019061562381836020880161450b565b0195945050505050565b7f3c7061746820643d224d2031323120313536204320313236203135332c20313481527f37203135322c203135312031353522207374726f6b653d22000000000000000060208201526000825161568b81603885016020870161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d60389390910192830152507f77696474683d2234222066696c6c3d227472616e73706172656e7422202f3e006058820152607701919050565b7f3c656c6c697073652063783d2233222063793d22323036222072783d2231312281526d10393c9e911b91103334b6361e9160911b60208201526000825161573481602e85016020870161450b565b7f22207472616e73666f726d3d22726f74617465282d3430203020302922202f3e602e939091019283015250604e01919050565b7f3c7061746820643d224d2031313020313530204320313138203135352c20313581527f34203135352c203136322031353022207374726f6b653d2200000000000000006020820152600082516157c681603885016020870161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d60389390910192830152507f77696474683d2236222066696c6c3d227472616e73706172656e7422202f3e006058820152607701919050565b60008161582f5761582f614b1a565b506000190190565b7f3c7061746820643d224d20313530203130302043203135352039392c20313635815275101c9c9610189b9810189818111039ba3937b5b29e9160511b60208201526000835161588e81603685016020880161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d603691840191820152683bb4b23a341e911a1160b91b605682015283516158dd81605f84016020880161450b565b6210179f60e91b605f9290910191820152606201949350505050565b7f3c6c696e652078313d22313132222079313d22313030222078323d223236362281527f2079323d22333622207374796c653d227374726f6b653a00000000000000000060208201526000835161595781603785016020880161450b565b6d1db9ba3937b5b296bbb4b23a341d60911b603791840191820152835161598581604584016020880161450b565b71111037b830b1b4ba3c9e9118171c1110179f60711b60459290910191820152605701949350505050565b600084516159c281846020890161450b565b80830190507f3c6c696e652078313d22313630222079313d22313030222078323d223236362281527f2079323d22353622207374796c653d227374726f6b653a00000000000000000060208201528451615a2381603784016020890161450b565b6d1db9ba3937b5b296bbb4b23a341d60911b603792909101918201528351615a5281604584016020880161450b565b71111037b830b1b4ba3c9e9118171c1110179f60711b6045929091019182015260570195945050505050565b701e3837b63cb3b7b7103837b4b73a399e9160791b81528251600090615aab81601185016020880161450b565b6711103334b6361e9160c11b6011918401918201528351615ad381601984016020880161450b565b631110179f60e11b60199290910191820152601d01949350505050565b6c1e32b63634b839b29031bc1e9160991b81528651600090615b1981600d850160208c0161450b565b65111031bc9e9160d11b600d918401918201528751615b3f816013840160208c0161450b565b651110393c1e9160d11b601392909101918201528651615b66816019840160208b0161450b565b651110393c9e9160d11b601992909101918201528551615b8d81601f840160208a0161450b565b6711103334b6361e9160c11b601f92909101918201528451615bb681602784016020890161450b565b614f84615bd9615bd360278486010161011160f51b815260020190565b87614cc3565b61179f60f11b815260020190565b600060ff821660ff84168060ff03821115615c0457615c04614b1a565b01939250505056fe3132392c203136302c203134312c203139302c203133332c203230302c203135302c203235362c203131302c203235362c203132332c203230302c203131352c2031393031363620313630203133382032353620313733203235362031393120323235203137382032313820313932203231303932203136302031363020313630203232302031383020323430203235362031373020323536203835203235362032302032353620333020313830393220313630203136302031363020313830203139302032323020323536203139302032353620313638203232302031373020323536203835203235362038352032323020363620323536203338203235363020323230203830203138302039302031363020313232203235362030203235364142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c7465787420783d223232362220793d2231373522207472616e73666f726d3d22726f7461746528313820302030292220666f6e742d66616d696c793d225461686f6d612c2073616e732d73657269662220666f6e742d73697a653d223134222066696c6c3d2223464644373030223e26233132373438323b26233132373438303b3c2f746578743e323536203234302031373620313830203136362031363020313338203235362032353620323536393020313630203132322032353620383320323536203635203232352037382032313820363420323130a2646970667358221220265a3b17db23bdd11919155598a99529d162dc098df495c9a3c2531d506e99e864736f6c634300080b00334f6e436861696e446f6e616c64206973206120636f6c6c656374696f6e206f66203230323420756e6971756520446f6e616c64732e2054686520617274776f726b20616e64206d65746164617461206172652066756c6c79206f6e2d636861696e2c20696e20612073696e676c6520636f6e74726163742e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000006000000000000000000000000eefbdae2b62f9a1639bcba81a7e76e84b2c6813b000000000000000000000000236ff0657e76e11ad981d08c358638de8ad778d60000000000000000000000001d42949af932ad94022d5546239616c9c6de06760000000000000000000000007d81af7a1c7d04aae4f1a4819865528017f1664b000000000000000000000000440bd23858e50918895171f24d4e142e5a1abe390000000000000000000000000c97e7502bc647e5aaeca08d569ee78475c9b8180000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001

Deployed Bytecode

0x6080604052600436106102555760003560e01c8063715018a611610139578063c19d93fb116100b6578063d52079b41161007a578063d52079b41461075b578063d79779b214610772578063e33b7de3146107a8578063e985e9c5146107bd578063f2fde38b14610806578063f83d08ba1461082657600080fd5b8063c19d93fb146106b9578063c2ca0ac5146106cf578063c87b56dd146106ef578063cce132d11461070f578063ce7c2ac21461072557600080fd5b80639852595c116100fd5780639852595c146105e65780639b19251a1461061c5780639ebd36f31461064c578063a22cb46514610679578063b88d4fde1461069957600080fd5b8063715018a61461056b578063868ff4a2146105805780638b83209b146105935780638da5cb5b146105b357806395d89b41146105d157600080fd5b80633a98ef39116101d25780634dfc1abc116101965780634dfc1abc146104c35780634f6ccce7146104e35780636352211e1461050357806364f101f01461052357806367f68fac1461053857806370a082311461054b57600080fd5b80633a98ef3914610408578063406072a91461041d57806342842e0e1461046357806348b75044146104835780634952603d146104a357600080fd5b80631916558711610219578063191655871461037357806323b872dd146103935780632be09561146103b35780632bf04304146103c85780632f745c59146103e857600080fd5b806301ffc9a7146102a357806306fdde03146102d8578063081812fc146102fa578063095ea7b31461033257806318160ddd1461035457600080fd5b3661029e577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b3480156102af57600080fd5b506102c36102be3660046144ee565b61083b565b60405190151581526020015b60405180910390f35b3480156102e457600080fd5b506102ed61084c565b6040516102cf9190614563565b34801561030657600080fd5b5061031a610315366004614576565b6108de565b6040516001600160a01b0390911681526020016102cf565b34801561033e57600080fd5b5061035261034d3660046145a4565b610978565b005b34801561036057600080fd5b506008545b6040519081526020016102cf565b34801561037f57600080fd5b5061035261038e3660046145d0565b610a8e565b34801561039f57600080fd5b506103526103ae3660046145ed565b610bbc565b3480156103bf57600080fd5b50610352610bed565b3480156103d457600080fd5b506103526103e336600461469f565b610c2b565b3480156103f457600080fd5b506103656104033660046145a4565b610cdb565b34801561041457600080fd5b50600c54610365565b34801561042957600080fd5b50610365610438366004614751565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b34801561046f57600080fd5b5061035261047e3660046145ed565b610d71565b34801561048f57600080fd5b5061035261049e366004614751565b610d8c565b3480156104af57600080fd5b506102ed6104be3660046147a3565b610f65565b3480156104cf57600080fd5b506103526104de3660046148d7565b610f78565b3480156104ef57600080fd5b506103656104fe366004614576565b610fc5565b34801561050f57600080fd5b5061031a61051e366004614576565b611058565b34801561052f57600080fd5b506103526110cf565b610352610546366004614920565b61110f565b34801561055757600080fd5b506103656105663660046145d0565b611249565b34801561057757600080fd5b506103526112d0565b61035261058e366004614576565b611306565b34801561059f57600080fd5b5061031a6105ae366004614576565b611463565b3480156105bf57600080fd5b50600a546001600160a01b031661031a565b3480156105dd57600080fd5b506102ed611493565b3480156105f257600080fd5b506103656106013660046145d0565b6001600160a01b03166000908152600f602052604090205490565b34801561062857600080fd5b506102c36106373660046145d0565b60156020526000908152604090205460ff1681565b34801561065857600080fd5b5061066c610667366004614576565b6114a2565b6040516102cf9190614945565b34801561068557600080fd5b506103526106943660046149eb565b61155f565b3480156106a557600080fd5b506103526106b4366004614a19565b611624565b3480156106c557600080fd5b5061036560135481565b3480156106db57600080fd5b506103526106ea366004614576565b61165c565b3480156106fb57600080fd5b506102ed61070a366004614576565b6116bd565b34801561071b57600080fd5b506103656107e881565b34801561073157600080fd5b506103656107403660046145d0565b6001600160a01b03166000908152600e602052604090205490565b34801561076757600080fd5b506014546103659081565b34801561077e57600080fd5b5061036561078d3660046145d0565b6001600160a01b031660009081526011602052604090205490565b3480156107b457600080fd5b50600d54610365565b3480156107c957600080fd5b506102c36107d8366004614751565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561081257600080fd5b506103526108213660046145d0565b6116d2565b34801561083257600080fd5b5061035261176d565b6000610846826117ad565b92915050565b60606000805461085b90614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461088790614a99565b80156108d45780601f106108a9576101008083540402835291602001916108d4565b820191906000526020600020905b8154815290600101906020018083116108b757829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661095c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061098382611058565b9050806001600160a01b0316836001600160a01b031614156109f15760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610953565b336001600160a01b0382161480610a0d5750610a0d81336107d8565b610a7f5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610953565b610a8983836117d2565b505050565b6001600160a01b0381166000908152600e6020526040902054610ac35760405162461bcd60e51b815260040161095390614ad4565b6000610ace600d5490565b610ad89047614b30565b90506000610b058383610b00866001600160a01b03166000908152600f602052604090205490565b611840565b905080610b245760405162461bcd60e51b815260040161095390614b48565b6001600160a01b0383166000908152600f602052604081208054839290610b4c908490614b30565b9250508190555080600d6000828254610b659190614b30565b90915550610b7590508382611886565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b610bc6338261199f565b610be25760405162461bcd60e51b815260040161095390614b93565b610a89838383611a95565b600a546001600160a01b03163314610c175760405162461bcd60e51b815260040161095390614be4565b60135415610c2457600080fd5b6001601355565b600a546001600160a01b03163314610c555760405162461bcd60e51b815260040161095390614be4565b6013541580610c6657506001601354145b610c6f57600080fd5b60005b8151811015610cd757600160156000848481518110610c9357610c93614c19565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610ccf81614c2f565b915050610c72565b5050565b6000610ce683611249565b8210610d485760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610953565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610a8983838360405180602001604052806000815250611624565b6001600160a01b0381166000908152600e6020526040902054610dc15760405162461bcd60e51b815260040161095390614ad4565b6001600160a01b0382166000908152601160205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610e1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e429190614c4a565b610e4c9190614b30565b90506000610e858383610b0087876001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b905080610ea45760405162461bcd60e51b815260040161095390614b48565b6001600160a01b03808516600090815260126020908152604080832093871683529290529081208054839290610edb908490614b30565b90915550506001600160a01b03841660009081526011602052604081208054839290610f08908490614b30565b90915550610f199050848483611c40565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6060610f718383611c92565b9392505050565b600a546001600160a01b03163314610fa25760405162461bcd60e51b815260040161095390614be4565b60046013541415610fb257600080fd5b8051610cd79060189060208401906143d3565b6000610fd060085490565b82106110335760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610953565b6008828154811061104657611046614c19565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806108465760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610953565b600a546001600160a01b031633146110f95760405162461bcd60e51b815260040161095390614be4565b60026013541461110857600080fd5b6003601355565b6002600b5414156111625760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610953565b6002600b556013546001148061117a57506002601354145b6111b45760405162461bcd60e51b815260206004820152600b60248201526a135a5b9d0818db1bdcd95960aa1b6044820152606401610953565b6000821180156111c5575060058211155b6111ce57600080fd5b6111f382826111e4576647e82c3a4100006111ed565b669fdf42f6e480005b90611ccd565b3410156112365760405162461bcd60e51b815260206004820152601160248201527014185e5b595b9d081d1bdbc81cdb585b1b607a1b6044820152606401610953565b6112408282611cd9565b50506001600b55565b60006001600160a01b0382166112b45760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610953565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146112fa5760405162461bcd60e51b815260040161095390614be4565b6113046000611db6565b565b6002600b5414156113595760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610953565b6002600b556013546001148061137157506001601354145b61137a57600080fd5b3360009081526015602052604090205460ff166113cb5760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610953565b6000811180156113dc575060028111155b6113e557600080fd5b6113f66647e82c3a41000082611ccd565b3410156114395760405162461bcd60e51b815260206004820152601160248201527014185e5b595b9d081d1bdbc81cdb585b1b607a1b6044820152606401610953565b611444816001611cd9565b50336000908152601560205260409020805460ff191690556001600b55565b60006010828154811061147857611478614c19565b6000918252602090912001546001600160a01b031692915050565b60606001805461085b90614a99565b6114aa614457565b6000828152600260205260409020546001600160a01b03166115265760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610953565b601754600083815260166020526040902054601354610846928592909160ff909116901580159061155a5750600160135414155b611e08565b6001600160a01b0382163314156115b85760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610953565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61162e338361199f565b61164a5760405162461bcd60e51b815260040161095390614b93565b6116568484848461252b565b50505050565b600a546001600160a01b031633146116865760405162461bcd60e51b815260040161095390614be4565b60016013541461169557600080fd5b8061169f57600080fd5b60026013556116b78168201620202024c0fefe614b30565b60175550565b60606108466116cb836114a2565b6000611c92565b600a546001600160a01b031633146116fc5760405162461bcd60e51b815260040161095390614be4565b6001600160a01b0381166117615760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610953565b61176a81611db6565b50565b600a546001600160a01b031633146117975760405162461bcd60e51b815260040161095390614be4565b6003601354146117a657600080fd5b6004601355565b60006001600160e01b0319821663780e9d6360e01b148061084657506108468261255e565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061180782611058565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600c546001600160a01b0384166000908152600e60205260408120549091839161186a9086614c63565b6118749190614c98565b61187e9190614cac565b949350505050565b804710156118d65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610953565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611923576040519150601f19603f3d011682016040523d82523d6000602084013e611928565b606091505b5050905080610a895760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610953565b6000818152600260205260408120546001600160a01b0316611a185760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610953565b6000611a2383611058565b9050806001600160a01b0316846001600160a01b03161480611a5e5750836001600160a01b0316611a53846108de565b6001600160a01b0316145b8061187e57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16949350505050565b826001600160a01b0316611aa882611058565b6001600160a01b031614611b105760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610953565b6001600160a01b038216611b725760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610953565b611b7d8383836125ae565b611b886000826117d2565b6001600160a01b0383166000908152600360205260408120805460019290611bb1908490614cac565b90915550506001600160a01b0382166000908152600360205260408120805460019290611bdf908490614b30565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610a899084906125b9565b6060611ca6611ca1848461268b565b6127eb565b604051602001611cb69190614cdf565b604051602081830303815290604052905092915050565b6000610f718284614c63565b60008211611ce657600080fd5b6107e8611cfc83611cf660145490565b90612951565b1115611d4a5760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742065786365656420746f74616c20737570706c790000000000006044820152606401610953565b60005b82811015610a8957611d63601480546001019055565b6000611d6e60145490565b90506107e88111611da357611d83338261295d565b8215611da3576000818152601660205260409020805460ff191660011790555b5080611dae81614c2f565b915050611d4d565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e10614457565b81611e8357604051806101a0016040528086815260200160001515815260200184151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250905061187e565b6000611efd85876040518060400160405280600481526020016314dd5a5d60e21b815250603f805480602002602001604051908101604052809291908181526020018280548015611ef357602002820191906000526020600020905b815481526020019060010190808311611edf575b5050505050612977565b9050600084611f0e5760475461200d565b61200d86886040518060400160405280600a8152602001695370656369616c69747960b01b8152506046805480602002602001604051908101604052809291908181526020016000905b82821015612004578382906000526020600020018054611f7790614a99565b80601f0160208091040260200160405190810160405280929190818152602001828054611fa390614a99565b8015611ff05780601f10611fc557610100808354040283529160200191611ff0565b820191906000526020600020905b815481529060010190602001808311611fd357829003601f168201915b505050505081526020019060010190611f58565b50505050612a26565b9050604051806101a0016040528088815260200160011515815260200186151581526020016120a8888a604051806040016040528060048152602001634579657360e01b8152506021805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b81526020016121a3888a6040518060400160405280600a81526020016922bc383932b9b9b4b7b760b11b815250601b805480602002602001604051908101604052809291908181526020016000905b8282101561200457838290600052602060002001805461211690614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461214290614a99565b801561218f5780601f106121645761010080835404028352916020019161218f565b820191906000526020600020905b81548152906001019060200180831161217257829003601f168201915b5050505050815260200190600101906120f7565b815260200161221e888a6040518060400160405280600481526020016329b5b4b760e11b8152506029805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001612317888a604051806040016040528060088152602001672637b1b0ba34b7b760c11b8152506019805480602002602001604051908101604052809291908181526020016000905b8282101561200457838290600052602060002001805461228a90614a99565b80601f01602080910402602001604051908101604052809291908181526020018280546122b690614a99565b80156123035780601f106122d857610100808354040283529160200191612303565b820191906000526020600020905b8154815290600101906020018083116122e657829003601f168201915b50505050508152602001906001019061226b565b8152602001612392888a604051806040016040528060048152602001632430b4b960e11b8152506037805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001612486888a6040518060400160405280600381526020016254696560e81b815250603a805480602002602001604051908101604052809291908181526020016000905b828210156120045783829060005260206000200180546123f990614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461242590614a99565b80156124725780601f1061244757610100808354040283529160200191612472565b820191906000526020600020905b81548152906001019060200180831161245557829003601f168201915b5050505050815260200190600101906123da565b8152602001612502888a6040518060400160405280600581526020016409adeeae8d60db1b815250602e805480602002602001604051908101604052809291908181526020018280548015611ef35760200282019190600052602060002090815481526020019060010190808311611edf575050505050612977565b8152602001838152602001612518888a86612a66565b8152602001919091529695505050505050565b612536848484611a95565b61254284848484612ad1565b6116565760405162461bcd60e51b815260040161095390614d24565b60006001600160e01b031982166380ac58cd60e01b148061258f57506001600160e01b03198216635b5e139f60e01b145b8061084657506301ffc9a760e01b6001600160e01b0319831614610846565b610a89838383612bcc565b600061260e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612c849092919063ffffffff16565b805190915015610a89578080602001905181019061262c9190614d76565b610a895760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610953565b606061269683612c93565b83516126a190612d4f565b60186126ac86612e4d565b6127826040518060400160405280600a8152602001695370656369616c69747960b01b8152506046896101800151815481106126ea576126ea614c19565b9060005260206000200180546126ff90614a99565b80601f016020809104026020016040519081016040528092919081815260200182805461272b90614a99565b80156127785780601f1061274d57610100808354040283529160200191612778565b820191906000526020600020905b81548152906001019060200180831161275b57829003601f168201915b5050505050613063565b87604001516127ab57604051806040016040528060028152602001614e6f60f01b8152506127c8565b6040518060400160405280600381526020016259657360e81b8152505b6127d5611ca18a8a613078565b604051602001611cb69796959493929190614e2d565b606081516000141561280b57505060408051602081019091526000815290565b6000604051806060016040528060408152602001615d2e604091399050600060038451600261283a9190614b30565b6128449190614c98565b61284f906004614c63565b9050600061285e826020614b30565b67ffffffffffffffff8111156128765761287661462e565b6040519080825280601f01601f1916602001820160405280156128a0576020820181803683370190505b509050818152600183018586518101602084015b8183101561290c576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f81168501518253506001016128b4565b600389510660018114612926576002811461293757612943565b613d3d60f01b600119830152612943565b603d60f81b6000198301525b509398975050505050505050565b6000610f718284614b30565b610cd78282604051806020016040528060008152506130fa565b6000806103e86129b0878661298b89612d4f565b60405160200161299c929190614f92565b60405160208183030381529060405261312d565b6129ba9190614fc1565b90506000805b600185516129ce9190614cac565b821015612a1b578482815181106129e7576129e7614c19565b6020026020010151816129fa9190614b30565b905080831015612a0957612a1b565b81612a1381614c2f565b9250506129c0565b509695505050505050565b600080612a37868561298b88612d4f565b905060018351612a479190614cac565b612a519082614fc1565b612a5c906001614b30565b9695505050505050565b6000604254821415612a7b5750604454610f71565b60006004612aa886604051806040016040528060038152602001622834b760e91b81525061298b88612d4f565b612ab29190614fc1565b90508060011415612ac7575050604554610f71565b5050604454610f71565b60006001600160a01b0384163b15612bc457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612b15903390899088908890600401614fd5565b6020604051808303816000875af1925050508015612b50575060408051601f3d908101601f19168201909252612b4d91810190615008565b60015b612baa573d808015612b7e576040519150601f19603f3d011682016040523d82523d6000602084013e612b83565b606091505b508051612ba25760405162461bcd60e51b815260040161095390614d24565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061187e565b50600161187e565b6001600160a01b038316612c2757612c2281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612c4a565b816001600160a01b0316836001600160a01b031614612c4a57612c4a8382613162565b6001600160a01b038216612c6157610a89816131ff565b826001600160a01b0316826001600160a01b031614610a8957610a8982826132ae565b606061187e84846000856132f2565b60608160200151158015612ca8575081604001515b15612cd1575050604080518082019091526008815267029b832b1b4b0b6160c51b602082015290565b81602001518015612ce9575060475482610180015114155b15612d3657604682610180015181548110612d0657612d06614c19565b90600052602060002001604051602001612d209190615025565b6040516020818303038152906040529050919050565b505060408051602081019091526000815290565b919050565b606081612d735750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612d9d5780612d8781614c2f565b9150612d969050600a83614c98565b9150612d77565b60008167ffffffffffffffff811115612db857612db861462e565b6040519080825280601f01601f191660200182016040528015612de2576020820181803683370190505b5090505b841561187e57612df7600183614cac565b9150612e04600a86614fc1565b612e0f906030614b30565b60f81b818381518110612e2457612e24614c19565b60200101906001600160f81b031916908160001a905350612e46600a86614c98565b9450612de6565b6060612e86604051806040016040528060048152602001634579657360e01b81525060208460600151815481106126ea576126ea614c19565b612ec36040518060400160405280600a81526020016922bc383932b9b9b4b7b760b11b815250601b8560800151815481106126ea576126ea614c19565b612efa6040518060400160405280600481526020016329b5b4b760e11b81525060288660a00151815481106126ea576126ea614c19565b612f35604051806040016040528060088152602001672637b1b0ba34b7b760c11b81525060198760c00151815481106126ea576126ea614c19565b612f6c604051806040016040528060048152602001632430b4b960e11b81525060368860e00151815481106126ea576126ea614c19565b612fa36040518060400160405280600381526020016254696560e81b815250603a896101000151815481106126ea576126ea614c19565b612fdc6040518060400160405280600581526020016409adeeae8d60db1b815250602d8a6101200151815481106126ea576126ea614c19565b6130146040518060400160405280600481526020016314dd5a5d60e21b815250603e8b6101400151815481106126ea576126ea614c19565b61304b604051806040016040528060038152602001622834b760e91b81525060438c6101600151815481106126ea576126ea614c19565b604051602001612d2099989796959493929190615042565b60608282604051602001611cb6929190615103565b60606130838361341a565b61308d84846134f5565b613096856135cd565b61309f8661378a565b6130a88761393a565b6130b188613c2d565b6130e4896130df602c8c60a00151815481106130cf576130cf614c19565b9060005260206000200154613cec565b613da7565b604051602001611cb69796959493929190615178565b61310483836141b7565b6131116000848484612ad1565b610a895760405162461bcd60e51b815260040161095390614d24565b60008160405160200161314091906152a1565b60408051601f198184030181529190528051602090910120610f719084614b30565b6000600161316f84611249565b6131799190614cac565b6000838152600760205260409020549091508082146131cc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061321190600190614cac565b6000838152600960205260408120546008805493945090928490811061323957613239614c19565b90600052602060002001549050806008838154811061325a5761325a614c19565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613292576132926152bd565b6001900381819060005260206000200160009055905550505050565b60006132b983611249565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6060824710156133535760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610953565b843b6133a15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610953565b600080866001600160a01b031685876040516133bd91906152a1565b60006040518083038185875af1925050503d80600081146133fa576040519150601f19603f3d011682016040523d82523d6000602084013e6133ff565b606091505b509150915061340f828286614305565b979650505050505050565b60606000603c5483610100015114613451576040518060400160405280600781526020016611b3333333333360c91b815250613472565b604051806040016040528060078152602001660236530313031360cc1b8152505b90506000603c54846101000151146134b75760405180604001604052806015815260200174039ba3937b5b296b7b830b1b4ba3c9e9118171b911605d1b8152506134c8565b604051806020016040528060008152505b905081816040516020016134dd9291906152d3565b60405160208183030381529060405292505050919050565b606060008360c00151600361350a9190614c63565b905060008361353a576040518060400160405280600981526020016875726c28236772312960b81b815250613558565b604051806040016040528060048152602001636e6f6e6560e01b8152505b9050613570601a83815481106130cf576130cf614c19565b613590601a613580856001614b30565b815481106130cf576130cf614c19565b6135a0601a613580866002614b30565b836040516020016135b494939291906153eb565b6040516020818303038152906040529250505092915050565b6060600082610100015190506000836101400151905060006135fb603d84815481106130cf576130cf614c19565b9050600061360b62ffffff613cec565b9050600061361b62eaeaea613cec565b90506000604051806080016040528060528152602001615cbb60529139905060006040518060600160405280603b8152602001615c80603b913990506000604051806080016040528060448152602001615c0d60449139905061368e60425488106136865782613688565b835b8561433e565b6136c6604051806040016040528060168152602001753133302031363020313035203231302039302031363560501b8152508761433e565b6137056040518060400160405280601781526020017f31323620313630203135312032313020313636203136350000000000000000008152508861433e565b61370f848a61433e565b603b548c101561372e5760405180602001604052806000815250613758565b613758856040518060400160405280600881526020016775726c282370312960c01b81525061433e565b60405160200161376c95949392919061557f565b60405160208183030381529060405298505050505050505050919050565b6060600082610140015190506000836101600151905060006137b8604084815481106130cf576130cf614c19565b905060006137d2604185815481106130cf576130cf614c19565b905060425484106137f25760405180602001604052806000815250613814565b613814604051806060016040528060218152602001615d0d602191398361433e565b60425485106138325760405180602001604052806000815250613854565b613854604051806060016040528060278152602001615df7602791398461433e565b60425486106138725760405180602001604052806000815250613894565b6138946040518060600160405280602a8152602001615e1e602a91398461433e565b60425487106138b257604051806020016040528060008152506138d4565b6138d46040518060600160405280602f8152602001615c51602f91398561433e565b60455487146138f2576040518060200160405280600081525061390c565b6040518060c0016040528060898152602001615d6e608991395b60405160200161392095949392919061557f565b604051602081830303815290604052945050505050919050565b606060008260a001519050600083610120015190506000613967602a84815481106130cf576130cf614c19565b90506000613981602b85815481106130cf576130cf614c19565b9050600061399b602c86815481106130cf576130cf614c19565b604080516020810190915260008152602f5491925090851415613a40576139d96087609c601060088660405180602001604052806000815250614353565b613a196087609c600c60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b604051602001613a2a929190614f92565b6040516020818303038152906040529050613bbc565b603054851415613a7257613a6b6087609c601060048660405180602001604052806000815250614353565b9050613bbc565b603154851415613b2f57613a9d6087609c601260098660405180602001604052806000815250614353565b613add60876095600b60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b613b1d608760a3600b60026040518060400160405280600781526020016611b3333333333360c91b81525060405180602001604052806000815250614353565b604051602001613a2a939291906155ea565b603254851415613b5957613a6b6087609c6008808660405180602001604052806000815250614353565b603354851415613b745781604051602001613a2a919061562d565b603454851415613b8f5781604051602001613a2a91906156e5565b603554851415613bbc5781604051602001613baa9190615768565b60405160208183030381529060405290505b613bdd6082606c603c604b8860405180602001604052806000815250614353565b613bfe608a607c6008600c8860405180602001604052806000815250614353565b82604051602001613c11939291906155ea565b6040516020818303038152906040529650505050505050919050565b606060008260e0015190506000613c50603883815481106130cf576130cf614c19565b9050603954821415613c7357505060408051602081019091526000815292915050565b613c94608c6037604060188560405180602001604052806000815250614353565b613cdb6055604660106026866040518060400160405280601a81526020017f7472616e73666f726d3d22726f74617465283130203020302922000000000000815250614353565b6040516020016134dd929190614f92565b60408051600780825281830190925260609160009190602082018180368337019050509050600f60065b8015613d6f57613d2c8262ffffff1686166143ab565b60f81b838281518110613d4157613d41614c19565b60200101906001600160f81b031916908160001a90535060049490941c93613d6881615820565b9050613d16565b602360f81b83600081518110613d8757613d87614c19565b60200101906001600160f81b031916908160001a90535091949350505050565b6060600083606001519050600060278281548110613dc757613dc7614c19565b6000918252602080832090820401546080880151601f9092166101000a900460ff16925090600c90600590600490819060079087613e1a57613e1560268a815481106130cf576130cf614c19565b613e3b565b6040518060400160405280600781526020016611b3333333333360c91b8152505b905060008190506000613e5a60268c815481106130cf576130cf614c19565b604080516020808201835260008083528351808301855281815284519283019094528152601e5493945090928c1415613eb057613e9860028b614cac565b995088613ea481615820565b99505060049650613f74565b601d548c1415613f34578c613ec55784613ec7565b8f5b6022548f14613ee55760405180602001604052806000815250613f0d565b6040518060400160405280600e81526020016d1037b830b1b4ba3c9e9118171a9160911b8152505b604051602001613f1e929190615837565b6040516020818303038152906040529050613f74565b601f548c1415613f7457613f4960048c614cac565b9a5089613f5581614c2f565b9a50613f649050600588614b30565b965087613f7081614c2f565b9850505b6023548e148015613f875750601e548c14155b15613fa85788613f9681614c2f565b9950508780613fa490614c2f565b9850505b601f548c148015613fba57506023548e145b15613fdb578a613fc981614c2f565b9b50508980613fd790614c2f565b9a50505b8c1561407257613ff1607060648a8c8887614353565b601d548d14156140105760405180602001604052806000815250614020565b61402060a060648b8d8988614353565b604051602001614031929190614f92565b60408051601f19818403018152828201825260078084526611b3333333333360c91b6020858101829052845180860190955291845290830152919750955092505b6024548e141561408f5761408862ff0000613cec565b955061414f565b6025548e14156141175786156140cc57856140a988612d4f565b6040516020016140ba9291906158f9565b60405160208183030381529060405292505b6000871180156140de5750601d548c14155b156141125782866140ee89612d4f565b604051602001614100939291906159b0565b60405160208183030381529060405292505b61414f565b6022548e141561414f57604051806040016040528060128152602001713334b63616b7b830b1b4ba3c9e9118171a9160711b81525091505b61415f607060648d8d8a87614353565b601d548d141561416f578161417f565b61417f60a060648e8e8a88614353565b84604051602001614192939291906155ea565b6040516020818303038152906040529e50505050505050505050505050505092915050565b6001600160a01b03821661420d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610953565b6000818152600260205260409020546001600160a01b0316156142725760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610953565b61427e600083836125ae565b6001600160a01b03821660009081526003602052604081208054600192906142a7908490614b30565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608315614314575081610f71565b8251156143245782518084602001fd5b8160405162461bcd60e51b81526004016109539190614563565b60608282604051602001611cb6929190615a7e565b606061435e87612d4f565b61436787612d4f565b61437087612d4f565b61437987612d4f565b868660405160200161439096959493929190615af0565b60405160208183030381529060405290509695505050505050565b600060098260ff16116143c8576143c3826030615be7565b610846565b610846826057615be7565b8280546143df90614a99565b90600052602060002090601f0160209004810192826144015760008555614447565b82601f1061441a57805160ff1916838001178555614447565b82800160010185558215614447579182015b8281111561444757825182559160200191906001019061442c565b506144539291506144c3565b5090565b604051806101a0016040528060008152602001600015158152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b8082111561445357600081556001016144c4565b6001600160e01b03198116811461176a57600080fd5b60006020828403121561450057600080fd5b8135610f71816144d8565b60005b8381101561452657818101518382015260200161450e565b838111156116565750506000910152565b6000815180845261454f81602086016020860161450b565b601f01601f19169290920160200192915050565b602081526000610f716020830184614537565b60006020828403121561458857600080fd5b5035919050565b6001600160a01b038116811461176a57600080fd5b600080604083850312156145b757600080fd5b82356145c28161458f565b946020939093013593505050565b6000602082840312156145e257600080fd5b8135610f718161458f565b60008060006060848603121561460257600080fd5b833561460d8161458f565b9250602084013561461d8161458f565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff811182821017156146685761466861462e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156146975761469761462e565b604052919050565b600060208083850312156146b257600080fd5b823567ffffffffffffffff808211156146ca57600080fd5b818501915085601f8301126146de57600080fd5b8135818111156146f0576146f061462e565b8060051b915061470184830161466e565b818152918301840191848101908884111561471b57600080fd5b938501935b8385101561474557843592506147358361458f565b8282529385019390850190614720565b98975050505050505050565b6000806040838503121561476457600080fd5b823561476f8161458f565b9150602083013561477f8161458f565b809150509250929050565b801515811461176a57600080fd5b8035612d4a8161478a565b6000808284036101c08112156147b857600080fd5b6101a0808212156147c857600080fd5b6147d0614644565b9150843582526147e260208601614798565b60208301526147f360408601614798565b6040830152606085013560608301526080850135608083015260a085013560a083015260c085013560c083015260e085013560e0830152610100808601358184015250610120808601358184015250610140808601358184015250610160808601358184015250610180808601358184015250819350614874818601614798565b925050509250929050565b600067ffffffffffffffff8311156148995761489961462e565b6148ac601f8401601f191660200161466e565b90508281528383830111156148c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156148e957600080fd5b813567ffffffffffffffff81111561490057600080fd5b8201601f8101841361491157600080fd5b61187e8482356020840161487f565b6000806040838503121561493357600080fd5b82359150602083013561477f8161478a565b815181526020808301516101a08301916149629084018215159052565b506040830151614976604084018215159052565b50606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525061016080840151818401525061018080840151818401525092915050565b600080604083850312156149fe57600080fd5b8235614a098161458f565b9150602083013561477f8161478a565b60008060008060808587031215614a2f57600080fd5b8435614a3a8161458f565b93506020850135614a4a8161458f565b925060408501359150606085013567ffffffffffffffff811115614a6d57600080fd5b8501601f81018713614a7e57600080fd5b614a8d8782356020840161487f565b91505092959194509250565b600181811c90821680614aad57607f821691505b60208210811415614ace57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614b4357614b43614b1a565b500190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614c4357614c43614b1a565b5060010190565b600060208284031215614c5c57600080fd5b5051919050565b6000816000190483118215151615614c7d57614c7d614b1a565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ca757614ca7614c82565b500490565b600082821015614cbe57614cbe614b1a565b500390565b60008151614cd581856020860161450b565b9290920192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614d1781601d85016020870161450b565b91909101601d0192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600060208284031215614d8857600080fd5b8151610f718161478a565b8054600090600181811c9080831680614dad57607f831692505b6020808410821415614dcf57634e487b7160e01b600052602260045260246000fd5b818015614de35760018114614df457614e21565b60ff19861689528489019650614e21565b60008881526020902060005b86811015614e195781548b820152908501908301614e00565b505084890196505b50505050505092915050565b683d913730b6b2911d1160b91b81528751600090614e52816009850160208d0161450b565b67446f6e616c64202360c01b6009918401918201528851614e7a816011840160208d0161450b565b701116113232b9b1b934b83a34b7b7111d1160791b60119290910191820152614ea66022820189614d93565b6f222c2261747472696275746573223a5b60801b81528751909150614ed2816010840160208b0161450b565b8651910190614ee8816010840160208a0161450b565b7f7b2274726169745f74797065223a20225370656369616c222c202276616c75656010929091019182015263111d101160e11b6030820152614f84614f76614f70614f366034850189614cc3565b7f227d5d2c22696d616765223a2022646174613a696d6167652f7376672b786d6c8152670ed8985cd94d8d0b60c21b602082015260280190565b86614cc3565b61227d60f01b815260020190565b9a9950505050505050505050565b60008351614fa481846020880161450b565b835190830190614fb881836020880161450b565b01949350505050565b600082614fd057614fd0614c82565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612a5c90830184614537565b60006020828403121561501a57600080fd5b8151610f71816144d8565b60006150318284614d93565b600160fd1b81526001019392505050565b60008a51615054818460208f0161450b565b8a516150668183860160208f0161450b565b8a51918401019061507b818360208e0161450b565b895161508d8183850160208e0161450b565b89519290910101906150a3818360208c0161450b565b87516150b58183850160208c0161450b565b87519290910101906150cb818360208a0161450b565b85516150dd8183850160208a0161450b565b85519290910101906150f381836020880161450b565b019b9a5050505050505050505050565b6f3d913a3930b4ba2fba3cb832911d101160811b8152825160009061512f81601085016020880161450b565b6c111610113b30b63ab2911d101160991b601091840191820152835161515c81601d84016020880161450b565b62089f4b60ea1b601d9290910191820152602001949350505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32308152600060207f30302f73766722207072657365727665617370656374726174696f3d22784d69818401527f64594d6964206d656574222076696577426f783d223020302032353620323536604084015261111f60f11b606084015260628a5161520881838701858f0161450b565b8a519085019061521d81848401868f0161450b565b8a5191019061523181848401868e0161450b565b895191019061524581848401868d0161450b565b885191019061525981848401868c0161450b565b875191019061526d81848401868b0161450b565b61529061527e848385010189614cc3565b651e17b9bb339f60d11b815260060190565b9d9c50505050505050505050505050565b600082516152b381846020870161450b565b9190910192915050565b634e487b7160e01b600052603160045260246000fd5b7f3c7061747465726e2069643d22703122207061747465726e556e6974733d227581527f73657253706163654f6e557365222077696474683d223822206865696768743d60208201527f223822207061747465726e5472616e73666f726d3d22726f74617465282d353560408201527f29223e3c6c696e652078313d22302220793d2230222078323d2230222079323d60608201526c111998111039ba3937b5b29e9160991b60808201526000835161539381608d85016020880161450b565b61011160f51b608d9184019182015283516153b581608f84016020880161450b565b7f7374726f6b652d77696474683d223622202f3e3c2f7061747465726e3e000000608f929091019182015260ac01949350505050565b7f3c6c696e6561724772616469656e742069643d22677231222078313d2230222081527f78323d2230222079313d2230222079323d2231223e3c73746f70206f666673656020820152723a1e911812911039ba37b816b1b7b637b91e9160691b604082015260008551615465816053850160208a0161450b565b7f222f3e3c73746f70206f66667365743d22343025222073746f702d636f6c6f72605391840191820152611e9160f11b6073820181905286516154af816075850160208b0161450b565b7f222f3e3c73746f70206f66667365743d22383025222073746f702d636f6c6f7260759390910192830152609582015284516154f281609784016020890161450b565b7f222f3e3c2f6c696e6561724772616469656e743e3c7265637420783d22302220609792909101918201527f793d2230222072783d2230222072793d2230222077696474683d22323536222060b7820152723432b4b3b43a1e91191a9b11103334b6361e9160691b60d782015261340f61556f60ea830186614cc3565b631110179f60e11b815260040190565b60008651615591818460208b0161450b565b8651908301906155a5818360208b0161450b565b86519101906155b8818360208a0161450b565b85519101906155cb81836020890161450b565b84519101906155de81836020880161450b565b01979650505050505050565b600084516155fc81846020890161450b565b84519083019061561081836020890161450b565b845191019061562381836020880161450b565b0195945050505050565b7f3c7061746820643d224d2031323120313536204320313236203135332c20313481527f37203135322c203135312031353522207374726f6b653d22000000000000000060208201526000825161568b81603885016020870161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d60389390910192830152507f77696474683d2234222066696c6c3d227472616e73706172656e7422202f3e006058820152607701919050565b7f3c656c6c697073652063783d2233222063793d22323036222072783d2231312281526d10393c9e911b91103334b6361e9160911b60208201526000825161573481602e85016020870161450b565b7f22207472616e73666f726d3d22726f74617465282d3430203020302922202f3e602e939091019283015250604e01919050565b7f3c7061746820643d224d2031313020313530204320313138203135352c20313581527f34203135352c203136322031353022207374726f6b653d2200000000000000006020820152600082516157c681603885016020870161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d60389390910192830152507f77696474683d2236222066696c6c3d227472616e73706172656e7422202f3e006058820152607701919050565b60008161582f5761582f614b1a565b506000190190565b7f3c7061746820643d224d20313530203130302043203135352039392c20313635815275101c9c9610189b9810189818111039ba3937b5b29e9160511b60208201526000835161588e81603685016020880161450b565b7f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d603691840191820152683bb4b23a341e911a1160b91b605682015283516158dd81605f84016020880161450b565b6210179f60e91b605f9290910191820152606201949350505050565b7f3c6c696e652078313d22313132222079313d22313030222078323d223236362281527f2079323d22333622207374796c653d227374726f6b653a00000000000000000060208201526000835161595781603785016020880161450b565b6d1db9ba3937b5b296bbb4b23a341d60911b603791840191820152835161598581604584016020880161450b565b71111037b830b1b4ba3c9e9118171c1110179f60711b60459290910191820152605701949350505050565b600084516159c281846020890161450b565b80830190507f3c6c696e652078313d22313630222079313d22313030222078323d223236362281527f2079323d22353622207374796c653d227374726f6b653a00000000000000000060208201528451615a2381603784016020890161450b565b6d1db9ba3937b5b296bbb4b23a341d60911b603792909101918201528351615a5281604584016020880161450b565b71111037b830b1b4ba3c9e9118171c1110179f60711b6045929091019182015260570195945050505050565b701e3837b63cb3b7b7103837b4b73a399e9160791b81528251600090615aab81601185016020880161450b565b6711103334b6361e9160c11b6011918401918201528351615ad381601984016020880161450b565b631110179f60e11b60199290910191820152601d01949350505050565b6c1e32b63634b839b29031bc1e9160991b81528651600090615b1981600d850160208c0161450b565b65111031bc9e9160d11b600d918401918201528751615b3f816013840160208c0161450b565b651110393c1e9160d11b601392909101918201528651615b66816019840160208b0161450b565b651110393c9e9160d11b601992909101918201528551615b8d81601f840160208a0161450b565b6711103334b6361e9160c11b601f92909101918201528451615bb681602784016020890161450b565b614f84615bd9615bd360278486010161011160f51b815260020190565b87614cc3565b61179f60f11b815260020190565b600060ff821660ff84168060ff03821115615c0457615c04614b1a565b01939250505056fe3132392c203136302c203134312c203139302c203133332c203230302c203135302c203235362c203131302c203235362c203132332c203230302c203131352c2031393031363620313630203133382032353620313733203235362031393120323235203137382032313820313932203231303932203136302031363020313630203232302031383020323430203235362031373020323536203835203235362032302032353620333020313830393220313630203136302031363020313830203139302032323020323536203139302032353620313638203232302031373020323536203835203235362038352032323020363620323536203338203235363020323230203830203138302039302031363020313232203235362030203235364142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c7465787420783d223232362220793d2231373522207472616e73666f726d3d22726f7461746528313820302030292220666f6e742d66616d696c793d225461686f6d612c2073616e732d73657269662220666f6e742d73697a653d223134222066696c6c3d2223464644373030223e26233132373438323b26233132373438303b3c2f746578743e323536203234302031373620313830203136362031363020313338203235362032353620323536393020313630203132322032353620383320323536203635203232352037382032313820363420323130a2646970667358221220265a3b17db23bdd11919155598a99529d162dc098df495c9a3c2531d506e99e864736f6c634300080b0033

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000006000000000000000000000000eefbdae2b62f9a1639bcba81a7e76e84b2c6813b000000000000000000000000236ff0657e76e11ad981d08c358638de8ad778d60000000000000000000000001d42949af932ad94022d5546239616c9c6de06760000000000000000000000007d81af7a1c7d04aae4f1a4819865528017f1664b000000000000000000000000440bd23858e50918895171f24d4e142e5a1abe390000000000000000000000000c97e7502bc647e5aaeca08d569ee78475c9b8180000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001

-----Decoded View---------------
Arg [0] : _payees (address[]): 0xeeFbdAe2b62F9A1639bCBa81A7E76e84B2C6813B,0x236ff0657E76e11aD981d08c358638DE8AD778d6,0x1d42949Af932ad94022D5546239616c9C6DE0676,0x7d81af7a1c7d04AaE4F1a4819865528017F1664B,0x440BD23858e50918895171F24D4e142E5A1Abe39,0x0C97e7502BC647E5aAEcA08D569Ee78475c9b818
Arg [1] : _shares (uint256[]): 5,1,1,1,1,1

-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [3] : 000000000000000000000000eefbdae2b62f9a1639bcba81a7e76e84b2c6813b
Arg [4] : 000000000000000000000000236ff0657e76e11ad981d08c358638de8ad778d6
Arg [5] : 0000000000000000000000001d42949af932ad94022d5546239616c9c6de0676
Arg [6] : 0000000000000000000000007d81af7a1c7d04aae4f1a4819865528017f1664b
Arg [7] : 000000000000000000000000440bd23858e50918895171f24d4e142e5a1abe39
Arg [8] : 0000000000000000000000000c97e7502bc647e5aaeca08d569ee78475c9b818
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000001


Deployed Bytecode Sourcemap

75558:37068:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71159:40;21178:10;71159:40;;;-1:-1:-1;;;;;206:32:1;;;188:51;;71189:9:0;270:2:1;255:18;;248:34;161:18;71159:40:0;;;;;;;75558:37068;;;;;112411:212;;;;;;;;;;-1:-1:-1;112411:212:0;;;;;:::i;:::-;;:::i;:::-;;;940:14:1;;933:22;915:41;;903:2;888:18;112411:212:0;;;;;;;;42959:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44518:221::-;;;;;;;;;;-1:-1:-1;44518:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2089:32:1;;;2071:51;;2059:2;2044:18;44518:221:0;1925:203:1;44041:411:0;;;;;;;;;;-1:-1:-1;44041:411:0;;;;;:::i;:::-;;:::i;:::-;;55672:113;;;;;;;;;;-1:-1:-1;55760:10:0;:17;55672:113;;;2735:25:1;;;2723:2;2708:18;55672:113:0;2589:177:1;72945:566:0;;;;;;;;;;-1:-1:-1;72945:566:0;;;;;:::i;:::-;;:::i;45408:339::-;;;;;;;;;;-1:-1:-1;45408:339:0;;;;;:::i;:::-;;:::i;87603:121::-;;;;;;;;;;;;;:::i;87328:267::-;;;;;;;;;;-1:-1:-1;87328:267:0;;;;;:::i;:::-;;:::i;55340:256::-;;;;;;;;;;-1:-1:-1;55340:256:0;;;;;:::i;:::-;;:::i;71290:91::-;;;;;;;;;;-1:-1:-1;71361:12:0;;71290:91;;72419:135;;;;;;;;;;-1:-1:-1;72419:135:0;;;;;:::i;:::-;-1:-1:-1;;;;;72516:21:0;;;72489:7;72516:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;72419:135;45818:185;;;;;;;;;;-1:-1:-1;45818:185:0;;;;;:::i;:::-;;:::i;73779:641::-;;;;;;;;;;-1:-1:-1;73779:641:0;;;;;:::i;:::-;;:::i;111933:179::-;;;;;;;;;;-1:-1:-1;111933:179:0;;;;;:::i;:::-;;:::i;88224:152::-;;;;;;;;;;-1:-1:-1;88224:152:0;;;;;:::i;:::-;;:::i;55862:233::-;;;;;;;;;;-1:-1:-1;55862:233:0;;;;;:::i;:::-;;:::i;42653:239::-;;;;;;;;;;-1:-1:-1;42653:239:0;;;;;:::i;:::-;;:::i;87959:132::-;;;;;;;;;;;;;:::i;86315:523::-;;;;;;:::i;:::-;;:::i;42383:208::-;;;;;;;;;;-1:-1:-1;42383:208:0;;;;;:::i;:::-;;:::i;22928:94::-;;;;;;;;;;;;;:::i;86846:474::-;;;;;;:::i;:::-;;:::i;72645:100::-;;;;;;;;;;-1:-1:-1;72645:100:0;;;;;:::i;:::-;;:::i;22277:87::-;;;;;;;;;;-1:-1:-1;22350:6:0;;-1:-1:-1;;;;;22350:6:0;22277:87;;43128:104;;;;;;;;;;;;;:::i;72141:109::-;;;;;;;;;;-1:-1:-1;72141:109:0;;;;;:::i;:::-;-1:-1:-1;;;;;72224:18:0;72197:7;72224:18;;;:9;:18;;;;;;;72141:109;76402:42;;;;;;;;;;-1:-1:-1;76402:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;109522:402;;;;;;;;;;-1:-1:-1;109522:402:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;44811:295::-;;;;;;;;;;-1:-1:-1;44811:295:0;;;;;:::i;:::-;;:::i;46074:328::-;;;;;;;;;;-1:-1:-1;46074:328:0;;;;;:::i;:::-;;:::i;75776:20::-;;;;;;;;;;;;;;;;87732:219;;;;;;;;;;-1:-1:-1;87732:219:0;;;;;:::i;:::-;;:::i;109932:202::-;;;;;;;;;;-1:-1:-1;109932:202:0;;;;;:::i;:::-;;:::i;76115:40::-;;;;;;;;;;;;76151:4;76115:40;;71937:105;;;;;;;;;;-1:-1:-1;71937:105:0;;;;;:::i;:::-;-1:-1:-1;;;;;72018:16:0;71991:7;72018:16;;;:7;:16;;;;;;;71937:105;76075:33;;;;;;;;;;-1:-1:-1;76075:33:0;;;;;;71727:119;;;;;;;;;;-1:-1:-1;71727:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;71812:26:0;71785:7;71812:26;;;:19;:26;;;;;;;71727:119;71475:95;;;;;;;;;;-1:-1:-1;71548:14:0;;71475:95;;45177:164;;;;;;;;;;-1:-1:-1;45177:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;45298:25:0;;;45274:4;45298:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;45177:164;23177:192;;;;;;;;;;-1:-1:-1;23177:192:0;;;;;:::i;:::-;;:::i;88099:117::-;;;;;;;;;;;;;:::i;112411:212::-;112550:4;112579:36;112603:11;112579:23;:36::i;:::-;112572:43;112411:212;-1:-1:-1;;112411:212:0:o;42959:100::-;43013:13;43046:5;43039:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42959:100;:::o;44518:221::-;44594:7;48001:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48001:16:0;44614:73;;;;-1:-1:-1;;;44614:73:0;;12257:2:1;44614:73:0;;;12239:21:1;12296:2;12276:18;;;12269:30;12335:34;12315:18;;;12308:62;-1:-1:-1;;;12386:18:1;;;12379:42;12438:19;;44614:73:0;;;;;;;;;-1:-1:-1;44707:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44707:24:0;;44518:221::o;44041:411::-;44122:13;44138:23;44153:7;44138:14;:23::i;:::-;44122:39;;44186:5;-1:-1:-1;;;;;44180:11:0;:2;-1:-1:-1;;;;;44180:11:0;;;44172:57;;;;-1:-1:-1;;;44172:57:0;;12670:2:1;44172:57:0;;;12652:21:1;12709:2;12689:18;;;12682:30;12748:34;12728:18;;;12721:62;-1:-1:-1;;;12799:18:1;;;12792:31;12840:19;;44172:57:0;12468:397:1;44172:57:0;21178:10;-1:-1:-1;;;;;44264:21:0;;;;:62;;-1:-1:-1;44289:37:0;44306:5;21178:10;45177:164;:::i;44289:37::-;44242:168;;;;-1:-1:-1;;;44242:168:0;;13072:2:1;44242:168:0;;;13054:21:1;13111:2;13091:18;;;13084:30;13150:34;13130:18;;;13123:62;13221:26;13201:18;;;13194:54;13265:19;;44242:168:0;12870:420:1;44242:168:0;44423:21;44432:2;44436:7;44423:8;:21::i;:::-;44111:341;44041:411;;:::o;72945:566::-;-1:-1:-1;;;;;73021:16:0;;73040:1;73021:16;;;:7;:16;;;;;;73013:71;;;;-1:-1:-1;;;73013:71:0;;;;;;;:::i;:::-;73097:21;73145:15;71548:14;;;71475:95;73145:15;73121:39;;:21;:39;:::i;:::-;73097:63;;73171:15;73189:58;73205:7;73214:13;73229:17;73238:7;-1:-1:-1;;;;;72224:18:0;72197:7;72224:18;;;:9;:18;;;;;;;72141:109;73229:17;73189:15;:58::i;:::-;73171:76;-1:-1:-1;73268:12:0;73260:68;;;;-1:-1:-1;;;73260:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;73341:18:0;;;;;;:9;:18;;;;;:29;;73363:7;;73341:18;:29;;73363:7;;73341:29;:::i;:::-;;;;;;;;73399:7;73381:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;73419:35:0;;-1:-1:-1;73437:7:0;73446;73419:17;:35::i;:::-;73470:33;;;-1:-1:-1;;;;;206:32:1;;188:51;;270:2;255:18;;248:34;;;73470:33:0;;161:18:1;73470:33:0;;;;;;;73002:509;;72945:566;:::o;45408:339::-;45603:41;21178:10;45636:7;45603:18;:41::i;:::-;45595:103;;;;-1:-1:-1;;;45595:103:0;;;;;;;:::i;:::-;45711:28;45721:4;45727:2;45731:7;45711:9;:28::i;87603:121::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;87662:5:::1;::::0;:19;87654:28:::1;;;::::0;::::1;;75892:1;87695:5;:21:::0;87603:121::o;87328:267::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;87423:5:::1;::::0;:19;;:45:::1;;;75892:1;87446:5;;:22;87423:45;87415:54;;;::::0;::::1;;87487:9;87482:106;87506:10;:17;87502:1;:21;87482:106;;;87572:4;87545:9;:24;87555:10;87566:1;87555:13;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;87545:24:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;87545:24:0;:31;;-1:-1:-1;;87545:31:0::1;::::0;::::1;;::::0;;;::::1;::::0;;87525:3;::::1;::::0;::::1;:::i;:::-;;;;87482:106;;;;87328:267:::0;:::o;55340:256::-;55437:7;55473:23;55490:5;55473:16;:23::i;:::-;55465:5;:31;55457:87;;;;-1:-1:-1;;;55457:87:0;;15919:2:1;55457:87:0;;;15901:21:1;15958:2;15938:18;;;15931:30;15997:34;15977:18;;;15970:62;-1:-1:-1;;;16048:18:1;;;16041:41;16099:19;;55457:87:0;15717:407:1;55457:87:0;-1:-1:-1;;;;;;55562:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;55340:256::o;45818:185::-;45956:39;45973:4;45979:2;45983:7;45956:39;;;;;;;;;;;;:16;:39::i;73779:641::-;-1:-1:-1;;;;;73861:16:0;;73880:1;73861:16;;;:7;:16;;;;;;73853:71;;;;-1:-1:-1;;;73853:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;71812:26:0;;73937:21;71812:26;;;:19;:26;;;;;;73961:30;;-1:-1:-1;;;73961:30:0;;73985:4;73961:30;;;2071:51:1;-1:-1:-1;;;;;73961:15:0;;;;;2044:18:1;;73961:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;73937:77;;74025:15;74043:65;74059:7;74068:13;74083:24;74092:5;74099:7;-1:-1:-1;;;;;72516:21:0;;;72489:7;72516:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;72419:135;74043:65;74025:83;-1:-1:-1;74129:12:0;74121:68;;;;-1:-1:-1;;;74121:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;74202:21:0;;;;;;;:14;:21;;;;;;;;:30;;;;;;;;;;;:41;;74236:7;;74202:21;:41;;74236:7;;74202:41;:::i;:::-;;;;-1:-1:-1;;;;;;;74254:26:0;;;;;;:19;:26;;;;;:37;;74284:7;;74254:26;:37;;74284:7;;74254:37;:::i;:::-;;;;-1:-1:-1;74304:47:0;;-1:-1:-1;74327:5:0;74334:7;74343;74304:22;:47::i;:::-;74367:45;;;-1:-1:-1;;;;;206:32:1;;;188:51;;270:2;255:18;;248:34;;;74367:45:0;;;;;161:18:1;74367:45:0;;;;;;;73842:578;;73779:641;;:::o;111933:179::-;112033:13;112071:33;112087:3;112092:11;112071:15;:33::i;:::-;112064:40;111933:179;-1:-1:-1;;;111933:179:0:o;88224:152::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;76049:1:::1;88307:5;;:21;;88299:30;;;::::0;::::1;;88342:26:::0;;::::1;::::0;:11:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;55862:233::-:0;55937:7;55973:30;55760:10;:17;;55672:113;55973:30;55965:5;:38;55957:95;;;;-1:-1:-1;;;55957:95:0;;16520:2:1;55957:95:0;;;16502:21:1;16559:2;16539:18;;;16532:30;16598:34;16578:18;;;16571:62;-1:-1:-1;;;16649:18:1;;;16642:42;16701:19;;55957:95:0;16318:408:1;55957:95:0;56070:10;56081:5;56070:17;;;;;;;;:::i;:::-;;;;;;;;;56063:24;;55862:233;;;:::o;42653:239::-;42725:7;42761:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42761:16:0;42796:19;42788:73;;;;-1:-1:-1;;;42788:73:0;;16933:2:1;42788:73:0;;;16915:21:1;16972:2;16952:18;;;16945:30;17011:34;16991:18;;;16984:62;-1:-1:-1;;;17062:18:1;;;17055:39;17111:19;;42788:73:0;16731:405:1;87959:132:0;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;75951:1:::1;88018:5;;:31;88010:40;;;::::0;::::1;;76000:1;88063:5;:20:::0;87959:132::o;86315:523::-;9213:1;9811:7;;:19;;9803:63;;;;-1:-1:-1;;;9803:63:0;;17343:2:1;9803:63:0;;;17325:21:1;17382:2;17362:18;;;17355:30;17421:33;17401:18;;;17394:61;17472:18;;9803:63:0;17141:355:1;9803:63:0;9213:1;9944:7;:18;86458:5:::1;::::0;75892:1:::1;86458:22;::::0;:57:::1;;;75951:1;86484:5;;:31;86458:57;86436:118;;;::::0;-1:-1:-1;;;86436:118:0;;17703:2:1;86436:118:0::1;::::0;::::1;17685:21:1::0;17742:2;17722:18;;;17715:30;-1:-1:-1;;;17761:18:1;;;17754:41;17812:18;;86436:118:0::1;17501:335:1::0;86436:118:0::1;86585:1;86573:9;:13;:46;;;;;76207:1;86590:9;:29;;86573:46;86565:55;;;::::0;::::1;;86683:59;86732:9;86684:8;:42;;76254:13;86684:42;;;76321:11;86684:42;86683:48:::0;::::1;:59::i;:::-;86653:9;:89;;86631:156;;;::::0;-1:-1:-1;;;86631:156:0;;18043:2:1;86631:156:0::1;::::0;::::1;18025:21:1::0;18082:2;18062:18;;;18055:30;-1:-1:-1;;;18101:18:1;;;18094:47;18158:18;;86631:156:0::1;17841:341:1::0;86631:156:0::1;86800:30;86810:9;86821:8;86800:9;:30::i;:::-;-1:-1:-1::0;;9169:1:0;10123:7;:22;86315:523::o;42383:208::-;42455:7;-1:-1:-1;;;;;42483:19:0;;42475:74;;;;-1:-1:-1;;;42475:74:0;;18389:2:1;42475:74:0;;;18371:21:1;18428:2;18408:18;;;18401:30;18467:34;18447:18;;;18440:62;-1:-1:-1;;;18518:18:1;;;18511:40;18568:19;;42475:74:0;18187:406:1;42475:74:0;-1:-1:-1;;;;;;42567:16:0;;;;;:9;:16;;;;;;;42383:208::o;22928:94::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;22993:21:::1;23011:1;22993:9;:21::i;:::-;22928:94::o:0;86846:474::-;9213:1;9811:7;;:19;;9803:63;;;;-1:-1:-1;;;9803:63:0;;17343:2:1;9803:63:0;;;17325:21:1;17382:2;17362:18;;;17355:30;17421:33;17401:18;;;17394:61;17472:18;;9803:63:0;17141:355:1;9803:63:0;9213:1;9944:7;:18;86969:5:::1;::::0;75892:1:::1;86969:22;::::0;:48:::1;;;75892:1;86995:5;;:22;86969:48;86961:57;;;::::0;::::1;;87047:10;87037:21;::::0;;;:9:::1;:21;::::0;;;;;::::1;;87029:49;;;::::0;-1:-1:-1;;;87029:49:0;;18800:2:1;87029:49:0::1;::::0;::::1;18782:21:1::0;18839:2;18819:18;;;18812:30;-1:-1:-1;;;18858:18:1;;;18851:45;18913:18;;87029:49:0::1;18598:339:1::0;87029:49:0::1;87109:1;87097:9;:13;:56;;;;;76394:1;87114:9;:39;;87097:56;87089:65;;;::::0;::::1;;87186:25;76254:13;87201:9:::0;87186:14:::1;:25::i;:::-;87173:9;:38;;87165:68;;;::::0;-1:-1:-1;;;87165:68:0;;18043:2:1;87165:68:0::1;::::0;::::1;18025:21:1::0;18082:2;18062:18;;;18055:30;-1:-1:-1;;;18101:18:1;;;18094:47;18158:18;;87165:68:0::1;17841:341:1::0;87165:68:0::1;87246:26;87256:9;87267:4;87246:9;:26::i;:::-;-1:-1:-1::0;87293:10:0::1;87307:5;87283:21:::0;;;:9:::1;:21;::::0;;;;:29;;-1:-1:-1;;87283:29:0::1;::::0;;;10123:7;:22;86846:474::o;72645:100::-;72696:7;72723;72731:5;72723:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;72723:14:0;;72645:100;-1:-1:-1;;72645:100:0:o;43128:104::-;43184:13;43217:7;43210:14;;;;;:::i;109522:402::-;109575:10;;:::i;:::-;47977:4;48001:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48001:16:0;109598:113;;;;-1:-1:-1;;;109598:113:0;;19144:2:1;109598:113:0;;;19126:21:1;19183:2;19163:18;;;19156:30;19222:34;19202:18;;;19195:62;-1:-1:-1;;;19273:18:1;;;19266:45;19328:19;;109598:113:0;18942:411:1;109598:113:0;109798:4;;109821:16;;;;:7;:16;;;;;;109856:5;;109744:172;;109772:7;;109798:4;;109821:16;;;;;109856:19;;;;:45;;;75892:1;109879:5;;:22;;109856:45;109744:9;:172::i;44811:295::-;-1:-1:-1;;;;;44914:24:0;;21178:10;44914:24;;44906:62;;;;-1:-1:-1;;;44906:62:0;;19560:2:1;44906:62:0;;;19542:21:1;19599:2;19579:18;;;19572:30;19638:27;19618:18;;;19611:55;19683:18;;44906:62:0;19358:349:1;44906:62:0;21178:10;44981:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;44981:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;44981:53:0;;;;;;;;;;45050:48;;915:41:1;;;44981:42:0;;21178:10;45050:48;;888:18:1;45050:48:0;;;;;;;44811:295;;:::o;46074:328::-;46249:41;21178:10;46282:7;46249:18;:41::i;:::-;46241:103;;;;-1:-1:-1;;;46241:103:0;;;;;;;:::i;:::-;46355:39;46369:4;46375:2;46379:7;46388:5;46355:13;:39::i;:::-;46074:328;;;;:::o;87732:219::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;75892:1:::1;87801:5;;:22;87793:31;;;::::0;::::1;;87843:10:::0;87835:19:::1;;;::::0;::::1;;75951:1;87867:5;:30:::0;87915:28:::1;:5:::0;87923:20:::1;87915:28;:::i;:::-;87908:4;:35:::0;-1:-1:-1;87732:219:0:o;109932:202::-;110050:13;110088:38;110104:14;110110:7;110104:5;:14::i;:::-;110120:5;110088:15;:38::i;23177:192::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;23266:22:0;::::1;23258:73;;;::::0;-1:-1:-1;;;23258:73:0;;19914:2:1;23258:73:0::1;::::0;::::1;19896:21:1::0;19953:2;19933:18;;;19926:30;19992:34;19972:18;;;19965:62;-1:-1:-1;;;20043:18:1;;;20036:36;20089:19;;23258:73:0::1;19712:402:1::0;23258:73:0::1;23342:19;23352:8;23342:9;:19::i;:::-;23177:192:::0;:::o;88099:117::-;22350:6;;-1:-1:-1;;;;;22350:6:0;21178:10;22497:23;22489:68;;;;-1:-1:-1;;;22489:68:0;;;;;;;:::i;:::-;76000:1:::1;88153:5;;:21;88145:30;;;::::0;::::1;;76049:1;88188:5;:20:::0;88099:117::o;55032:224::-;55134:4;-1:-1:-1;;;;;;55158:50:0;;-1:-1:-1;;;55158:50:0;;:90;;;55212:36;55236:11;55212:23;:36::i;51894:174::-;51969:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;51969:29:0;-1:-1:-1;;;;;51969:29:0;;;;;;;;:24;;52023:23;51969:24;52023:14;:23::i;:::-;-1:-1:-1;;;;;52014:46:0;;;;;;;;;;;51894:174;;:::o;74598:248::-;74808:12;;-1:-1:-1;;;;;74788:16:0;;74744:7;74788:16;;;:7;:16;;;;;;74744:7;;74823:15;;74772:32;;:13;:32;:::i;:::-;74771:49;;;;:::i;:::-;:67;;;;:::i;:::-;74764:74;74598:248;-1:-1:-1;;;;74598:248:0:o;25614:317::-;25729:6;25704:21;:31;;25696:73;;;;-1:-1:-1;;;25696:73:0;;20881:2:1;25696:73:0;;;20863:21:1;20920:2;20900:18;;;20893:30;20959:31;20939:18;;;20932:59;21008:18;;25696:73:0;20679:353:1;25696:73:0;25783:12;25801:9;-1:-1:-1;;;;;25801:14:0;25823:6;25801:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25782:52;;;25853:7;25845:78;;;;-1:-1:-1;;;25845:78:0;;21449:2:1;25845:78:0;;;21431:21:1;21488:2;21468:18;;;21461:30;21527:34;21507:18;;;21500:62;21598:28;21578:18;;;21571:56;21644:19;;25845:78:0;21247:422:1;48206:348:0;48299:4;48001:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48001:16:0;48316:73;;;;-1:-1:-1;;;48316:73:0;;21876:2:1;48316:73:0;;;21858:21:1;21915:2;21895:18;;;21888:30;21954:34;21934:18;;;21927:62;-1:-1:-1;;;22005:18:1;;;21998:42;22057:19;;48316:73:0;21674:408:1;48316:73:0;48400:13;48416:23;48431:7;48416:14;:23::i;:::-;48400:39;;48469:5;-1:-1:-1;;;;;48458:16:0;:7;-1:-1:-1;;;;;48458:16:0;;:51;;;;48502:7;-1:-1:-1;;;;;48478:31:0;:20;48490:7;48478:11;:20::i;:::-;-1:-1:-1;;;;;48478:31:0;;48458:51;:87;;;-1:-1:-1;;;;;;45298:25:0;;;45274:4;45298:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;48450:96;48206:348;-1:-1:-1;;;;48206:348:0:o;51198:578::-;51357:4;-1:-1:-1;;;;;51330:31:0;:23;51345:7;51330:14;:23::i;:::-;-1:-1:-1;;;;;51330:31:0;;51322:85;;;;-1:-1:-1;;;51322:85:0;;22289:2:1;51322:85:0;;;22271:21:1;22328:2;22308:18;;;22301:30;22367:34;22347:18;;;22340:62;-1:-1:-1;;;22418:18:1;;;22411:39;22467:19;;51322:85:0;22087:405:1;51322:85:0;-1:-1:-1;;;;;51426:16:0;;51418:65;;;;-1:-1:-1;;;51418:65:0;;22699:2:1;51418:65:0;;;22681:21:1;22738:2;22718:18;;;22711:30;22777:34;22757:18;;;22750:62;-1:-1:-1;;;22828:18:1;;;22821:34;22872:19;;51418:65:0;22497:400:1;51418:65:0;51496:39;51517:4;51523:2;51527:7;51496:20;:39::i;:::-;51600:29;51617:1;51621:7;51600:8;:29::i;:::-;-1:-1:-1;;;;;51642:15:0;;;;;;:9;:15;;;;;:20;;51661:1;;51642:15;:20;;51661:1;;51642:20;:::i;:::-;;;;-1:-1:-1;;;;;;;51673:13:0;;;;;;:9;:13;;;;;:18;;51690:1;;51673:13;:18;;51690:1;;51673:18;:::i;:::-;;;;-1:-1:-1;;51702:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51702:21:0;-1:-1:-1;;;;;51702:21:0;;;;;;;;;51741:27;;51702:16;;51741:27;;;;;;;51198:578;;;:::o;64652:211::-;64796:58;;;-1:-1:-1;;;;;206:32:1;;64796:58:0;;;188:51:1;255:18;;;;248:34;;;64796:58:0;;;;;;;;;;161:18:1;;;;64796:58:0;;;;;;;;-1:-1:-1;;;;;64796:58:0;-1:-1:-1;;;64796:58:0;;;64769:86;;64789:5;;64769:19;:86::i;111557:368::-;111666:13;111835:48;111855:26;111864:3;111869:11;111855:8;:26::i;:::-;111835:13;:48::i;:::-;111742:160;;;;;;;;:::i;:::-;;;;;;;;;;;;;111697:220;;111557:368;;;;:::o;15038:98::-;15096:7;15123:5;15127:1;15123;:5;:::i;85706:601::-;85798:1;85786:9;:13;85778:22;;;;;;76151:4;85833:34;85857:9;85833:19;:9;11038:14;;10946:114;85833:19;:23;;:34::i;:::-;:47;;85811:123;;;;-1:-1:-1;;;85811:123:0;;23747:2:1;85811:123:0;;;23729:21:1;23786:2;23766:18;;;23759:30;23825:28;23805:18;;;23798:56;23871:18;;85811:123:0;23545:350:1;85811:123:0;85952:9;85947:353;85971:9;85967:1;:13;85947:353;;;86002:21;:9;11157:19;;11175:1;11157:19;;;11068:127;86002:21;86038:17;86058:19;:9;11038:14;;10946:114;86058:19;86038:39;;76151:4;86098:9;:22;86094:195;;86141:32;86151:10;86163:9;86141;:32::i;:::-;86196:8;86192:82;;;86229:18;;;;:7;:18;;;;;:25;;-1:-1:-1;;86229:25:0;86250:4;86229:25;;;86192:82;-1:-1:-1;85982:3:0;;;;:::i;:::-;;;;85947:353;;23377:173;23452:6;;;-1:-1:-1;;;;;23469:17:0;;;-1:-1:-1;;;;;;23469:17:0;;;;;;;23502:40;;23452:6;;;23469:17;23452:6;;23502:40;;23433:16;;23502:40;23422:128;23377:173;:::o;107616:1898::-;107765:10;;:::i;:::-;107792:18;107788:118;;107834:60;;;;;;;;107838:8;107834:60;;;;107848:5;107834:60;;;;;;107855:8;107834:60;;;;;;107865:1;107834:60;;;;107868:1;107834:60;;;;107871:1;107834:60;;;;107874:1;107834:60;;;;107877:1;107834:60;;;;107880:1;107834:60;;;;107883:1;107834:60;;;;107886:1;107834:60;;;;107889:1;107834:60;;;;107892:1;107834:60;;;107827:67;;;;107788:118;107918:12;107933:128;107961:5;107981:8;108004:19;;;;;;;;;;;;;-1:-1:-1;;;108004:19:0;;;108038:12;107933:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:128::i;:::-;107918:143;;108072:18;108093:8;:207;;108279:21;;108093:207;;;108117:146;108141:5;108165:8;108192:25;;;;;;;;;;;;;-1:-1:-1;;;108192:25:0;;;108236:12;108117:146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:5;:146::i;:::-;108072:228;;108333:1173;;;;;;;;108365:8;108333:1173;;;;108438:4;108333:1173;;;;;;108401:8;108333:1173;;;;;;108467:64;108481:5;108488:8;108498:19;;;;;;;;;;;;;-1:-1:-1;;;108498:19:0;;;108519:11;108467:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:64::i;:::-;108333:1173;;;;108562:165;108590:5;108618:8;108649:25;;;;;;;;;;;;;-1:-1:-1;;;108649:25:0;;;108697:11;108562:165;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108333:1173;;;;108752:65;108766:5;108773:8;108783:19;;;;;;;;;;;;;-1:-1:-1;;;108783:19:0;;;108804:12;108752:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:65::i;:::-;108333:1173;;;;108846:161;108874:5;108902:8;108933:23;;;;;;;;;;;;;-1:-1:-1;;;108933:23:0;;;108979:9;108846:161;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108333:1173;;;;109032:65;109046:5;109053:8;109063:19;;;;;;;;;;;;;-1:-1:-1;;;109063:19:0;;;109084:12;109032:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:65::i;:::-;108333:1173;;;;109121:48;109127:5;109134:8;109144:18;;;;;;;;;;;;;-1:-1:-1;;;109144:18:0;;;109164:4;109121:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108333:1173;;;;109195:170;109231:5;109259:8;109290:20;;;;;;;;;;;;;-1:-1:-1;;;109290:20:0;;;109333:13;109195:170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:170::i;:::-;108333:1173;;;;109390:4;108333:1173;;;;109418:31;109427:5;109434:8;109444:4;109418:8;:31::i;:::-;108333:1173;;;;;;;;;107616:1898;-1:-1:-1;;;;;;107616:1898:0:o;47284:315::-;47441:28;47451:4;47457:2;47461:7;47441:9;:28::i;:::-;47488:48;47511:4;47517:2;47521:7;47530:5;47488:22;:48::i;:::-;47480:111;;;;-1:-1:-1;;;47480:111:0;;;;;;;:::i;42014:305::-;42116:4;-1:-1:-1;;;;;;42153:40:0;;-1:-1:-1;;;42153:40:0;;:105;;-1:-1:-1;;;;;;;42210:48:0;;-1:-1:-1;;;42210:48:0;42153:105;:158;;;-1:-1:-1;;;;;;;;;;34246:40:0;;;42275:36;34137:157;112188:215;112350:45;112377:4;112383:2;112387:7;112350:26;:45::i;67225:716::-;67649:23;67675:69;67703:4;67675:69;;;;;;;;;;;;;;;;;67683:5;-1:-1:-1;;;;;67675:27:0;;;:69;;;;;:::i;:::-;67759:17;;67649:95;;-1:-1:-1;67759:21:0;67755:179;;67856:10;67845:30;;;;;;;;;;;;:::i;:::-;67837:85;;;;-1:-1:-1;;;67837:85:0;;24771:2:1;67837:85:0;;;24753:21:1;24810:2;24790:18;;;24783:30;24849:34;24829:18;;;24822:62;-1:-1:-1;;;24900:18:1;;;24893:40;24950:19;;67837:85:0;24569:406:1;110522:1027:0;110624:13;110773:15;110784:3;110773:10;:15::i;:::-;110861:11;;110844:29;;:16;:29::i;:::-;110938:11;111013:27;111036:3;111013:22;:27::i;:::-;111063:147;111107:25;;;;;;;;;;;;;-1:-1:-1;;;111107:25:0;;;111159:12;111172:3;:14;;;111159:28;;;;;;;;:::i;:::-;;;;;;;;111063:147;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:17;:147::i;:::-;111295:3;:11;;;:26;;;;;;;;;;;;;;;-1:-1:-1;;;111295:26:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;111295:26:0;;;;111434:46;111454:24;111461:3;111466:11;111454:6;:24::i;111434:46::-;110700:826;;;;;;;;;;;;;;:::i;3264:1912::-;3322:13;3352:4;:11;3367:1;3352:16;3348:31;;;-1:-1:-1;;3370:9:0;;;;;;;;;-1:-1:-1;3370:9:0;;;3264:1912::o;3348:31::-;3431:19;3453:12;;;;;;;;;;;;;;;;;3431:34;;3517:18;3563:1;3544:4;:11;3558:1;3544:15;;;;:::i;:::-;3543:21;;;;:::i;:::-;3538:27;;:1;:27;:::i;:::-;3517:48;-1:-1:-1;3648:20:0;3682:15;3517:48;3695:2;3682:15;:::i;:::-;3671:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3671:27:0;;3648:50;;3795:10;3787:6;3780:26;3890:1;3883:5;3879:13;3949:4;4000;3994:11;3985:7;3981:25;4096:2;4088:6;4084:15;4169:754;4188:6;4179:7;4176:19;4169:754;;;4288:1;4279:7;4275:15;4264:26;;4327:7;4321:14;4453:4;4445:5;4441:2;4437:14;4433:25;4423:8;4419:40;4413:47;4402:9;4394:67;4507:1;4496:9;4492:17;4479:30;;4586:4;4578:5;4574:2;4570:14;4566:25;4556:8;4552:40;4546:47;4535:9;4527:67;4640:1;4629:9;4625:17;4612:30;;4719:4;4711:5;4708:1;4703:14;4699:25;4689:8;4685:40;4679:47;4668:9;4660:67;4773:1;4762:9;4758:17;4745:30;;4852:4;4844:5;4832:25;4822:8;4818:40;4812:47;4801:9;4793:67;-1:-1:-1;4906:1:0;4891:17;4169:754;;;4996:1;4989:4;4983:11;4979:19;5017:1;5012:54;;;;5085:1;5080:52;;;;4972:160;;5012:54;-1:-1:-1;;;;;5028:17:0;;5021:43;5012:54;;5080:52;-1:-1:-1;;;;;5096:17:0;;5089:41;4972:160;-1:-1:-1;5162:6:0;;3264:1912;-1:-1:-1;;;;;;;;3264:1912:0:o;14300:98::-;14358:7;14385:5;14389:1;14385;:5;:::i;48896:110::-;48972:26;48982:2;48986:7;48972:26;;;;;;;;;;;;:9;:26::i;88970:562::-;89145:7;89167:12;89299:4;89182:114;89203:5;89247:9;89258:25;89275:7;89258:16;:25::i;:::-;89230:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;89182:6;:114::i;:::-;:121;;;;:::i;:::-;89167:136;;89316:9;89340:11;89368:136;89400:1;89379:11;:18;:22;;;;:::i;:::-;89375:1;:26;89368:136;;;89425:11;89437:1;89425:14;;;;;;;;:::i;:::-;;;;;;;89418:21;;;;;:::i;:::-;;;89464:3;89457:4;:10;89454:20;;;89469:5;;89454:20;89489:3;;;;:::i;:::-;;;;89368:136;;;-1:-1:-1;89523:1:0;88970:562;-1:-1:-1;;;;;;88970:562:0:o;88584:378::-;88750:7;88770:12;88785:114;88806:5;88850:9;88861:25;88878:7;88861:16;:25::i;88785:114::-;88770:129;;88947:1;88926:11;:18;:22;;;;:::i;:::-;88918:31;;:4;:31;:::i;:::-;88917:37;;88953:1;88917:37;:::i;:::-;88910:44;88584:378;-1:-1:-1;;;;;;88584:378:0:o;107068:540::-;107189:7;107221:15;;107213:4;:23;107209:77;;;-1:-1:-1;107260:14:0;;107253:21;;107209:77;107298:11;107470:1;107312:155;107333:5;107395:18;;;;;;;;;;;;;-1:-1:-1;;;107395:18:0;;;107415:25;107432:7;107415:16;:25::i;107312:155::-;:159;;;;:::i;:::-;107298:173;;107486:3;107493:1;107486:8;107482:119;;;-1:-1:-1;;107518:17:0;;107511:24;;107482:119;-1:-1:-1;;107575:14:0;;107568:21;;52633:799;52788:4;-1:-1:-1;;;;;52809:13:0;;24615:20;24663:8;52805:620;;52845:72;;-1:-1:-1;;;52845:72:0;;-1:-1:-1;;;;;52845:36:0;;;;;:72;;21178:10;;52896:4;;52902:7;;52911:5;;52845:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52845:72:0;;;;;;;;-1:-1:-1;;52845:72:0;;;;;;;;;;;;:::i;:::-;;;52841:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53087:13:0;;53083:272;;53130:60;;-1:-1:-1;;;53130:60:0;;;;;;;:::i;53083:272::-;53305:6;53299:13;53290:6;53286:2;53282:15;53275:38;52841:529;-1:-1:-1;;;;;;52968:51:0;-1:-1:-1;;;52968:51:0;;-1:-1:-1;52961:58:0;;52805:620;-1:-1:-1;53409:4:0;53402:11;;56708:589;-1:-1:-1;;;;;56914:18:0;;56910:187;;56949:40;56981:7;58124:10;:17;;58097:24;;;;:15;:24;;;;;:44;;;58152:24;;;;;;;;;;;;58020:164;56949:40;56910:187;;;57019:2;-1:-1:-1;;;;;57011:10:0;:4;-1:-1:-1;;;;;57011:10:0;;57007:90;;57038:47;57071:4;57077:7;57038:32;:47::i;:::-;-1:-1:-1;;;;;57111:16:0;;57107:183;;57144:45;57181:7;57144:36;:45::i;57107:183::-;57217:4;-1:-1:-1;;;;;57211:10:0;:2;-1:-1:-1;;;;;57211:10:0;;57207:83;;57238:40;57266:2;57270:7;57238:27;:40::i;27098:229::-;27235:12;27267:52;27289:6;27297:4;27303:1;27306:12;27267:21;:52::i;110142:372::-;110201:13;110232:3;:12;;;110231:13;:28;;;;;110248:3;:11;;;110231:28;110227:280;;;-1:-1:-1;;110276:17:0;;;;;;;;;;;;-1:-1:-1;;;110276:17:0;;;;;110142:372::o;110227:280::-;110315:3;:12;;;:55;;;;;110349:21;;110331:3;:14;;;:39;;110315:55;110311:196;;;110418:12;110431:3;:14;;;110418:28;;;;;;;;:::i;:::-;;;;;;;;110401:51;;;;;;;;:::i;:::-;;;;;;;;;;;;;110387:66;;110142:372;;;:::o;110311:196::-;-1:-1:-1;;110486:9:0;;;;;;;;;-1:-1:-1;110486:9:0;;;110142:372::o;110311:196::-;110142:372;;;:::o;18745:723::-;18801:13;19022:10;19018:53;;-1:-1:-1;;19049:10:0;;;;;;;;;;;;-1:-1:-1;;;19049:10:0;;;;;18745:723::o;19018:53::-;19096:5;19081:12;19137:78;19144:9;;19137:78;;19170:8;;;;:::i;:::-;;-1:-1:-1;19193:10:0;;-1:-1:-1;19201:2:0;19193:10;;:::i;:::-;;;19137:78;;;19225:19;19257:6;19247:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19247:17:0;;19225:39;;19275:154;19282:10;;19275:154;;19309:11;19319:1;19309:11;;:::i;:::-;;-1:-1:-1;19378:10:0;19386:2;19378:5;:10;:::i;:::-;19365:24;;:2;:24;:::i;:::-;19352:39;;19335:6;19342;19335:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;19335:56:0;;;;;;;;-1:-1:-1;19406:11:0;19415:2;19406:11;;:::i;:::-;;;19275:154;;105955:1105;106052:13;106167:54;106185:19;;;;;;;;;;;;;-1:-1:-1;;;106185:19:0;;;106206:4;106211:3;:8;;;106206:14;;;;;;;;:::i;106167:54::-;106244:146;106288:25;;;;;;;;;;;;;-1:-1:-1;;;106288:25:0;;;106340:11;106352:3;:14;;;106340:27;;;;;;;;:::i;106244:146::-;106413:55;106431:19;;;;;;;;;;;;;-1:-1:-1;;;106431:19:0;;;106452:5;106458:3;:8;;;106452:15;;;;;;;;:::i;106413:55::-;106491:140;106535:23;;;;;;;;;;;;;-1:-1:-1;;;106535:23:0;;;106585:9;106595:3;:12;;;106585:23;;;;;;;;:::i;106491:140::-;106654:55;106672:19;;;;;;;;;;;;;-1:-1:-1;;;106672:19:0;;;106693:5;106699:3;:8;;;106693:15;;;;;;;;:::i;106654:55::-;106732:52;106750:18;;;;;;;;;;;;;-1:-1:-1;;;106750:18:0;;;106770:4;106775:3;:7;;;106770:13;;;;;;;;:::i;106732:52::-;106807:58;106825:20;;;;;;;;;;;;;-1:-1:-1;;;106825:20:0;;;106847:6;106854:3;:9;;;106847:17;;;;;;;;:::i;106807:58::-;106888:55;106906:19;;;;;;;;;;;;;-1:-1:-1;;;106906:19:0;;;106927:5;106933:3;:8;;;106927:15;;;;;;;;:::i;106888:55::-;106966:52;106984:18;;;;;;;;;;;;;-1:-1:-1;;;106984:18:0;;;107004:4;107009:3;:7;;;107004:13;;;;;;;;:::i;106966:52::-;106128:909;;;;;;;;;;;;;;;;:::i;105534:413::-;105651:13;105807:4;105872:5;105727:197;;;;;;;;;:::i;104837:689::-;104909:13;105142:15;105153:3;105142:10;:15::i;:::-;105180:32;105195:3;105200:11;105180:14;:32::i;:::-;105235:22;105253:3;105235:17;:22::i;:::-;105280:15;105291:3;105280:10;:15::i;:::-;105318;105329:3;105318:10;:15::i;:::-;105356;105367:3;105356:10;:15::i;:::-;105394:59;105405:3;105410:42;105427:14;105442:3;:8;;;105427:24;;;;;;;;:::i;:::-;;;;;;;;;105410:16;:42::i;:::-;105394:10;:59::i;:::-;104980:523;;;;;;;;;;;;;;:::i;49233:321::-;49363:18;49369:2;49373:7;49363:5;:18::i;:::-;49414:54;49445:1;49449:2;49453:7;49462:5;49414:22;:54::i;:::-;49392:154;;;;-1:-1:-1;;;49392:154:0;;;;;;;:::i;88384:192::-;88485:7;88560:5;88543:23;;;;;;;;:::i;:::-;;;;-1:-1:-1;;88543:23:0;;;;;;;;;88533:34;;88543:23;88533:34;;;;88517:51;;:5;:51;:::i;58811:988::-;59077:22;59127:1;59102:22;59119:4;59102:16;:22::i;:::-;:26;;;;:::i;:::-;59139:18;59160:26;;;:17;:26;;;;;;59077:51;;-1:-1:-1;59293:28:0;;;59289:328;;-1:-1:-1;;;;;59360:18:0;;59338:19;59360:18;;;:12;:18;;;;;;;;:34;;;;;;;;;59411:30;;;;;;:44;;;59528:30;;:17;:30;;;;;:43;;;59289:328;-1:-1:-1;59713:26:0;;;;:17;:26;;;;;;;;59706:33;;;-1:-1:-1;;;;;59757:18:0;;;;;:12;:18;;;;;:34;;;;;;;59750:41;58811:988::o;60094:1079::-;60372:10;:17;60347:22;;60372:21;;60392:1;;60372:21;:::i;:::-;60404:18;60425:24;;;:15;:24;;;;;;60798:10;:26;;60347:46;;-1:-1:-1;60425:24:0;;60347:46;;60798:26;;;;;;:::i;:::-;;;;;;;;;60776:48;;60862:11;60837:10;60848;60837:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;60942:28;;;:15;:28;;;;;;;:41;;;61114:24;;;;;61107:31;61149:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;60165:1008;;;60094:1079;:::o;57598:221::-;57683:14;57700:20;57717:2;57700:16;:20::i;:::-;-1:-1:-1;;;;;57731:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;57776:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;57598:221:0:o;28218:510::-;28388:12;28446:5;28421:21;:30;;28413:81;;;;-1:-1:-1;;;28413:81:0;;35897:2:1;28413:81:0;;;35879:21:1;35936:2;35916:18;;;35909:30;35975:34;35955:18;;;35948:62;-1:-1:-1;;;36026:18:1;;;36019:36;36072:19;;28413:81:0;35695:402:1;28413:81:0;24615:20;;28505:60;;;;-1:-1:-1;;;28505:60:0;;36304:2:1;28505:60:0;;;36286:21:1;36343:2;36323:18;;;36316:30;36382:31;36362:18;;;36355:59;36431:18;;28505:60:0;36102:353:1;28505:60:0;28579:12;28593:23;28620:6;-1:-1:-1;;;;;28620:11:0;28639:5;28646:4;28620:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28578:73;;;;28669:51;28686:7;28695:10;28707:12;28669:16;:51::i;:::-;28662:58;28218:510;-1:-1:-1;;;;;;;28218:510:0:o;104060:769::-;104118:13;104144:20;104179:17;;104168:3;:7;;;:28;104167:82;;104238:11;;;;;;;;;;;;;-1:-1:-1;;;104238:11:0;;;104167:82;;;;;;;;;;;;;;;;-1:-1:-1;;;104167:82:0;;;;104144:105;;104260:27;104302:17;;104291:3;:7;;;:28;104290:87;;;;;;;;;;;;;;;-1:-1:-1;;;104290:87:0;;;;;;;;;;;;;;;;;;;104260:117;;104664:6;104720:13;104435:371;;;;;;;;;:::i;:::-;;;;;;;;;;;;;104390:431;;;;104060:769;;;:::o;103030:1022::-;103137:13;103168;103184:3;:12;;;103199:1;103184:16;;;;:::i;:::-;103168:32;;103211:18;103232:11;:34;;;;;;;;;;;;;;;-1:-1:-1;;;103232:34:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;103232:34:0;;;;103211:55;;103503:39;103520:14;103535:5;103520:21;;;;;;;;:::i;103503:39::-;103648:43;103665:14;103680:9;:5;103688:1;103680:9;:::i;:::-;103665:25;;;;;;;;:::i;103648:43::-;103797;103814:14;103829:9;:5;103837:1;103829:9;:::i;103797:43::-;103998:4;103332:697;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103287:757;;;;103030:1022;;;;:::o;93055:1501::-;93147:13;93178:16;93197:3;:7;;;93178:26;;93215:17;93235:3;:8;;;93215:28;;93254:22;93279:37;93296:9;93306:8;93296:19;;;;;;;;:::i;93279:37::-;93254:62;;93327:30;93360:26;93377:8;93360:16;:26::i;:::-;93327:59;;93397:28;93428:26;93445:8;93428:16;:26::i;:::-;93397:57;;93465:40;:127;;;;;;;;;;;;;;;;;;;93603:43;:107;;;;;;;;;;;;;;;;;;;93721:37;:110;;;;;;;;;;;;;;;;;;;93928:222;93978:15;;93966:9;:27;:120;;94070:16;93966:120;;;94025:13;93966:120;94113:14;93928:11;:222::i;:::-;94173:55;;;;;;;;;;;;;;-1:-1:-1;;;94173:55:0;;;94211:16;94173:11;:55::i;:::-;94251:56;;;;;;;;;;;;;;;;;;94290:16;94251:11;:56::i;:::-;94330:33;94342:10;94354:8;94330:11;:33::i;:::-;94398:23;;94386:8;:35;;:128;;;;;;;;;;;;;;;;;94449:35;94461:10;94449:35;;;;;;;;;;;;;-1:-1:-1;;;94449:35:0;;;:11;:35::i;:::-;93889:644;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93844:704;;;;;;;;;;93055:1501;;;:::o;91300:1747::-;91358:13;91384:17;91404:3;:8;;;91384:28;;91423:16;91442:3;:7;;;91423:26;;91460:23;91486:39;91503:10;91514:9;91503:21;;;;;;;;:::i;91486:39::-;91460:65;;91536:28;91567:68;91598:15;91614:9;91598:26;;;;;;;;:::i;91567:68::-;91536:99;;91744:15;;91732:9;:27;:229;;;;;;;;;;;;;;;;;91787:144;;;;;;;;;;;;;;;;;;91895:9;91787:11;:144::i;:::-;91996:15;;91984:9;:27;:235;;;;;;;;;;;;;;;;;92039:150;;;;;;;;;;;;;;;;;;92153:9;92039:11;:150::i;:::-;92254:15;;92242:9;:27;:243;;;;;;;;;;;;;;;;;92297:158;;;;;;;;;;;;;;;;;;92414:14;92297:11;:158::i;:::-;92520:15;;92508:9;:27;:248;;;;;;;;;;;;;;;;;92563:163;;;;;;;;;;;;;;;;;;92685:14;92563:11;:163::i;:::-;92791:17;;92779:8;:29;:226;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91693:1331;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;91648:1391;;;;;;91300:1747;;;:::o;99348:2857::-;99406:13;99432:17;99452:3;:8;;;99432:28;;99471:18;99492:3;:9;;;99471:30;;99512;99545:67;99576:14;99591:9;99576:25;;;;;;;;:::i;99545:67::-;99512:100;;99623:30;99656:67;99687:14;99702:9;99687:25;;;;;;;;:::i;99656:67::-;99623:100;;99734:30;99767:67;99798:14;99813:9;99798:25;;;;;;;;:::i;99767:67::-;99845:27;;;;;;;;;:22;:27;;99903:18;;99734:100;;-1:-1:-1;99845:27:0;99889:32;;99885:2014;;;100013:56;100031:3;100036;100041:2;100045:1;100048:16;100013:56;;;;;;;;;;;;:17;:56::i;:::-;100092:51;100110:3;100115;100120:2;100124:1;100127:11;;;;;;;;;;;;;-1:-1:-1;;;100127:11:0;;;100092:51;;;;;;;;;;;;:17;:51::i;:::-;99974:188;;;;;;;;;:::i;:::-;;;;;;;;;;;;;99938:239;;99885:2014;;;100213:18;;100199:10;:32;100195:1704;;;100259:56;100277:3;100282;100287:2;100291:1;100294:16;100259:56;;;;;;;;;;;;:17;:56::i;:::-;100248:67;;100195:1704;;;100351:16;;100337:10;:30;100333:1566;;;100459:56;100477:3;100482;100487:2;100491:1;100494:16;100459:56;;;;;;;;;;;;:17;:56::i;:::-;100538:51;100556:3;100561;100566:2;100570:1;100573:11;;;;;;;;;;;;;-1:-1:-1;;;100573:11:0;;;100538:51;;;;;;;;;;;;:17;:51::i;:::-;100612;100630:3;100635;100640:2;100644:1;100647:11;;;;;;;;;;;;;-1:-1:-1;;;100647:11:0;;;100612:51;;;;;;;;;;;;:17;:51::i;:::-;100420:262;;;;;;;;;;:::i;100333:1566::-;100733:20;;100719:10;:34;100715:1184;;;100781:55;100799:3;100804;100809:1;100812;100815:16;100781:55;;;;;;;;;;;;:17;:55::i;100715:1184::-;100872:17;;100858:10;:31;100854:1045;;;101062:16;100942:243;;;;;;;;:::i;100854:1045::-;101236:18;;101222:10;:32;101218:681;;;101417:16;101307:202;;;;;;;;:::i;101218:681::-;101560:16;;101546:10;:30;101542:357;;;101749:16;101629:243;;;;;;;;:::i;:::-;;;;;;;;;;;;;101593:294;;101542:357;101996:57;102014:3;102019;102024:2;102028;102032:16;101996:57;;;;;;;;;;;;:17;:57::i;:::-;102076:56;102094:3;102099;102104:1;102107:2;102111:16;102076:56;;;;;;;;;;;;:17;:56::i;:::-;102155:8;101957:225;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101912:285;;;;;;;;99348:2857;;;:::o;102213:809::-;102271:13;102297:17;102317:3;:8;;;102297:28;;102336:26;102365:39;102382:10;102393:9;102382:21;;;;;;;;:::i;102365:39::-;102336:68;;102434:15;;102421:9;:28;102417:598;;;-1:-1:-1;;102466:9:0;;;;;;;;;-1:-1:-1;102466:9:0;;;102213:809;-1:-1:-1;;102213:809:0:o;102417:598::-;102604:52;102622:3;102627:2;102631;102635;102639:12;102604:52;;;;;;;;;;;;:17;:52::i;:::-;102683:278;102731:2;102764;102797;102830;102863:12;102683:278;;;;;;;;;;;;;;;;;:17;:278::i;:::-;102561:423;;;;;;;;;:::i;90935:357::-;91037:12;;;91047:1;91037:12;;;;;;;;;90994:13;;91020:14;;91037:12;;;;;;;;;;;-1:-1:-1;;91020:29:0;-1:-1:-1;91074:8:0;91124:1;91115:122;91127:5;;91115:122;;91168:31;91193:4;91189:8;;:1;:8;91168:14;:31::i;:::-;91161:39;;91154:1;91156;91154:4;;;;;;;;:::i;:::-;;;;:46;-1:-1:-1;;;;;91154:46:0;;;;;;;;-1:-1:-1;91224:1:0;91219:6;;;;;91134:3;;;:::i;:::-;;;91115:122;;;-1:-1:-1;;;91247:1:0;91249;91247:4;;;;;;;;:::i;:::-;;;;:10;-1:-1:-1;;;;;91247:10:0;;;;;;;;-1:-1:-1;91282:1:0;;90935:357;-1:-1:-1;;;;90935:357:0:o;94564:4776::-;94650:13;94676:16;94695:3;:8;;;94676:27;;94714:14;94731:6;94738:8;94731:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;94784:14;;;;94731:16;;;;;;;;;;;-1:-1:-1;94784:14:0;94828:2;;94861:1;;94895;;;;94961;;94731:16;94999:63;;95025:37;95042:9;95052:8;95042:19;;;;;;;;:::i;95025:37::-;94999:63;;;95011:11;;;;;;;;;;;;;-1:-1:-1;;;95011:11:0;;;94999:63;94973:89;;95073:23;95099:9;95073:35;;95119:24;95146:37;95163:9;95173:8;95163:19;;;;;;;;:::i;95146:37::-;95194:25;;;;;;;;;:20;:25;;;95230:29;;;;;;;;;;95270:31;;;;;;;;;;95337:23;;95119:64;;-1:-1:-1;95194:25:0;;95318:42;;95314:805;;;95377:14;95390:1;95377:14;;:::i;:::-;;-1:-1:-1;95406:13:0;;;;:::i;:::-;;;;95447:1;95434:14;;95314:805;;;95489:21;;95470:15;:40;95466:653;;;95685:9;:36;;95712:9;95685:36;;;95697:12;95685:36;95823:17;;95811:8;:29;95810:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95810:55:0;;;;95567:345;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95527:400;;95466:653;;;95968:26;;95949:15;:45;95945:174;;;96011:13;96023:1;96011:13;;:::i;:::-;;-1:-1:-1;96039:11:0;;;;:::i;:::-;;-1:-1:-1;96065:15:0;;-1:-1:-1;96079:1:0;96065:15;;:::i;:::-;;-1:-1:-1;96095:12:0;;;;:::i;:::-;;;;95945:174;96146:15;;96134:8;:27;:73;;;;;96184:23;;96165:15;:42;;96134:73;96131:145;;;96224:13;;;;:::i;:::-;;;;96252:12;;;;;:::i;:::-;;;;96131:145;96311:26;;96292:15;:45;:76;;;;;96353:15;;96341:8;:27;96292:76;96288:145;;;96385:10;;;;:::i;:::-;;;;96410:11;;;;;:::i;:::-;;;;96288:145;96449:9;96445:876;;;96548:249;96592:3;96622;96652:10;96689:11;96727:10;96764;96548:17;:249::i;:::-;96840:21;;96821:15;:40;;96820:377;;;;;;;;;;;;;;;;;96890:277;96938:3;96972;97006:10;97047:11;97089:10;97130;96890:17;:277::i;:::-;96509:707;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;96509:707:0;;;;;;97260:11;;;;;;;;;-1:-1:-1;;;96509:707:0;97260:11;;;;;;97298;;;;;;;;;;;;;;;96509:707;;-1:-1:-1;97298:11:0;-1:-1:-1;96509:707:0;-1:-1:-1;96445:876:0;97349:18;;97337:8;:30;97333:1191;;;97396:26;97413:8;97396:16;:26::i;:::-;97384:38;;97333:1191;;;97456:16;;97444:8;:28;97440:1084;;;97493:14;;97489:416;;97693:9;97772:28;97789:10;97772:16;:28::i;:::-;97566:304;;;;;;;;;:::i;:::-;;;;;;;;;;;;;97528:361;;97489:416;97936:1;97923:10;:14;:58;;;;;97960:21;;97941:15;:40;;97923:58;97919:493;;;98083:6;98200:9;98279:28;98296:10;98279:16;:28::i;:::-;98040:337;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;98002:394;;97919:493;97440:1084;;;98445:17;;98433:8;:29;98429:95;;;98479:33;;;;;;;;;;;;;-1:-1:-1;;;98479:33:0;;;;;98429:95;98620:244;98664:3;98694;98724:8;98759:9;98795;98831:10;98620:17;:244::i;:::-;98907:21;;98888:15;:40;;98887:382;;99257:12;98887:382;;;98957:272;99005:3;99039;99073:8;99112:9;99152;99192:10;98957:17;:272::i;:::-;99292:6;98581:736;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;98536:796;;;;;;;;;;;;;;;;94564:4776;;;;:::o;49890:382::-;-1:-1:-1;;;;;49970:16:0;;49962:61;;;;-1:-1:-1;;;49962:61:0;;48815:2:1;49962:61:0;;;48797:21:1;;;48834:18;;;48827:30;48893:34;48873:18;;;48866:62;48945:18;;49962:61:0;48613:356:1;49962:61:0;47977:4;48001:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48001:16:0;:30;50034:58;;;;-1:-1:-1;;;50034:58:0;;49176:2:1;50034:58:0;;;49158:21:1;49215:2;49195:18;;;49188:30;49254;49234:18;;;49227:58;49302:18;;50034:58:0;48974:352:1;50034:58:0;50105:45;50134:1;50138:2;50142:7;50105:20;:45::i;:::-;-1:-1:-1;;;;;50163:13:0;;;;;;:9;:13;;;;;:18;;50180:1;;50163:13;:18;;50180:1;;50163:18;:::i;:::-;;;;-1:-1:-1;;50192:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;50192:21:0;-1:-1:-1;;;;;50192:21:0;;;;;;;;50231:33;;50192:16;;;50231:33;;50192:16;;50231:33;49890:382;;:::o;30904:712::-;31054:12;31083:7;31079:530;;;-1:-1:-1;31114:10:0;31107:17;;31079:530;31228:17;;:21;31224:374;;31426:10;31420:17;31487:15;31474:10;31470:2;31466:19;31459:44;31224:374;31569:12;31562:20;;-1:-1:-1;;;31562:20:0;;;;;;;;:::i;90323:406::-;90435:13;90592:6;90654:4;90511:195;;;;;;;;;:::i;89540:775::-;89740:13;89888:20;89905:2;89888:16;:20::i;:::-;89962;89979:2;89962:16;:20::i;:::-;90036;90053:2;90036:16;:20::i;:::-;90110;90127:2;90110:16;:20::i;:::-;90186:4;90240:6;89811:481;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;89766:541;;89540:775;;;;;;;;:::o;90737:190::-;90792:5;90835:1;90831;:5;;;90830:76;;90899:6;:1;90903:2;90899:6;:::i;:::-;90830:76;;;90858:6;:1;90862:2;90858:6;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;293:131:1;-1:-1:-1;;;;;;367:32:1;;357:43;;347:71;;414:1;411;404:12;429:245;487:6;540:2;528:9;519:7;515:23;511:32;508:52;;;556:1;553;546:12;508:52;595:9;582:23;614:30;638:5;614:30;:::i;967:258::-;1039:1;1049:113;1063:6;1060:1;1057:13;1049:113;;;1139:11;;;1133:18;1120:11;;;1113:39;1085:2;1078:10;1049:113;;;1180:6;1177:1;1174:13;1171:48;;;-1:-1:-1;;1215:1:1;1197:16;;1190:27;967:258::o;1230:269::-;1283:3;1321:5;1315:12;1348:6;1343:3;1336:19;1364:63;1420:6;1413:4;1408:3;1404:14;1397:4;1390:5;1386:16;1364:63;:::i;:::-;1481:2;1460:15;-1:-1:-1;;1456:29:1;1447:39;;;;1488:4;1443:50;;1230:269;-1:-1:-1;;1230:269:1:o;1504:231::-;1653:2;1642:9;1635:21;1616:4;1673:56;1725:2;1714:9;1710:18;1702:6;1673:56;:::i;1740:180::-;1799:6;1852:2;1840:9;1831:7;1827:23;1823:32;1820:52;;;1868:1;1865;1858:12;1820:52;-1:-1:-1;1891:23:1;;1740:180;-1:-1:-1;1740:180:1:o;2133:131::-;-1:-1:-1;;;;;2208:31:1;;2198:42;;2188:70;;2254:1;2251;2244:12;2269:315;2337:6;2345;2398:2;2386:9;2377:7;2373:23;2369:32;2366:52;;;2414:1;2411;2404:12;2366:52;2453:9;2440:23;2472:31;2497:5;2472:31;:::i;:::-;2522:5;2574:2;2559:18;;;;2546:32;;-1:-1:-1;;;2269:315:1:o;2771:255::-;2838:6;2891:2;2879:9;2870:7;2866:23;2862:32;2859:52;;;2907:1;2904;2897:12;2859:52;2946:9;2933:23;2965:31;2990:5;2965:31;:::i;3031:456::-;3108:6;3116;3124;3177:2;3165:9;3156:7;3152:23;3148:32;3145:52;;;3193:1;3190;3183:12;3145:52;3232:9;3219:23;3251:31;3276:5;3251:31;:::i;:::-;3301:5;-1:-1:-1;3358:2:1;3343:18;;3330:32;3371:33;3330:32;3371:33;:::i;:::-;3031:456;;3423:7;;-1:-1:-1;;;3477:2:1;3462:18;;;;3449:32;;3031:456::o;3492:127::-;3553:10;3548:3;3544:20;3541:1;3534:31;3584:4;3581:1;3574:15;3608:4;3605:1;3598:15;3624:255;3696:2;3690:9;3738:6;3726:19;;3775:18;3760:34;;3796:22;;;3757:62;3754:88;;;3822:18;;:::i;:::-;3858:2;3851:22;3624:255;:::o;3884:275::-;3955:2;3949:9;4020:2;4001:13;;-1:-1:-1;;3997:27:1;3985:40;;4055:18;4040:34;;4076:22;;;4037:62;4034:88;;;4102:18;;:::i;:::-;4138:2;4131:22;3884:275;;-1:-1:-1;3884:275:1:o;4164:1021::-;4248:6;4279:2;4322;4310:9;4301:7;4297:23;4293:32;4290:52;;;4338:1;4335;4328:12;4290:52;4378:9;4365:23;4407:18;4448:2;4440:6;4437:14;4434:34;;;4464:1;4461;4454:12;4434:34;4502:6;4491:9;4487:22;4477:32;;4547:7;4540:4;4536:2;4532:13;4528:27;4518:55;;4569:1;4566;4559:12;4518:55;4605:2;4592:16;4627:2;4623;4620:10;4617:36;;;4633:18;;:::i;:::-;4679:2;4676:1;4672:10;4662:20;;4702:28;4726:2;4722;4718:11;4702:28;:::i;:::-;4764:15;;;4834:11;;;4830:20;;;4795:12;;;;4862:19;;;4859:39;;;4894:1;4891;4884:12;4859:39;4918:11;;;;4938:217;4954:6;4949:3;4946:15;4938:217;;;5034:3;5021:17;5008:30;;5051:31;5076:5;5051:31;:::i;:::-;5095:18;;;4971:12;;;;5133;;;;4938:217;;;5174:5;4164:1021;-1:-1:-1;;;;;;;;4164:1021:1:o;5190:403::-;5273:6;5281;5334:2;5322:9;5313:7;5309:23;5305:32;5302:52;;;5350:1;5347;5340:12;5302:52;5389:9;5376:23;5408:31;5433:5;5408:31;:::i;:::-;5458:5;-1:-1:-1;5515:2:1;5500:18;;5487:32;5528:33;5487:32;5528:33;:::i;:::-;5580:7;5570:17;;;5190:403;;;;;:::o;5598:118::-;5684:5;5677:13;5670:21;5663:5;5660:32;5650:60;;5706:1;5703;5696:12;5721:128;5786:20;;5815:28;5786:20;5815:28;:::i;5854:1333::-;5940:6;5948;5992:9;5983:7;5979:23;6022:3;6018:2;6014:12;6011:32;;;6039:1;6036;6029:12;6011:32;6062:6;6088:2;6084;6080:11;6077:31;;;6104:1;6101;6094:12;6077:31;6130:22;;:::i;:::-;6117:35;;6188:9;6175:23;6168:5;6161:38;6231:35;6262:2;6251:9;6247:18;6231:35;:::i;:::-;6226:2;6219:5;6215:14;6208:59;6299:35;6330:2;6319:9;6315:18;6299:35;:::i;:::-;6294:2;6287:5;6283:14;6276:59;6395:2;6384:9;6380:18;6367:32;6362:2;6355:5;6351:14;6344:56;6461:3;6450:9;6446:19;6433:33;6427:3;6420:5;6416:15;6409:58;6528:3;6517:9;6513:19;6500:33;6494:3;6487:5;6483:15;6476:58;6595:3;6584:9;6580:19;6567:33;6561:3;6554:5;6550:15;6543:58;6662:3;6651:9;6647:19;6634:33;6628:3;6621:5;6617:15;6610:58;6687:3;6750:2;6739:9;6735:18;6722:32;6717:2;6710:5;6706:14;6699:56;;6774:3;6837:2;6826:9;6822:18;6809:32;6804:2;6797:5;6793:14;6786:56;;6861:3;6924:2;6913:9;6909:18;6896:32;6891:2;6884:5;6880:14;6873:56;;6948:3;7011:2;7000:9;6996:18;6983:32;6978:2;6971:5;6967:14;6960:56;;7035:3;7098:2;7087:9;7083:18;7070:32;7065:2;7058:5;7054:14;7047:56;;7122:5;7112:15;;7146:35;7177:2;7166:9;7162:18;7146:35;:::i;:::-;7136:45;;;;5854:1333;;;;;:::o;7192:407::-;7257:5;7291:18;7283:6;7280:30;7277:56;;;7313:18;;:::i;:::-;7351:57;7396:2;7375:15;;-1:-1:-1;;7371:29:1;7402:4;7367:40;7351:57;:::i;:::-;7342:66;;7431:6;7424:5;7417:21;7471:3;7462:6;7457:3;7453:16;7450:25;7447:45;;;7488:1;7485;7478:12;7447:45;7537:6;7532:3;7525:4;7518:5;7514:16;7501:43;7591:1;7584:4;7575:6;7568:5;7564:18;7560:29;7553:40;7192:407;;;;;:::o;7604:451::-;7673:6;7726:2;7714:9;7705:7;7701:23;7697:32;7694:52;;;7742:1;7739;7732:12;7694:52;7782:9;7769:23;7815:18;7807:6;7804:30;7801:50;;;7847:1;7844;7837:12;7801:50;7870:22;;7923:4;7915:13;;7911:27;-1:-1:-1;7901:55:1;;7952:1;7949;7942:12;7901:55;7975:74;8041:7;8036:2;8023:16;8018:2;8014;8010:11;7975:74;:::i;8060:309::-;8125:6;8133;8186:2;8174:9;8165:7;8161:23;8157:32;8154:52;;;8202:1;8199;8192:12;8154:52;8238:9;8225:23;8215:33;;8298:2;8287:9;8283:18;8270:32;8311:28;8333:5;8311:28;:::i;8626:1192::-;8833:13;;8815:32;;8894:4;8882:17;;;8876:24;8802:3;8787:19;;;8909:51;;8939:20;;8876:24;749:13;742:21;730:34;;679:91;8909:51;;9009:4;9001:6;8997:17;8991:24;9024:53;9071:4;9060:9;9056:20;9040:14;749:13;742:21;730:34;;679:91;9024:53;;9133:4;9125:6;9121:17;9115:24;9108:4;9097:9;9093:20;9086:54;9196:4;9188:6;9184:17;9178:24;9171:4;9160:9;9156:20;9149:54;9259:4;9251:6;9247:17;9241:24;9234:4;9223:9;9219:20;9212:54;9322:4;9314:6;9310:17;9304:24;9297:4;9286:9;9282:20;9275:54;9385:4;9377:6;9373:17;9367:24;9360:4;9349:9;9345:20;9338:54;9411:6;9471:2;9463:6;9459:15;9453:22;9448:2;9437:9;9433:18;9426:50;;9495:6;9555:2;9547:6;9543:15;9537:22;9532:2;9521:9;9517:18;9510:50;;9579:6;9639:2;9631:6;9627:15;9621:22;9616:2;9605:9;9601:18;9594:50;;9663:6;9723:2;9715:6;9711:15;9705:22;9700:2;9689:9;9685:18;9678:50;;9747:6;9807:2;9799:6;9795:15;9789:22;9784:2;9773:9;9769:18;9762:50;;8626:1192;;;;:::o;9823:382::-;9888:6;9896;9949:2;9937:9;9928:7;9924:23;9920:32;9917:52;;;9965:1;9962;9955:12;9917:52;10004:9;9991:23;10023:31;10048:5;10023:31;:::i;:::-;10073:5;-1:-1:-1;10130:2:1;10115:18;;10102:32;10143:30;10102:32;10143:30;:::i;10210:795::-;10305:6;10313;10321;10329;10382:3;10370:9;10361:7;10357:23;10353:33;10350:53;;;10399:1;10396;10389:12;10350:53;10438:9;10425:23;10457:31;10482:5;10457:31;:::i;:::-;10507:5;-1:-1:-1;10564:2:1;10549:18;;10536:32;10577:33;10536:32;10577:33;:::i;:::-;10629:7;-1:-1:-1;10683:2:1;10668:18;;10655:32;;-1:-1:-1;10738:2:1;10723:18;;10710:32;10765:18;10754:30;;10751:50;;;10797:1;10794;10787:12;10751:50;10820:22;;10873:4;10865:13;;10861:27;-1:-1:-1;10851:55:1;;10902:1;10899;10892:12;10851:55;10925:74;10991:7;10986:2;10973:16;10968:2;10964;10960:11;10925:74;:::i;:::-;10915:84;;;10210:795;;;;;;;:::o;11670:380::-;11749:1;11745:12;;;;11792;;;11813:61;;11867:4;11859:6;11855:17;11845:27;;11813:61;11920:2;11912:6;11909:14;11889:18;11886:38;11883:161;;;11966:10;11961:3;11957:20;11954:1;11947:31;12001:4;11998:1;11991:15;12029:4;12026:1;12019:15;11883:161;;11670:380;;;:::o;13295:402::-;13497:2;13479:21;;;13536:2;13516:18;;;13509:30;13575:34;13570:2;13555:18;;13548:62;-1:-1:-1;;;13641:2:1;13626:18;;13619:36;13687:3;13672:19;;13295:402::o;13702:127::-;13763:10;13758:3;13754:20;13751:1;13744:31;13794:4;13791:1;13784:15;13818:4;13815:1;13808:15;13834:128;13874:3;13905:1;13901:6;13898:1;13895:13;13892:39;;;13911:18;;:::i;:::-;-1:-1:-1;13947:9:1;;13834:128::o;13967:407::-;14169:2;14151:21;;;14208:2;14188:18;;;14181:30;14247:34;14242:2;14227:18;;14220:62;-1:-1:-1;;;14313:2:1;14298:18;;14291:41;14364:3;14349:19;;13967:407::o;14666:413::-;14868:2;14850:21;;;14907:2;14887:18;;;14880:30;14946:34;14941:2;14926:18;;14919:62;-1:-1:-1;;;15012:2:1;14997:18;;14990:47;15069:3;15054:19;;14666:413::o;15084:356::-;15286:2;15268:21;;;15305:18;;;15298:30;15364:34;15359:2;15344:18;;15337:62;15431:2;15416:18;;15084:356::o;15445:127::-;15506:10;15501:3;15497:20;15494:1;15487:31;15537:4;15534:1;15527:15;15561:4;15558:1;15551:15;15577:135;15616:3;-1:-1:-1;;15637:17:1;;15634:43;;;15657:18;;:::i;:::-;-1:-1:-1;15704:1:1;15693:13;;15577:135::o;16129:184::-;16199:6;16252:2;16240:9;16231:7;16227:23;16223:32;16220:52;;;16268:1;16265;16258:12;16220:52;-1:-1:-1;16291:16:1;;16129:184;-1:-1:-1;16129:184:1:o;20119:168::-;20159:7;20225:1;20221;20217:6;20213:14;20210:1;20207:21;20202:1;20195:9;20188:17;20184:45;20181:71;;;20232:18;;:::i;:::-;-1:-1:-1;20272:9:1;;20119:168::o;20292:127::-;20353:10;20348:3;20344:20;20341:1;20334:31;20384:4;20381:1;20374:15;20408:4;20405:1;20398:15;20424:120;20464:1;20490;20480:35;;20495:18;;:::i;:::-;-1:-1:-1;20529:9:1;;20424:120::o;20549:125::-;20589:4;20617:1;20614;20611:8;20608:34;;;20622:18;;:::i;:::-;-1:-1:-1;20659:9:1;;20549:125::o;22902:185::-;22944:3;22982:5;22976:12;22997:52;23042:6;23037:3;23030:4;23023:5;23019:16;22997:52;:::i;:::-;23065:16;;;;;22902:185;-1:-1:-1;;22902:185:1:o;23092:448::-;23354:31;23349:3;23342:44;23324:3;23415:6;23409:13;23431:62;23486:6;23481:2;23476:3;23472:12;23465:4;23457:6;23453:17;23431:62;:::i;:::-;23513:16;;;;23531:2;23509:25;;23092:448;-1:-1:-1;;23092:448:1:o;23900:414::-;24102:2;24084:21;;;24141:2;24121:18;;;24114:30;24180:34;24175:2;24160:18;;24153:62;-1:-1:-1;;;24246:2:1;24231:18;;24224:48;24304:3;24289:19;;23900:414::o;24319:245::-;24386:6;24439:2;24427:9;24418:7;24414:23;24410:32;24407:52;;;24455:1;24452;24445:12;24407:52;24487:9;24481:16;24506:28;24528:5;24506:28;:::i;25106:973::-;25191:12;;25156:3;;25246:1;25266:18;;;;25319;;;;25346:61;;25400:4;25392:6;25388:17;25378:27;;25346:61;25426:2;25474;25466:6;25463:14;25443:18;25440:38;25437:161;;;25520:10;25515:3;25511:20;25508:1;25501:31;25555:4;25552:1;25545:15;25583:4;25580:1;25573:15;25437:161;25614:18;25641:104;;;;25759:1;25754:319;;;;25607:466;;25641:104;-1:-1:-1;;25674:24:1;;25662:37;;25719:16;;;;-1:-1:-1;25641:104:1;;25754:319;25053:1;25046:14;;;25090:4;25077:18;;25848:1;25862:165;25876:6;25873:1;25870:13;25862:165;;;25954:14;;25941:11;;;25934:35;25997:16;;;;25891:10;;25862:165;;;25866:3;;26056:6;26051:3;26047:16;26040:23;;25607:466;;;;;;;25106:973;;;;:::o;26438:2303::-;-1:-1:-1;;;27579:43:1;;27645:13;;27561:3;;27667:61;27645:13;27717:1;27708:11;;27701:4;27689:17;;27667:61;:::i;:::-;-1:-1:-1;;;27787:1:1;27747:16;;;27779:10;;;27772:30;27827:13;;27849:63;27827:13;27898:2;27890:11;;27883:4;27871:17;;27849:63;:::i;:::-;-1:-1:-1;;;27972:2:1;27931:17;;;;27964:11;;;27957:67;28043:46;28085:2;28077:11;;28069:6;28043:46;:::i;:::-;-1:-1:-1;;;28098:56:1;;28179:13;;28033:56;;-1:-1:-1;28201:63:1;28179:13;28250:2;28242:11;;28235:4;28223:17;;28201:63;:::i;:::-;28325:13;;28283:17;;;28347:63;28325:13;28396:2;28388:11;;28381:4;28369:17;;28347:63;:::i;:::-;28475:66;28470:2;28429:17;;;;28462:11;;;28455:87;-1:-1:-1;;;28566:2:1;28558:11;;28551:41;28608:127;28638:96;28664:69;28694:38;28728:2;28720:11;;28712:6;28694:38;:::i;:::-;26161:66;26149:79;;-1:-1:-1;;;26253:2:1;26244:12;;26237:32;26294:2;26285:12;;26084:219;28664:69;28656:6;28638:96;:::i;:::-;-1:-1:-1;;;26373:27:1;;26425:1;26416:11;;26308:125;28608:127;28601:134;26438:2303;-1:-1:-1;;;;;;;;;;26438:2303:1:o;28746:470::-;28925:3;28963:6;28957:13;28979:53;29025:6;29020:3;29013:4;29005:6;29001:17;28979:53;:::i;:::-;29095:13;;29054:16;;;;29117:57;29095:13;29054:16;29151:4;29139:17;;29117:57;:::i;:::-;29190:20;;28746:470;-1:-1:-1;;;;28746:470:1:o;29221:112::-;29253:1;29279;29269:35;;29284:18;;:::i;:::-;-1:-1:-1;29318:9:1;;29221:112::o;29338:500::-;-1:-1:-1;;;;;29607:15:1;;;29589:34;;29659:15;;29654:2;29639:18;;29632:43;29706:2;29691:18;;29684:34;;;29754:3;29749:2;29734:18;;29727:31;;;29532:4;;29775:57;;29812:19;;29804:6;29775:57;:::i;29843:249::-;29912:6;29965:2;29953:9;29944:7;29940:23;29936:32;29933:52;;;29981:1;29978;29971:12;29933:52;30013:9;30007:16;30032:30;30056:5;30032:30;:::i;30097:351::-;30326:3;30354:38;30388:3;30380:6;30354:38;:::i;:::-;-1:-1:-1;;;30401:15:1;;30440:1;30432:10;;30097:351;-1:-1:-1;;;30097:351:1:o;30453:1767::-;30968:3;31006:6;31000:13;31022:53;31068:6;31063:3;31056:4;31048:6;31044:17;31022:53;:::i;:::-;31106:6;31100:13;31122:68;31181:8;31172:6;31167:3;31163:16;31156:4;31148:6;31144:17;31122:68;:::i;:::-;31268:13;;31216:16;;;31212:31;;31290:57;31268:13;31212:31;31324:4;31312:17;;31290:57;:::i;:::-;31378:6;31372:13;31394:72;31457:8;31446;31439:5;31435:20;31428:4;31420:6;31416:17;31394:72;:::i;:::-;31548:13;;31492:20;;;;31488:35;;31570:57;31548:13;31488:35;31604:4;31592:17;;31570:57;:::i;:::-;31658:6;31652:13;31674:72;31737:8;31726;31719:5;31715:20;31708:4;31700:6;31696:17;31674:72;:::i;:::-;31828:13;;31772:20;;;;31768:35;;31850:57;31828:13;31768:35;31884:4;31872:17;;31850:57;:::i;:::-;31938:6;31932:13;31954:72;32017:8;32006;31999:5;31995:20;31988:4;31980:6;31976:17;31954:72;:::i;:::-;32105:13;;32049:20;;;;32045:35;;32127:54;32105:13;32045:35;32161:4;32149:17;;32127:54;:::i;:::-;32197:17;;30453:1767;-1:-1:-1;;;;;;;;;;;30453:1767:1:o;32225:994::-;-1:-1:-1;;;32725:57:1;;32805:13;;32707:3;;32827:62;32805:13;32877:2;32868:12;;32861:4;32849:17;;32827:62;:::i;:::-;-1:-1:-1;;;32948:2:1;32908:16;;;32940:11;;;32933:59;33017:13;;33039:63;33017:13;33088:2;33080:11;;33073:4;33061:17;;33039:63;:::i;:::-;-1:-1:-1;;;33162:2:1;33121:17;;;;33154:11;;;33147:37;33208:4;33200:13;;32225:994;-1:-1:-1;;;;32225:994:1:o;33348:1929::-;33999:66;33994:3;33987:79;33969:3;34085:2;34117:66;34112:2;34107:3;34103:12;34096:88;34214:66;34209:2;34204:3;34200:12;34193:88;34320:4;34315:3;34311:14;34306:2;34301:3;34297:12;34290:36;34345:2;34376:6;34370:13;34392:60;34445:6;34440:2;34435:3;34431:12;34426:2;34418:6;34414:15;34392:60;:::i;:::-;34512:13;;34471:16;;;;34534:61;34512:13;34573:11;;;34556:15;;;34534:61;:::i;:::-;34656:13;;34614:17;;;34678:61;34656:13;34717:11;;;34700:15;;;34678:61;:::i;:::-;34800:13;;34758:17;;;34822:61;34800:13;34861:11;;;34844:15;;;34822:61;:::i;:::-;34944:13;;34902:17;;;34966:61;34944:13;35005:11;;;34988:15;;;34966:61;:::i;:::-;35088:13;;35046:17;;;35110:61;35088:13;35149:11;;;35132:15;;;35110:61;:::i;:::-;35187:84;35217:53;35266:2;35255:8;35251:2;35247:17;35243:26;35235:6;35217:53;:::i;:::-;-1:-1:-1;;;33289:21:1;;33335:1;33326:11;;33224:119;35187:84;35180:91;33348:1929;-1:-1:-1;;;;;;;;;;;;;33348:1929:1:o;35282:276::-;35413:3;35451:6;35445:13;35467:53;35513:6;35508:3;35501:4;35493:6;35489:17;35467:53;:::i;:::-;35536:16;;;;;35282:276;-1:-1:-1;;35282:276:1:o;35563:127::-;35624:10;35619:3;35615:20;35612:1;35605:31;35655:4;35652:1;35645:15;35679:4;35676:1;35669:15;36868:1401;37380:66;37375:3;37368:79;37477:66;37472:2;37467:3;37463:12;37456:88;37574:66;37569:2;37564:3;37560:12;37553:88;37671:66;37666:2;37661:3;37657:12;37650:88;37778:28;37773:3;37769:38;37763:3;37758;37754:13;37747:61;37350:3;37837:6;37831:13;37853:61;37907:6;37901:3;37896;37892:13;37887:2;37879:6;37875:15;37853:61;:::i;:::-;-1:-1:-1;;;37973:3:1;37933:16;;;37965:12;;;37958:35;38018:13;;38040:62;38018:13;38087:3;38079:12;;38074:2;38062:15;;38040:62;:::i;:::-;38168:66;38162:3;38121:17;;;;38154:12;;;38147:88;38259:3;38251:12;;36868:1401;-1:-1:-1;;;;36868:1401:1:o;38405:2139::-;39215:66;39210:3;39203:79;39312:66;39307:2;39302:3;39298:12;39291:88;39418:40;39413:3;39409:50;39404:2;39399:3;39395:12;39388:72;39185:3;39489:6;39483:13;39505:60;39558:6;39553:2;39548:3;39544:12;39539:2;39531:6;39527:15;39505:60;:::i;:::-;39629:66;39624:2;39584:16;;;39616:11;;;39609:87;-1:-1:-1;;;39753:3:1;39745:12;;39738:24;;;39787:13;;39809:62;39787:13;39856:3;39848:12;;39843:2;39831:15;;39809:62;:::i;:::-;39937:66;39931:3;39890:17;;;;39923:12;;;39916:88;40028:3;40020:12;;40013:24;40062:13;;40084:62;40062:13;40131:3;40123:12;;40118:2;40106:15;;40084:62;:::i;:::-;40212:66;40206:3;40165:17;;;;40198:12;;;40191:88;40309:66;40303:3;40295:12;;40288:88;-1:-1:-1;;;40400:3:1;40392:12;;40385:72;40473:65;40498:39;40532:3;40524:12;;40516:6;40498:39;:::i;:::-;-1:-1:-1;;;38334:33:1;;38392:1;38383:11;;38274:126;40549:1052;40872:3;40910:6;40904:13;40926:53;40972:6;40967:3;40960:4;40952:6;40948:17;40926:53;:::i;:::-;41042:13;;41001:16;;;;41064:57;41042:13;41001:16;41098:4;41086:17;;41064:57;:::i;:::-;41188:13;;41143:20;;;41210:57;41188:13;41143:20;41244:4;41232:17;;41210:57;:::i;:::-;41334:13;;41289:20;;;41356:57;41334:13;41289:20;41390:4;41378:17;;41356:57;:::i;:::-;41480:13;;41435:20;;;41502:57;41480:13;41435:20;41536:4;41524:17;;41502:57;:::i;:::-;41575:20;;40549:1052;-1:-1:-1;;;;;;;40549:1052:1:o;41606:664::-;41833:3;41871:6;41865:13;41887:53;41933:6;41928:3;41921:4;41913:6;41909:17;41887:53;:::i;:::-;42003:13;;41962:16;;;;42025:57;42003:13;41962:16;42059:4;42047:17;;42025:57;:::i;:::-;42149:13;;42104:20;;;42171:57;42149:13;42104:20;42205:4;42193:17;;42171:57;:::i;:::-;42244:20;;41606:664;-1:-1:-1;;;;;41606:664:1:o;42275:893::-;42638:66;42633:3;42626:79;42735:66;42730:2;42725:3;42721:12;42714:88;42608:3;42831:6;42825:13;42847:60;42900:6;42895:2;42890:3;42886:12;42881:2;42873:6;42869:15;42847:60;:::i;:::-;42971:66;42966:2;42926:16;;;;42958:11;;;42951:87;-1:-1:-1;43067:66:1;43062:2;43054:11;;43047:87;43158:3;43150:12;;42275:893;-1:-1:-1;42275:893:1:o;43173:770::-;43536:66;43531:3;43524:79;43642:30;43637:3;43633:40;43628:2;43623:3;43619:12;43612:62;43506:3;43703:6;43697:13;43719:60;43772:6;43767:2;43762:3;43758:12;43753:2;43745:6;43741:15;43719:60;:::i;:::-;43843:66;43838:2;43798:16;;;;43830:11;;;43823:87;-1:-1:-1;43934:2:1;43926:11;;43173:770;-1:-1:-1;43173:770:1:o;43948:893::-;44311:66;44306:3;44299:79;44408:66;44403:2;44398:3;44394:12;44387:88;44281:3;44504:6;44498:13;44520:60;44573:6;44568:2;44563:3;44559:12;44554:2;44546:6;44542:15;44520:60;:::i;:::-;44644:66;44639:2;44599:16;;;;44631:11;;;44624:87;-1:-1:-1;44740:66:1;44735:2;44727:11;;44720:87;44831:3;44823:12;;43948:893;-1:-1:-1;43948:893:1:o;44846:136::-;44885:3;44913:5;44903:39;;44922:18;;:::i;:::-;-1:-1:-1;;;44958:18:1;;44846:136::o;44987:1173::-;45499:66;45494:3;45487:79;45604:46;45600:2;45596:55;45591:2;45586:3;45582:12;45575:77;45469:3;45681:6;45675:13;45697:60;45750:6;45745:2;45740:3;45736:12;45731:2;45723:6;45719:15;45697:60;:::i;:::-;45821:66;45816:2;45776:16;;;45808:11;;;45801:87;-1:-1:-1;;;45912:2:1;45904:11;;45897:51;45973:13;;45995:61;45973:13;46042:2;46034:11;;46029:2;46017:15;;45995:61;:::i;:::-;-1:-1:-1;;;46116:2:1;46075:17;;;;46108:11;;;46101:26;46151:2;46143:11;;44987:1173;-1:-1:-1;;;;44987:1173:1:o;46165:1117::-;46677:66;46672:3;46665:79;46774:66;46769:2;46764:3;46760:12;46753:88;46647:3;46870:6;46864:13;46886:60;46939:6;46934:2;46929:3;46925:12;46920:2;46912:6;46908:15;46886:60;:::i;:::-;-1:-1:-1;;;47005:2:1;46965:16;;;46997:11;;;46990:37;47052:13;;47074:61;47052:13;47121:2;47113:11;;47108:2;47096:15;;47074:61;:::i;:::-;-1:-1:-1;;;47195:2:1;47154:17;;;;47187:11;;;47180:69;47273:2;47265:11;;46165:1117;-1:-1:-1;;;;46165:1117:1:o;47287:1321::-;47817:3;47855:6;47849:13;47871:53;47917:6;47912:3;47905:4;47897:6;47893:17;47871:53;:::i;:::-;47955:6;47950:3;47946:16;47933:29;;47985:66;47978:5;47971:81;48086:66;48079:4;48072:5;48068:16;48061:92;48184:6;48178:13;48200:66;48257:8;48252:2;48245:5;48241:14;48234:4;48226:6;48222:17;48200:66;:::i;:::-;-1:-1:-1;;;48329:2:1;48285:20;;;;48321:11;;;48314:37;48376:13;;48398:63;48376:13;48447:2;48439:11;;48432:4;48420:17;;48398:63;:::i;:::-;-1:-1:-1;;;48521:2:1;48480:17;;;;48513:11;;;48506:69;48599:2;48591:11;;47287:1321;-1:-1:-1;;;;;47287:1321:1:o;49331:988::-;-1:-1:-1;;;49831:59:1;;49913:13;;49813:3;;49935:62;49913:13;49985:2;49976:12;;49969:4;49957:17;;49935:62;:::i;:::-;-1:-1:-1;;;50056:2:1;50016:16;;;50048:11;;;50041:49;50115:13;;50137:63;50115:13;50186:2;50178:11;;50171:4;50159:17;;50137:63;:::i;:::-;-1:-1:-1;;;50260:2:1;50219:17;;;;50252:11;;;50245:41;50310:2;50302:11;;49331:988;-1:-1:-1;;;;49331:988:1:o;50444:2194::-;-1:-1:-1;;;51540:51:1;;51614:13;;51522:3;;51636:62;51614:13;51686:2;51677:12;;51670:4;51658:17;;51636:62;:::i;:::-;-1:-1:-1;;;51757:2:1;51717:16;;;51749:11;;;51742:45;51812:13;;51834:63;51812:13;51883:2;51875:11;;51868:4;51856:17;;51834:63;:::i;:::-;-1:-1:-1;;;51957:2:1;51916:17;;;;51949:11;;;51942:45;52012:13;;52034:63;52012:13;52083:2;52075:11;;52068:4;52056:17;;52034:63;:::i;:::-;-1:-1:-1;;;52157:2:1;52116:17;;;;52149:11;;;52142:45;52212:13;;52234:63;52212:13;52283:2;52275:11;;52268:4;52256:17;;52234:63;:::i;:::-;-1:-1:-1;;;52357:2:1;52316:17;;;;52349:11;;;52342:49;52416:13;;52438:63;52416:13;52487:2;52479:11;;52472:4;52460:17;;52438:63;:::i;:::-;52517:115;52547:84;52573:57;52626:2;52615:8;52611:2;52607:17;52603:26;-1:-1:-1;;;36804:26:1;;36855:1;36846:11;;36739:124;52573:57;52565:6;52547:84;:::i;:::-;-1:-1:-1;;;50389:17:1;;50431:1;50422:11;;50324:115;52643:204;52681:3;52717:4;52714:1;52710:12;52749:4;52746:1;52742:12;52784:3;52778:4;52774:14;52769:3;52766:23;52763:49;;;52792:18;;:::i;:::-;52828:13;;52643:204;-1:-1:-1;;;52643:204:1:o

Swarm Source

ipfs://265a3b17db23bdd11919155598a99529d162dc098df495c9a3c2531d506e99e8
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.