ETH Price: $3,355.65 (-0.98%)

Token

Console NFT Cyber Upgrades (Cnsl-NFT-U)
 

Overview

Max Total Supply

1,017 Cnsl-NFT-U

Holders

636

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
fcny.eth
Balance
1 Cnsl-NFT-U
0xB7972C694cB76d4756346A9a7235d90064D8bd8B
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:
ConsoleNFT_Cyber_Upgrades

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: GPL-3.0

/*
      ::::::::   ::::::::  ::::    :::  ::::::::   ::::::::  :::        ::::::::::          ::::    ::: :::::::::: ::::::::::: 
    :+:    :+: :+:    :+: :+:+:   :+: :+:    :+: :+:    :+: :+:        :+:                 :+:+:   :+: :+:            :+:      
   +:+        +:+    +:+ :+:+:+  +:+ +:+        +:+    +:+ +:+        +:+                 :+:+:+  +:+ +:+            +:+       
  +#+        +#+    +:+ +#+ +:+ +#+ +#++:++#++ +#+    +:+ +#+        +#++:++#            +#+ +:+ +#+ :#::+::#       +#+        
 +#+        +#+    +#+ +#+  +#+#+#        +#+ +#+    +#+ +#+        +#+                 +#+  +#+#+# +#+            +#+         
#+#    #+# #+#    #+# #+#   #+#+# #+#    #+# #+#    #+# #+#        #+#                 #+#   #+#+# #+#            #+#          
########   ########  ###    ####  ########   ########  ########## ##########          ###    #### ###            ###           
*/

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

contract VRFRequestIDBase {
  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  ) internal pure returns (uint256) {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

// File: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/LinkTokenInterface.sol

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

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

  function balanceOf(address owner) external view returns (uint256 balance);

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

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

  function name() external view returns (string memory tokenName);

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

  function totalSupply() external view returns (uint256 totalTokensIssued);

  function transfer(address to, uint256 value) external returns (bool success);

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function transferFrom(
    address from,
    address to,
    uint256 value
  ) external returns (bool success);
}

// File: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBase.sol



/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {
  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual;

  /**
   * @dev In order to keep backwards compatibility we have kept the user
   * seed field around. We remove the use of it because given that the blockhash
   * enters later, it overrides whatever randomness the used seed provides.
   * Given that it adds no security, and can easily lead to misunderstandings,
   * we have removed it from usage and can now provide a simpler API.
   */
  uint256 private constant USER_SEED_PLACEHOLDER = 0;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(bytes32 _keyHash, uint256 _fee) internal returns (bytes32 requestId) {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash] + 1;
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface internal immutable LINK;
  address private immutable vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 => uint256) /* keyHash */ /* nonce */
    private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(address _vrfCoordinator, address _link) {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

/**
 * @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);
}


/**
 * @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;
}



/**
 * @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);
    }
}


/*
 * @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;
    }
}


/**
 * @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);
    }
}


/**
 * @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 make 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;
    }
}



/**
 * @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);
}


/**
 * @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);
}


/**
 * @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);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private 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);
            }
        }
    }
}




/**
 * @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;
    }
}


/**
 * @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), "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(to).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 {}
}



/**
 * @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);
}


/**
 * @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();
    }
}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

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

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

abstract contract PercentageGenerator {
	function calculatePercentage(bool hasVault, uint rarity, uint tokens) public view virtual returns (uint[] memory);
}

abstract contract SourceData {
	function getVaultRarity(uint token_id) public view virtual returns(uint);
    function getFirstStat(uint token_id, uint rarity) public view virtual returns(uint);
    function getFirstStatValue(uint token_id, uint rarity) public view virtual returns(uint);
    function getSecondStat(uint token_id, uint rarity) public view virtual returns(uint);
    function getSecondStatValue(uint token_id, uint rarity) public view virtual returns(uint);
    function getFirstAugment(uint token_id, uint rarity) public view virtual returns(uint);
    function getSecondAugment(uint token_id, uint rarity) public view virtual returns(uint);
    function getAirdrops(uint token_id, uint rarity) public view virtual returns(uint);
}

contract ConsoleNFT_Cyber_Upgrades is ERC721Enumerable, ReentrancyGuard, Ownable, VRFConsumerBase {

	address dataContract;
    address percentageContract;
    address vaultContract;
    address levelUpContract;

    mapping(uint => bool) private _usedVaults;

    // Mapping for wallet addresses that have previously minted
    mapping(address => uint) private _whitelistMinters;

    // Merkle Proof Hashes for tokens
    bytes32[] public rootHashes;

	uint public constant maxTokens = 5000;

    uint public vaultHolderReserves = 500;

    uint[] public rarities; // mapping of pool rarities in constructor

    uint public total = 0;

	uint mintCost = 0.05 ether;
    uint publicMintCost = 0.1 ether;

    uint public whitelistMintStart;
    uint public publicMintStart;

	bool sysAdminMinted;
	bool error404Minted;
	bool code200Minted;
	bool giveawaysMinted;
	
	address error404Address;
	address code200Address;
	address giveawaysAddress;

    mapping(uint => uint) public levels; // tokenID -> level
    mapping(uint => uint) public rarity; // tokenID -> rarity

    function setMerkleHashes(bytes32[] memory _rootHash) external onlyOwner {
        rootHashes = new bytes32[](0);
        for (uint i=0; i < _rootHash.length; i++) {
            rootHashes.push(_rootHash[i]);
        }
    }

    function setVaultContractAddress(address _vaultContract) external onlyOwner {
        vaultContract = _vaultContract;
    }

    function setPercentageContractAddress(address _percentageContract) external onlyOwner {
        percentageContract = _percentageContract;
    }

    function setWhitelistMintStart(uint _timestamp) external onlyOwner {
        whitelistMintStart = _timestamp;
    }
	
    function setPublicMintStart(uint _timestamp) external onlyOwner {
        publicMintStart = _timestamp;
    }

	function setSourceData(address _dataContract) external onlyOwner {
        dataContract = _dataContract;
    }

    function setLevelUpContract(address _levelUpContract) external onlyOwner {
        levelUpContract = _levelUpContract;
    }

	string[] private rarityText = [
        "Common",
        "Uncommon",
        "Rare",
        "Epic",
        "Legendary"
    ];

    function getRarity(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
        output = rarityText[rarity[tokenId]];
		
        return output;
    }

    string[] private firstStat = [
        "Health",
        "Strength",
        "Speed",
        "Accuracy",
        "Intelligence",
        "Tech",
        "Hack speed",
        "SQL skill",
        "Network",
        "DNA",
        "De-auth",
        "Pwd cracking",
        "XSS forgery",
        "Decrypt",
        "Cryptography"
    ];

    function getFirstStat(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = firstStat[source_data.getFirstStat(tokenId, rarity[tokenId])];
		
        return output;
    }

    function getFirstStatValue(uint256 tokenId) public view returns (uint) {
        require(_exists(tokenId), "Nonexistent token");
		
        uint output;
		
		SourceData source_data = SourceData(dataContract);
		
		uint firstStatValue = source_data.getFirstStatValue(tokenId, rarity[tokenId]);
		
        output = (firstStatValue * getItemLevel(tokenId)) + 1;
		
        return output;
    }

    string[] private secondStat = [
        "Lockpicking",
        "Regeneration",
        "Armor",
        "Backpack",
        "Intelligence",
        "Charge",
        "Damage boost",
        "Reflexes",
        "Radar",
        "Keymaster",
        "Pickpocket",
        "EMP shield",
        "EMP power",
        "Run silent",
        "Nanotech"
    ];

    function getSecondStat(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = secondStat[source_data.getSecondStat(tokenId, rarity[tokenId])];
		
        return output;
    }

    function getSecondStatValue(uint256 tokenId) public view returns (uint) {
        require(_exists(tokenId), "Nonexistent token");
		
        uint output;
		
		SourceData source_data = SourceData(dataContract);
		
		uint secondStatValue = source_data.getSecondStatValue(tokenId, rarity[tokenId]);
		
        output = (secondStatValue * getItemLevel(tokenId)) + 1;
		
        return output;
    }

    string[] private firstAugment = [
        "Scrapper",
        "Bionic Arms",
        "Detoxifier",
        "Bionic Lungs",
        "Hardened Bones",
        "Berserk",
        "Blood pump",
        "Edge runner",
        "Adrenaline Pump",
        "Bloodware",
        "Cyber Joints",
        "Cloaking",
        "Nanobots",
        "Synthetic Heart",
        "?"
    ];

    function getFirstAugment(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = firstAugment[source_data.getFirstAugment(tokenId, rarity[tokenId])];
		
        return output;
    }

    string[] private secondAugment = [
        "Nightvision",
        "Titan Knuckles",
        "Cyber Legs",
        "Cyber Arms",
        "Reflex Boost",
        "Lizard skin",
        "Titanium Bones",
        "Echolocation",
        "Thermal vision",
        "X-ray Vision",
        "Shapeshifter",
        "Exoskeleton",
        "Stealth kit",
        "Double Heart",
        "?"
    ];

    function getSecondAugment(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = secondAugment[source_data.getSecondAugment(tokenId, rarity[tokenId])];
		
        return output;
    }

    function getAirdrops(uint256 tokenId) public view returns (uint) {
        require(_exists(tokenId), "Nonexistent token");
		
        uint output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = source_data.getAirdrops(tokenId, rarity[tokenId]) + getItemLevel(tokenId);
		
        return output;
    }
	
    string internal baseTokenURI;

	function setBaseTokenURI(string memory _uri) external onlyOwner {
        baseTokenURI = _uri;
    }

    string internal externalURI;

	function setExternalURI(string memory _uri) external onlyOwner {
        externalURI = _uri;
    }

	function tokenURI(uint _tokenId) public view override returns (string memory) {
        require(_exists(_tokenId), "Query for non-existent token!");

        string[7] memory json;

        json[0] = string(
			abi.encodePacked('{',
                '"name": "Cyber Upgrade #', t(_tokenId), ' (Level: ', t(getItemLevel(_tokenId)), ')",',
                '"image": "', baseTokenURI, t(rarity[_tokenId]), '.jpg",',
                '"external_url": "', externalURI, '?dna=', getDna(_tokenId) ,'&id=', t(_tokenId) ,'",',  
                '"description": "Upgrades waiting to be connected to players.",',
                '"attributes": ['
            )
		);

        json[1] = string(
			abi.encodePacked(
				'{',
					'"trait_type": "Rarity",',
					'"value": "', getRarity(_tokenId) ,'"',
                '},',
                '{',
                    '"trait_type": "Level",',
                    '"value": "', t(getItemLevel(_tokenId)) ,'"',
                '},'
            )
		);
        json[2] = string(
			abi.encodePacked(
				'{',
                    '"trait_type": "Upgrade #1",',
                    '"value": "', getFirstStat(_tokenId) , " +", t(getFirstStatValue(_tokenId)) ,'"',
                '},'
            )
		);

        json[3] = string(
			abi.encodePacked(
				'{',
                    '"trait_type": "Upgrade #2",',
                    '"value": "', getSecondStat(_tokenId) ," +", t(getSecondStatValue(_tokenId)) ,'"',
                '},'
            )
		);
        json[4] = string(
			abi.encodePacked(
				'{',
                    '"trait_type": "Augmentation #1",',
                    '"value": "', getFirstAugment(_tokenId) ,'"',
                '},'
            )
		);
        json[5] = string(
			abi.encodePacked(
                '{',
                    '"trait_type": "Augmentation #2",',
                    '"value": "', getSecondAugment(_tokenId) ,'"',
                '},',
                '{',
                    '"trait_type": "Airdrops",',
					'"value": "x', t(getAirdrops(_tokenId)) ,'"',
                '}'
            )
		);
        json[6] = string(
			abi.encodePacked('],',
                '"animation_url": "', externalURI, '?dna=', getDna(_tokenId) , '&id=', t(_tokenId) , '",',
                '"iframe_url": "', externalURI, '?dna=', getDna(_tokenId) , '&id=', t(_tokenId) , '"',
            '}')
		);

        string memory result = Base64.encode(
            bytes(
                string(
                    abi.encodePacked(
                        json[0],
                        json[1],
                        json[2],
                        json[3],
                        json[4],
                        json[5],
                        json[6]
                    )
                )
            )
        );

        return string(abi.encodePacked("data:application/json;base64,", result));
    }


	
	// helper
	function t(uint _tokenId) public pure returns (string memory) {
		return Strings.toString(_tokenId);
	}


    // Getters
    function getDna(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Query for non-existent token!");

        SourceData source_data = SourceData(dataContract);

        // First stat index
        uint firstStatIndex = source_data.getFirstStat(tokenId, rarity[tokenId]);

        // First stat index
        uint secondStatIndex = source_data.getSecondStat(tokenId, rarity[tokenId]);

        string[2] memory dna;

        dna[0] = string(
            abi.encodePacked(
                t(rarity[tokenId]), "-",
                t(levels[tokenId]), "-",
                t(firstStatIndex), "-",
                t(getFirstStatValue(tokenId)), "-"
            )
        );
        
        dna[1] = string(
			abi.encodePacked(
                t(secondStatIndex), "-",
                t(getSecondStatValue(tokenId)), "-",
                t(source_data.getFirstAugment(tokenId, rarity[tokenId])), "-",
                t(source_data.getSecondAugment(tokenId, rarity[tokenId])), "-",
                t(getAirdrops(tokenId))
            )
		);

        string memory result = string(
                    abi.encodePacked(
                        dna[0],
                        dna[1]
                    )
                );

        return string(abi.encodePacked(result));
    }

    function getItemLevel(uint256 tokenId) public view returns (uint) {
        return levels[tokenId];
    }

    function setItemLevel(uint tokenId, uint level) external {
        require(msg.sender == levelUpContract, "You can not call this");
        levels[tokenId] = level;
    }

	function whitelistClaim(bytes32[] memory proof, uint proofNumber) public nonReentrant payable {
        require(whitelistMintStart < block.timestamp, "Whitelist mint not started yet");
        require(maxTokens - total > vaultHolderReserves, "Minting over vault holder limit");
        require(total < maxTokens, "All tokens are already minted");
		require(msg.value == mintCost, "Incorrect mint cost value");
        require(_whitelistMinters[_msgSender()] < 1, "You've already minted");
		
		// Merkle tree validation
		bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
		require(MerkleProof.verify(proof, rootHashes[proofNumber], leaf), "Invalid proof");
		
		uint userTokens = proofNumber * 1000;
                
		// Proceed in minting process
		uint tokenId = getVRFRandomIndex(false, 0, userTokens);
		total++;

		// Set the _whitelistMinters value to tokenId for this address as it has minted
		_whitelistMinters[_msgSender()] = tokenId;

		_safeMint(_msgSender(), tokenId);
		
    }

    function publicClaim(uint numberOfTokens) public nonReentrant payable {
        require(publicMintStart < block.timestamp, "Public mint did not start yet");
        require(maxTokens - total > vaultHolderReserves, "Minting over vault holder limit");
        require(total + numberOfTokens < maxTokens, "All tokens are already minted");
        require(numberOfTokens > 0, "Can not mint zero tokens");
        require(numberOfTokens < 11, "Request exceeds max tokens");
		require(msg.value == publicMintCost * numberOfTokens, "Incorrect mint cost value");

        for (uint i=1; i < numberOfTokens; i++) {
            uint tokenId = getVRFRandomIndex(false, 0, 0);
            total++;
            _safeMint(_msgSender(), tokenId);
        }

    }

    function vaultHolderClaim(bytes32[] memory proof, uint proofNumber, uint[] memory vaultIds) public nonReentrant {
        require(whitelistMintStart < block.timestamp, "Whitelist mint not started yet");
        require(total + vaultIds.length < maxTokens, "Mint over the max tokens limit");

        for (uint i=0; i < vaultIds.length; i++) {
            require(validateVaultOwnership(vaultIds[i]), "Not Vault owner");
            require(!checkUsedVault(vaultIds[i]), "Vault was already used");
        }
		
		// This sender does not necessary need to have tokens, it is optional
        uint userTokens = 0;

        // Merkle tree for getting tokens
		bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
		
		if (MerkleProof.verify(proof, rootHashes[proofNumber], leaf) ) {

			userTokens = proofNumber * 1000;

		}

        for (uint i=0; i < vaultIds.length; i++) {

            // get vault rarity
            uint tokenId = getVRFRandomIndex(true, getVaultRarity(vaultIds[i]), userTokens);
            _usedVaults[vaultIds[i]] = true;

            total++;
            vaultHolderReserves--;
            _safeMint(_msgSender(), tokenId);
        }

    }
    
    function vaultHolderClaimCombined(bytes32[] memory proof, uint proofNumber, uint[] memory vaultIds) public nonReentrant payable {
        require(whitelistMintStart < block.timestamp, "Whitelist mint not started yet");
        require(total + 1 + vaultIds.length < maxTokens, "Mint over the max tokens limit");
        require(msg.value == mintCost, "Incorrect mint cost value");
        require(_whitelistMinters[_msgSender()] < 1, "You've already minted");

        for (uint i=0; i < vaultIds.length; i++) {
            require(validateVaultOwnership(vaultIds[i]), "Not Vault owner");
            require(!checkUsedVault(vaultIds[i]), "Vault was already used");
        }

        uint userTokens = 0;

        // Merkle tree for getting tokens
		bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
		require(MerkleProof.verify(proof, rootHashes[proofNumber], leaf), "Invalid proof");
		
        userTokens = proofNumber * 1000;

        // Continue minting process
        for (uint i=0; i < vaultIds.length; i++) {
            uint tokenId = getVRFRandomIndex(true, getVaultRarity(vaultIds[i]), userTokens);
            _usedVaults[vaultIds[i]] = true;

            total++;
            vaultHolderReserves--;
            _safeMint(_msgSender(), tokenId);
        }

        // + 1 for whitelist
        uint additionalTokenId = getVRFRandomIndex(false, 0, userTokens);
        total++;
        _whitelistMinters[_msgSender()] = additionalTokenId;
        _safeMint(_msgSender(), additionalTokenId);

    }

    function validateVaultOwnership(uint _vaultID) internal view returns(bool) {
        ERC721 vaultContractData = ERC721(vaultContract);
        if(vaultContractData.ownerOf(_vaultID) == msg.sender) {
            return true;
        }
        return false;
    }

    function checkUsedVault(uint _vaultID) internal view returns(bool) {
        if (_usedVaults[_vaultID] == true) {
            return true;
        }
        return false;
    }

    function vaultCheck(uint _vaultID) public view returns (bool) {
        if (_usedVaults[_vaultID] == true) {
            return true;
        }
        return false;
    }
	
    function getVaultRarity(uint _vaultID) public view returns (uint) {

		uint output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = source_data.getVaultRarity(_vaultID);
		
        return output;

    }

	function sysAdminClaim() public onlyOwner nonReentrant {
		require(sysAdminMinted == false, "Already minted!");
		
		sysAdminMinted = true;
		uint tokenId = getVRFRandomIndex(false, 0, 0);
        total++;
        _safeMint(owner(), tokenId);
    }

	function error404Claim() public nonReentrant {
		require(msg.sender == error404Address, "Not Error 404");
		require(error404Minted == false, "Already minted!");
		
		error404Minted = true;
		uint tokenId = getVRFRandomIndex(false, 0, 0);
        total++;
        _safeMint(msg.sender, tokenId);
    }
	
	function code200Claim() public nonReentrant {
		require(msg.sender == code200Address, "Not Code 200");
		require(code200Minted == false, "Already minted!");
		
		code200Minted = true;
		uint tokenId = getVRFRandomIndex(false, 0, 0);
        total++;
        _safeMint(msg.sender, tokenId);
    }
	
	function giveawaysClaim() public nonReentrant {
		require(msg.sender == giveawaysAddress, "Not Giveaways wallet");
		require(giveawaysMinted == false, "Already minted!");
		
		giveawaysMinted = true;

        for (uint i=0; i < 20; i++) {
            uint tokenId = getVRFRandomIndex(false, 0, 0);
            total++;
            _safeMint(msg.sender, tokenId);
        }
		
    }
	
    constructor() ERC721("Console NFT Cyber Upgrades", "Cnsl-NFT-U") VRFConsumerBase(
        0xf0d54349aDdcf704F77AE15b96510dEA15cb7952,
        0x514910771AF9Ca656af840dff83E8264EcF986CA
    ) 
	Ownable() {
        keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445;	
        fee = 2 * (10**18);
		
		error404Address = 0x24Db9e45f6aC29175030A083B985C184A02c2d64;
		code200Address = 0x1C0d3B190B18b4452BD4d0928D7f425eA9A0B3F9;
		giveawaysAddress = 0x7e95c71bDF0E0526eA534Fb5191ceD999190c117;

        whitelistMintStart = 1644330600; // 8. february 2022 - 14:30 UTC
        publicMintStart = 1644359400; // 8. february 2022 - 23:30 UTC (+8 hours)
        
        rarities.push(3250); // Common - 65%
        rarities.push(1000); // Uncommon - 20%
        rarities.push(475); // Rare - 9.5%
        rarities.push(225); // Epic - 4.5%
        rarities.push(50); // Legendary - 1%
    }


	////////////////////////// VRF /////////////////////////////
	
    bytes32 internal keyHash;
    uint internal fee;
    uint internal randomResult;
    
    // VRF Functions
    function getRandomNumber() public onlyOwner returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK!");
        return requestRandomness(keyHash, fee);
    }
    function fulfillRandomness(bytes32 requestId, uint randomness) internal override {
        randomResult = randomness;
    }
    function getRandomResult() public view onlyOwner returns (uint) {
        return randomResult;
    }

    // >>> Now, the VRF is stored in [uint internal randomResult]
    ////////////////////////// VRF /////////////////////////////

    /////////////////////// Token ID Generator ////////////////////////

    uint[maxTokens] internal indices;
    uint32 internal nonce;

    function getVRFRandomIndex(bool hasVault, uint vaultRarity, uint _userTokens) internal returns (uint) {
        require(randomResult != 0, "VRF Random Result has not been set!");

        // Get the random token ID
        uint _tokensRemaining = maxTokens - total; // require that this calculation is possible from all caller functions
        uint _maxIndex = _tokensRemaining == 0 ? 0 : _tokensRemaining - 1; // shorthand if for safety
        uint _rand = uint(keccak256(abi.encodePacked(randomResult, nonce, msg.sender, block.difficulty, block.timestamp))) % _tokensRemaining;
    
        uint _output = 0;

        _output = indices[_rand] != 0 ? indices[_rand] :_rand;
        indices[_rand] = indices[_maxIndex] == 0 ? _maxIndex : indices[_maxIndex];

        uint32 _nonceAdd = uint32(uint256(keccak256(abi.encodePacked(randomResult, nonce, msg.sender, block.difficulty, block.timestamp)))) % 10;
        nonce += _nonceAdd; 


        // Get the data from Percentage Contract
        PercentageGenerator percentage = PercentageGenerator(percentageContract);
        uint[] memory percentageArray = percentage.calculatePercentage(hasVault, vaultRarity, _userTokens);

        // Construct view array of 10k items to pick from
        // Because of rounding errors there might be close but not exactly 10k items, this should be safe
        uint totalItems;
        uint[] memory percentageNumbers = new uint[](5);
        for (uint i=0; i < percentageArray.length; i++) {
            totalItems += percentageArray[i];
            percentageNumbers[i] = totalItems;
        }

        // VRF guess the number in 10k items to get the rarity
        uint _randRarity = uint(keccak256(abi.encodePacked(randomResult, nonce, msg.sender, block.difficulty, block.timestamp))) % totalItems;

        uint rarityResult = 0; // Common as base

        // Get the rarity based on the VRF result
        if (_randRarity >= percentageNumbers[0] && _randRarity < percentageNumbers[1]) {
            rarityResult = 1; // Uncommon
        }
        if (_randRarity >= percentageNumbers[1] && _randRarity < percentageNumbers[2]) {
            rarityResult = 2; // Rare
        }
        if (_randRarity >= percentageNumbers[2] && _randRarity < percentageNumbers[3]) {
            rarityResult = 3; // Rpic
        }
        if (_randRarity >= percentageNumbers[3] && _randRarity <= percentageNumbers[4]) {
            rarityResult = 4; // Legendary
        }

        // If rarity no longer exist in the pool, give lower rarity
        if (rarities[rarityResult] > 0) {
            
            rarities[rarityResult]--;

            // There is still enough in the rarity pool
            // Assign rarity to this token ID
            rarity[_output] = rarityResult;

            // Assign starting level
            levels[_output] = 1;
        }
        else {
            // give other rarity, up or down
            rarity[_output] = pickOtherRarity(rarityResult);
        }

        return _output;
    }

    function pickOtherRarity(uint rarityResult) internal returns (uint) {
		
		bool direction; // default false = down
		
        if (rarities[rarityResult] > 0) {
            return rarityResult;
        }
        else {
            if(rarityResult == 4){	
                direction = false;
            }
            if(rarityResult == 0){
                direction = true;
        	}
            if(direction == true){ 
                rarityResult++;
            } else {
                rarityResult--;
            }
            if( rarities[rarityResult] > 0 ) {	
                return rarityResult;
            } else {
                return pickOtherRarity(rarityResult);
            }
        }

    }

    /////////////////////// Token ID Generator ////////////////////////
	
	// Withdraw Ether
    function withdrawEther() public onlyOwner {
        payable(msg.sender).transfer(address(this).balance); 
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"code200Claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"error404Claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getAirdrops","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDna","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstAugment","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstStat","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstStatValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getItemLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRandomNumber","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRandomResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRarity","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSecondAugment","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSecondStat","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSecondStatValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultID","type":"uint256"}],"name":"getVaultRarity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"giveawaysClaim","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"levels","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"numberOfTokens","type":"uint256"}],"name":"publicClaim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicMintStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rarities","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rarity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rootHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"_uri","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setExternalURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setItemLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_levelUpContract","type":"address"}],"name":"setLevelUpContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_rootHash","type":"bytes32[]"}],"name":"setMerkleHashes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_percentageContract","type":"address"}],"name":"setPercentageContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setPublicMintStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dataContract","type":"address"}],"name":"setSourceData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultContract","type":"address"}],"name":"setVaultContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setWhitelistMintStart","outputs":[],"stateMutability":"nonpayable","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":[],"name":"sysAdminClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"t","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","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":[],"name":"total","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":"uint256","name":"_vaultID","type":"uint256"}],"name":"vaultCheck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"proofNumber","type":"uint256"},{"internalType":"uint256[]","name":"vaultIds","type":"uint256[]"}],"name":"vaultHolderClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"proofNumber","type":"uint256"},{"internalType":"uint256[]","name":"vaultIds","type":"uint256[]"}],"name":"vaultHolderClaimCombined","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"vaultHolderReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"proofNumber","type":"uint256"}],"name":"whitelistClaim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistMintStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101f4601455600060165566b1a2bc2ec5000060175567016345785d8a000060185560066101609081526521b7b6b6b7b760d11b6101805260c090815260086101a0908152672ab731b7b6b6b7b760c11b6101c05260e05260046101e0818152635261726560e01b6102005261010052610220908152634570696360e01b61024052610120526102a06040526009610260908152684c6567656e6461727960b81b6102805261014052620000b890602090600562000c08565b50604080516102208101825260066101e0820190815265090cac2d8e8d60d31b6102008301528152815180830183526008808252670a6e8e4cadccee8d60c31b6020838101919091528084019290925283518085018552600581526414dc19595960da1b81840152838501528351808501855290815267416363757261637960c01b81830152606083015282518084018452600c8082526b496e74656c6c6967656e636560a01b8284015260808401919091528351808501855260048152630a8cac6d60e31b8184015260a084015283518085018552600a815269121858dac81cdc19595960b21b8184015260c084015283518085018552600981526814d453081cdada5b1b60ba1b8184015260e0840152835180850185526007808252664e6574776f726b60c81b82850152610100850191909152845180860186526003815262444e4160e81b818501526101208501528451808601865281815266088ca5ac2eae8d60cb1b81850152610140850152845180860186528281526b50776420637261636b696e6760a01b8185015261016085015284518086018652600b81526a58535320666f726765727960a81b818501526101808501528451808601865290815266111958dc9e5c1d60ca1b818401526101a0840152835180850190945283526b43727970746f67726170687960a01b908301526101c0810191909152620002c790602190600f62000c6c565b506040805161022081018252600b6101e082019081526a4c6f636b7069636b696e6760a81b610200830152815281518083018352600c8082526b2932b3b2b732b930ba34b7b760a11b602083810191909152808401929092528351808501855260058082526420b936b7b960d91b8285015284860191909152845180860186526008808252674261636b7061636b60c01b828601526060860191909152855180870187528381526b496e74656c6c6967656e636560a01b81860152608086015285518087018752600681526543686172676560d01b8186015260a0860152855180870187529283526b11185b5859d948189bdbdcdd60a21b8385015260c085019290925284518086018652828152675265666c6578657360c01b8185015260e085015284518086018652908152642930b230b960d91b818401526101008401528351808501855260098082526825b2bcb6b0b9ba32b960b91b8285015261012085019190915284518086018652600a80825269141a58dadc1bd8dad95d60b21b828601526101408601919091528551808701875281815269115354081cda1a595b1960b21b81860152610160860152855180870187529182526822a6a8103837bbb2b960b91b828501526101808501919091528451808601865290815269149d5b881cda5b195b9d60b21b818401526101a0840152835180850190945283526709cc2dcdee8cac6d60c31b908301526101c0810191909152620004ef90602290600f62000c6c565b50604051806101e001604052806040518060400160405280600881526020016729b1b930b83832b960c11b81525081526020016040518060400160405280600b81526020016a42696f6e69632041726d7360a81b81525081526020016040518060400160405280600a8152602001692232ba37bc34b334b2b960b11b81525081526020016040518060400160405280600c81526020016b42696f6e6963204c756e677360a01b81525081526020016040518060400160405280600e81526020016d48617264656e656420426f6e657360901b8152508152602001604051806040016040528060078152602001664265727365726b60c81b81525081526020016040518060400160405280600a8152602001690426c6f6f642070756d760b41b81525081526020016040518060400160405280600b81526020016a22b233b290393ab73732b960a91b81525081526020016040518060400160405280600f81526020016e0416472656e616c696e652050756d7608c1b815250815260200160405180604001604052806009815260200168426c6f6f647761726560b81b81525081526020016040518060400160405280600c81526020016b4379626572204a6f696e747360a01b815250815260200160405180604001604052806008815260200167436c6f616b696e6760c01b8152508152602001604051806040016040528060088152602001674e616e6f626f747360c01b81525081526020016040518060400160405280600f81526020016e14de5b9d1a195d1a58c81219585c9d608a1b8152508152602001604051806040016040528060018152602001603f60f81b815250815250602390600f6200076592919062000c6c565b506040805161022081018252600b6101e082018181526a2734b3b43a3b34b9b4b7b760a91b610200840152825282518084018452600e8082526d546974616e204b6e75636b6c657360901b6020838101919091528085019290925284518086018652600a808252694379626572204c65677360b01b8285015285870191909152855180870187529081526943796265722041726d7360b01b81840152606085015284518086018652600c8082526b1499599b195e08109bdbdcdd60a21b828501526080860191909152855180870187528481526a2634bd30b9321039b5b4b760a91b8185015260a0860152855180870187528281526d546974616e69756d20426f6e657360901b8185015260c0860152855180870187528181526b22b1b437b637b1b0ba34b7b760a11b8185015260e0860152855180870187529182526d2a3432b936b0b6103b34b9b4b7b760911b82840152610100850191909152845180860186528181526b2c16b930bc902b34b9b4b7b760a11b81840152610120850152845180860186528181526b29b430b832b9b434b33a32b960a11b81840152610140850152845180860186528381526a22bc37b9b5b2b632ba37b760a91b81840152610160850152845180860186529283526a14dd19585b1d1a081ada5d60aa1b83830152610180840192909252835180850185529182526b111bdd589b19481219585c9d60a21b828201526101a0830191909152825180840190935260018352603f60f81b908301526101c0810191909152620009a790602490600f62000c6c565b50348015620009b557600080fd5b50604080518082018252601a81527f436f6e736f6c65204e465420437962657220557067726164657300000000000060208083019182528351808501909452600a845269436e736c2d4e46542d5560b01b90840152815173f0d54349addcf704f77ae15b96510dea15cb79529373514910771af9ca656af840dff83e8264ecf986ca9392909162000a499160009162000cbe565b50805162000a5f90600190602084019062000cbe565b50506001600a555062000a723362000bb6565b6001600160601b0319606092831b811660a052911b166080527faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445602755671bc16d674ec80000602855601b80547724db9e45f6ac29175030a083b985c184a02c2d6400000000600160201b600160c01b0319909116179055601c80546001600160a01b0319908116731c0d3b190b18b4452bd4d0928d7f425ea9a0b3f917909155601d8054909116737e95c71bdf0e0526ea534fb5191ced999190c1171790556362027e68601955636202eee8601a5560158054600181810183556000839052610cb27f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47592830155825480820184556103e890830155825480820184556101db908301558254808201845560e1908301558254908101909255603291015562000e00565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805482825590600052602060002090810192821562000c5a579160200282015b8281111562000c5a578251805162000c4991849160209091019062000cbe565b509160200191906001019062000c29565b5062000c6892915062000d49565b5090565b82805482825590600052602060002090810192821562000c5a579160200282015b8281111562000c5a578251805162000cad91849160209091019062000cbe565b509160200191906001019062000c8d565b82805462000ccc9062000dc3565b90600052602060002090601f01602090048101928262000cf0576000855562000d3b565b82601f1062000d0b57805160ff191683800117855562000d3b565b8280016001018555821562000d3b579182015b8281111562000d3b57825182559160200191906001019062000d1e565b5062000c6892915062000d6a565b8082111562000c6857600062000d60828262000d81565b5060010162000d49565b5b8082111562000c68576000815560010162000d6b565b50805462000d8f9062000dc3565b6000825580601f1062000da0575050565b601f01602090049060005260206000209081019062000dc0919062000d6a565b50565b600181811c9082168062000dd857607f821691505b6020821081141562000dfa57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160601c615b9862000e3a600039600081816128f20152613f8f0152600081816130830152613f600152615b986000f3fe6080604052600436106103b85760003560e01c8063666c27d4116101f2578063a272fbae1161010d578063d08b4add116100a0578063e985e9c51161006f578063e985e9c514610acf578063f2fde38b14610b18578063fc59d96214610b38578063fdda339114610b4d57600080fd5b8063d08b4add14610a64578063d5a10a1514610a84578063dbdff2c114610aa4578063e831574214610ab957600080fd5b8063b2596a67116100dc578063b2596a67146109d7578063b88d4fde14610a04578063c87b56dd14610a24578063caf7c44514610a4457600080fd5b8063a272fbae1461096d578063aeceadbf1461098d578063afe29f71146109a2578063b102b6bc146109c257600080fd5b80638cfec4c0116101855780638f5dac6e116101545780638f5dac6e1461090557806394985ddd1461091857806395d89b4114610938578063a22cb4651461094d57600080fd5b80638cfec4c0146108915780638da5cb5b146108a75780638eb8c81c146108c55780638ebb25ca146108e557600080fd5b80637390c786116101c15780637390c7861461080f5780637d91b7b214610824578063871105cc146108445780638b58c5691461086457600080fd5b8063666c27d4146107a557806370a08231146107c5578063715018a6146107e55780637362377b146107fa57600080fd5b806330176e13116102e25780634f6ccce7116102755780635aa28742116102445780635aa28742146107235780635d41c19c14610743578063601fb175146107585780636352211e1461078557600080fd5b80634f6ccce7146106b057806350d5e770146106d057806353b93557146106e3578063556b5dd41461070357600080fd5b806342842e0e116102b157806342842e0e146106305780634336316c14610650578063434b3c1214610670578063487586971461069057600080fd5b806330176e13146105bd578063383aa784146105dd578063422627c3146105f05780634233429c1461061057600080fd5b806317b8e1cf1161035a57806323b872dd1161032957806323b872dd14610547578063276aeac1146105675780632ddbd13a146105875780632f745c591461059d57600080fd5b806317b8e1cf146104d257806318160ddd146104f2578063216c3019146105075780632374c9241461052757600080fd5b8063081812fc11610396578063081812fc14610438578063095ea7b31461047057806313e46f74146104925780631710fef8146104b257600080fd5b806301de34f8146103bd57806301ffc9a7146103e657806306fdde0314610416575b600080fd5b3480156103c957600080fd5b506103d360145481565b6040519081526020015b60405180910390f35b3480156103f257600080fd5b50610406610401366004614c96565b610b63565b60405190151581526020016103dd565b34801561042257600080fd5b5061042b610b8e565b6040516103dd91906156f7565b34801561044457600080fd5b50610458610453366004614d19565b610c20565b6040516001600160a01b0390911681526020016103dd565b34801561047c57600080fd5b5061049061048b366004614a4e565b610cad565b005b34801561049e57600080fd5b506104906104ad366004614af4565b610dc3565b3480156104be57600080fd5b506104906104cd3660046148ec565b6110a3565b3480156104de57600080fd5b506103d36104ed366004614d19565b6110ef565b3480156104fe57600080fd5b506008546103d3565b34801561051357600080fd5b50610406610522366004614d19565b611110565b34801561053357600080fd5b5061042b610542366004614d19565b61113c565b34801561055357600080fd5b5061049061056236600461495f565b6112ae565b34801561057357600080fd5b5061042b610582366004614d19565b6112df565b34801561059357600080fd5b506103d360165481565b3480156105a957600080fd5b506103d36105b8366004614a4e565b611355565b3480156105c957600080fd5b506104906105d8366004614cd0565b6113eb565b6104906105eb366004614aaf565b61142c565b3480156105fc57600080fd5b5061042b61060b366004614d19565b611696565b34801561061c57600080fd5b5061049061062b366004614d19565b611a0a565b34801561063c57600080fd5b5061049061064b36600461495f565b611a39565b34801561065c57600080fd5b5061049061066b3660046148ec565b611a54565b34801561067c57600080fd5b5061049061068b3660046148ec565b611aa0565b34801561069c57600080fd5b5061042b6106ab366004614d19565b611aec565b3480156106bc57600080fd5b506103d36106cb366004614d19565b611bd6565b6104906106de366004614af4565b611c69565b3480156106ef57600080fd5b506103d36106fe366004614d19565b612007565b34801561070f57600080fd5b506103d361071e366004614d19565b612017565b34801561072f57600080fd5b506103d361073e366004614d19565b612106565b34801561074f57600080fd5b506104906121df565b34801561076457600080fd5b506103d3610773366004614d19565b6000908152601e602052604090205490565b34801561079157600080fd5b506104586107a0366004614d19565b6122c0565b3480156107b157600080fd5b5061042b6107c0366004614d19565b612337565b3480156107d157600080fd5b506103d36107e03660046148ec565b6123ad565b3480156107f157600080fd5b50610490612434565b34801561080657600080fd5b5061049061246a565b34801561081b57600080fd5b506103d36124c3565b34801561083057600080fd5b5061049061083f366004614a7a565b6124f7565b34801561085057600080fd5b5061049061085f3660046148ec565b612590565b34801561087057600080fd5b506103d361087f366004614d19565b601f6020526000908152604090205481565b34801561089d57600080fd5b506103d3601a5481565b3480156108b357600080fd5b50600b546001600160a01b0316610458565b3480156108d157600080fd5b506103d36108e0366004614d19565b6125dc565b3480156108f157600080fd5b50610490610900366004614d19565b61265f565b610490610913366004614d19565b61268e565b34801561092457600080fd5b50610490610933366004614c74565b6128e7565b34801561094457600080fd5b5061042b612965565b34801561095957600080fd5b50610490610968366004614a20565b612974565b34801561097957600080fd5b5061042b610988366004614d19565b612a39565b34801561099957600080fd5b50610490612aaf565b3480156109ae57600080fd5b5061042b6109bd366004614d19565b612b6a565b3480156109ce57600080fd5b50610490612b75565b3480156109e357600080fd5b506103d36109f2366004614d19565b601e6020526000908152604090205481565b348015610a1057600080fd5b50610490610a1f3660046149a0565b612c33565b348015610a3057600080fd5b5061042b610a3f366004614d19565b612c6b565b348015610a5057600080fd5b50610490610a5f366004614c74565b612f2a565b348015610a7057600080fd5b50610490610a7f366004614cd0565b612f8e565b348015610a9057600080fd5b506103d3610a9f366004614d19565b612fcb565b348015610ab057600080fd5b506103d361303e565b348015610ac557600080fd5b506103d361138881565b348015610adb57600080fd5b50610406610aea366004614926565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610b2457600080fd5b50610490610b333660046148ec565b613159565b348015610b4457600080fd5b506104906131f1565b348015610b5957600080fd5b506103d360195481565b60006001600160e01b0319821663780e9d6360e01b1480610b885750610b88826132f6565b92915050565b606060008054610b9d906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc9906159f4565b8015610c165780601f10610beb57610100808354040283529160200191610c16565b820191906000526020600020905b815481529060010190602001808311610bf957829003601f168201915b5050505050905090565b6000610c2b82613346565b610c915760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610cb8826122c0565b9050806001600160a01b0316836001600160a01b03161415610d265760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c88565b336001600160a01b0382161480610d425750610d428133610aea565b610db45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610c88565b610dbe8383613363565b505050565b6002600a541415610de65760405162461bcd60e51b8152600401610c889061587b565b6002600a556019544211610e0c5760405162461bcd60e51b8152600401610c88906157be565b6113888151601654610e1e9190615930565b10610e6b5760405162461bcd60e51b815260206004820152601e60248201527f4d696e74206f76657220746865206d617820746f6b656e73206c696d697400006044820152606401610c88565b60005b8151811015610f5157610e99828281518110610e8c57610e8c615abd565b60200260200101516133d1565b610ed75760405162461bcd60e51b815260206004820152600f60248201526e2737ba102b30bab63a1037bbb732b960891b6044820152606401610c88565b610ef9828281518110610eec57610eec615abd565b6020026020010151611110565b15610f3f5760405162461bcd60e51b815260206004820152601660248201527515985d5b1d081dd85cc8185b1c9958591e481d5cd95960521b6044820152606401610c88565b80610f4981615a29565b915050610e6e565b506040516001600160601b03193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050610fb08560138681548110610f9f57610f9f615abd565b906000526020600020015483613473565b15610fc457610fc1846103e861597b565b91505b60005b8351811015611096576000610fff6001610ff9878581518110610fec57610fec615abd565b60200260200101516125dc565b86613489565b905060016011600087858151811061101957611019615abd565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055506016600081548092919061105990615a29565b90915550506014805490600061106e836159dd565b919050555061108361107d3390565b826139c8565b508061108e81615a29565b915050610fc7565b50506001600a5550505050565b600b546001600160a01b031633146110cd5760405162461bcd60e51b8152600401610c88906157f5565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b601581815481106110ff57600080fd5b600091825260209091200154905081565b60008181526011602052604081205460ff1615156001141561113457506001919050565b506000919050565b606061114782613346565b6111635760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051631ef2f77160e01b81526060926001600160a01b0316916022918391631ef2f771916111b2918991600401918252602082015260400190565b60206040518083038186803b1580156111ca57600080fd5b505afa1580156111de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112029190614d32565b8154811061121257611212615abd565b906000526020600020018054611227906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611253906159f4565b80156112a05780601f10611275576101008083540402835291602001916112a0565b820191906000526020600020905b81548152906001019060200180831161128357829003601f168201915b509398975050505050505050565b6112b833826139e2565b6112d45760405162461bcd60e51b8152600401610c889061582a565b610dbe838383613ac8565b60606112ea82613346565b6113065760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051632311963b60e01b81526060926001600160a01b0316916021918391632311963b916111b2918991600401918252602082015260400190565b6000611360836123ad565b82106113c25760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c88565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600b546001600160a01b031633146114155760405162461bcd60e51b8152600401610c88906157f5565b805161142890602590602084019061470e565b5050565b6002600a54141561144f5760405162461bcd60e51b8152600401610c889061587b565b6002600a5560195442116114755760405162461bcd60e51b8152600401610c88906157be565b6014546016546114879061138861599a565b116114d45760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e67206f766572207661756c7420686f6c646572206c696d6974006044820152606401610c88565b611388601654106115275760405162461bcd60e51b815260206004820152601d60248201527f416c6c20746f6b656e732061726520616c7265616479206d696e7465640000006044820152606401610c88565b60175434146115485760405162461bcd60e51b8152600401610c889061575c565b3360009081526012602052604090205460011161159f5760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610c88565b6040516001600160601b03193360601b1660208201526000906034016040516020818303038152906040528051906020012090506115ea8360138481548110610f9f57610f9f615abd565b6116265760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610c88565b6000611634836103e861597b565b9050600061164460008084613489565b60168054919250600061165683615a29565b919050555080601260006116673390565b6001600160a01b0316815260208101919091526040016000205561168a3361107d565b50506001600a55505050565b60606116a182613346565b6116ed5760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610c88565b600d546000838152601f6020526040808220549051632311963b60e01b81526001600160a01b03909316928391632311963b91611737918891600401918252602082015260400190565b60206040518083038186803b15801561174f57600080fd5b505afa158015611763573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117879190614d32565b6000858152601f6020526040808220549051631ef2f77160e01b8152600481018890526024810191909152919250906001600160a01b03841690631ef2f7719060440160206040518083038186803b1580156117e257600080fd5b505afa1580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190614d32565b9050611824614792565b6000868152601f602052604090205461183c90612b6a565b6000878152601e602052604090205461185490612b6a565b61185d85612b6a565b6118696109bd8a612017565b60405160200161187c9493929190614f0a565b60408051808303601f19018152919052815261189782612b6a565b6118a36109bd88612fcb565b6000888152601f6020526040908190205490516307568f4b60e01b8152600481018a90526024810191909152611938906001600160a01b038816906307568f4b906044015b60206040518083038186803b15801561190057600080fd5b505afa158015611914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bd9190614d32565b6000898152601f602052604090819020549051637c9cead360e01b8152600481018b90526024810191909152611981906001600160a01b03891690637c9cead3906044016118e8565b61198d6109bd8b612106565b6040516020016119a1959493929190614f8b565b60408051808303601f190181529181526020808401839052835191516000936119cd9392909101614e49565b6040516020818303038152906040529050806040516020016119ef9190614e2d565b60405160208183030381529060405295505050505050919050565b600b546001600160a01b03163314611a345760405162461bcd60e51b8152600401610c88906157f5565b601955565b610dbe83838360405180602001604052806000815250612c33565b600b546001600160a01b03163314611a7e5760405162461bcd60e51b8152600401610c88906157f5565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b600b546001600160a01b03163314611aca5760405162461bcd60e51b8152600401610c88906157f5565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6060611af782613346565b611b135760405162461bcd60e51b8152600401610c8890615793565b60606020601f60008581526020019081526020016000205481548110611b3b57611b3b615abd565b906000526020600020018054611b50906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7c906159f4565b8015611bc95780601f10611b9e57610100808354040283529160200191611bc9565b820191906000526020600020905b815481529060010190602001808311611bac57829003601f168201915b5093979650505050505050565b6000611be160085490565b8210611c445760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c88565b60088281548110611c5757611c57615abd565b90600052602060002001549050919050565b6002600a541415611c8c5760405162461bcd60e51b8152600401610c889061587b565b6002600a556019544211611cb25760405162461bcd60e51b8152600401610c88906157be565b61138881516016546001611cc69190615930565b611cd09190615930565b10611d1d5760405162461bcd60e51b815260206004820152601e60248201527f4d696e74206f76657220746865206d617820746f6b656e73206c696d697400006044820152606401610c88565b6017543414611d3e5760405162461bcd60e51b8152600401610c889061575c565b33600090815260126020526040902054600111611d955760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610c88565b60005b8151811015611e6157611db6828281518110610e8c57610e8c615abd565b611df45760405162461bcd60e51b815260206004820152600f60248201526e2737ba102b30bab63a1037bbb732b960891b6044820152606401610c88565b611e09828281518110610eec57610eec615abd565b15611e4f5760405162461bcd60e51b815260206004820152601660248201527515985d5b1d081dd85cc8185b1c9958591e481d5cd95960521b6044820152606401610c88565b80611e5981615a29565b915050611d98565b506040516001600160601b03193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050611eaf8560138681548110610f9f57610f9f615abd565b611eeb5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610c88565b611ef7846103e861597b565b915060005b8351811015611fb2576000611f216001610ff9878581518110610fec57610fec615abd565b9050600160116000878581518110611f3b57611f3b615abd565b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555060166000815480929190611f7b90615a29565b909155505060148054906000611f90836159dd565b9190505550611f9f61107d3390565b5080611faa81615a29565b915050611efc565b506000611fc160008085613489565b601680549192506000611fd383615a29565b91905055508060126000611fe43390565b6001600160a01b031681526020810191909152604001600020556110963361107d565b601381815481106110ff57600080fd5b600061202282613346565b61203e5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604080822054905163d913a56760e01b815260048101869052602481019190915290916001600160a01b0316908290829063d913a567906044015b60206040518083038186803b15801561209e57600080fd5b505afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190614d32565b6000868152601e60205260409020549091506120f2908261597b565b6120fd906001615930565b95945050505050565b600061211182613346565b61212d5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601e6020908152604080832054601f909252808320549051633570d40760e11b815260048101879052602481019190915291926001600160a01b0316918290636ae1a80e9060440160206040518083038186803b15801561219557600080fd5b505afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190614d32565b6121d79190615930565b949350505050565b6002600a5414156122025760405162461bcd60e51b8152600401610c889061587b565b6002600a55601c546001600160a01b031633146122505760405162461bcd60e51b815260206004820152600c60248201526b04e6f7420436f6465203230360a41b6044820152606401610c88565b601b5462010000900460ff16156122795760405162461bcd60e51b8152600401610c88906158b2565b601b805462ff00001916620100001790556000612297818080613489565b6016805491925060006122a983615a29565b91905055506122b833826139c8565b506001600a55565b6000818152600260205260408120546001600160a01b031680610b885760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610c88565b606061234282613346565b61235e5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051637c9cead360e01b81526060926001600160a01b0316916024918391637c9cead3916111b2918991600401918252602082015260400190565b60006001600160a01b0382166124185760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610c88565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b0316331461245e5760405162461bcd60e51b8152600401610c88906157f5565b6124686000613c73565b565b600b546001600160a01b031633146124945760405162461bcd60e51b8152600401610c88906157f5565b60405133904780156108fc02916000818181858888f193505050501580156124c0573d6000803e3d6000fd5b50565b600b546000906001600160a01b031633146124f05760405162461bcd60e51b8152600401610c88906157f5565b5060295490565b600b546001600160a01b031633146125215760405162461bcd60e51b8152600401610c88906157f5565b604080516000815260208101918290525161253e916013916147b9565b5060005b815181101561142857601382828151811061255f5761255f615abd565b602090810291909101810151825460018101845560009384529190922001558061258881615a29565b915050612542565b600b546001600160a01b031633146125ba5760405162461bcd60e51b8152600401610c88906157f5565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600d546040516323ae320760e21b81526004810183905260009182916001600160a01b03909116908190638eb8c81c9060240160206040518083038186803b15801561262757600080fd5b505afa15801561263b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d79190614d32565b600b546001600160a01b031633146126895760405162461bcd60e51b8152600401610c88906157f5565b601a55565b6002600a5414156126b15760405162461bcd60e51b8152600401610c889061587b565b6002600a55601a5442116127075760405162461bcd60e51b815260206004820152601d60248201527f5075626c6963206d696e7420646964206e6f74207374617274207965740000006044820152606401610c88565b6014546016546127199061138861599a565b116127665760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e67206f766572207661756c7420686f6c646572206c696d6974006044820152606401610c88565b611388816016546127779190615930565b106127c45760405162461bcd60e51b815260206004820152601d60248201527f416c6c20746f6b656e732061726520616c7265616479206d696e7465640000006044820152606401610c88565b600081116128145760405162461bcd60e51b815260206004820152601860248201527f43616e206e6f74206d696e74207a65726f20746f6b656e7300000000000000006044820152606401610c88565b600b81106128645760405162461bcd60e51b815260206004820152601a60248201527f526571756573742065786365656473206d617820746f6b656e730000000000006044820152606401610c88565b80601854612872919061597b565b34146128905760405162461bcd60e51b8152600401610c889061575c565b60015b818110156128de5760006128aa6000806000613489565b6016805491925060006128bc83615a29565b91905055506128cb61107d3390565b50806128d681615a29565b915050612893565b50506001600a55565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461295f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610c88565b60295550565b606060018054610b9d906159f4565b6001600160a01b0382163314156129cd5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c88565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060612a4482613346565b612a605760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f6020526040908190205490516307568f4b60e01b81526060926001600160a01b03169160239183916307568f4b916111b2918991600401918252602082015260400190565b600b546001600160a01b03163314612ad95760405162461bcd60e51b8152600401610c88906157f5565b6002600a541415612afc5760405162461bcd60e51b8152600401610c889061587b565b6002600a55601b5460ff1615612b245760405162461bcd60e51b8152600401610c88906158b2565b601b805460ff191660011790556000612b3e818080613489565b601680549192506000612b5083615a29565b91905055506122b861107d600b546001600160a01b031690565b6060610b8882613cc5565b6002600a541415612b985760405162461bcd60e51b8152600401610c889061587b565b6002600a55601b5464010000000090046001600160a01b03163314612bef5760405162461bcd60e51b815260206004820152600d60248201526c139bdd08115c9c9bdc880d0c0d609a1b6044820152606401610c88565b601b54610100900460ff1615612c175760405162461bcd60e51b8152600401610c88906158b2565b601b805461ff0019166101001790556000612297818080613489565b612c3d33836139e2565b612c595760405162461bcd60e51b8152600401610c889061582a565b612c6584848484613dc3565b50505050565b6060612c7682613346565b612cc25760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610c88565b612cca6147f3565b612cd383612b6a565b6000848152601e6020526040902054612ceb90612b6a565b6000858152601f6020526040902054602590612d0690612b6a565b6026612d1188611696565b612d1a89612b6a565b604051602001612d3097969594939291906151d2565b60408051808303601f190181529190528152612d4b83611aec565b6000848152601e6020526040902054612d6390612b6a565b604051602001612d749291906154e7565b60408051808303601f190181529190526020820152612d92836112df565b612d9e6109bd85612017565b604051602001612daf9291906155bb565b60408051808303601f19018152918152820152612dcb8361113c565b612dd76109bd85612fcb565b604051602001612de8929190615135565b60408051808303601f190181529190526060820152612e0683612a39565b604051602001612e16919061538a565b60408051808303601f190181529190526080820152612e3483612337565b612e406109bd85612106565b604051602001612e51929190615403565b60408051808303601f1901815291905260a08201526026612e7184611696565b612e7a85612b6a565b6026612e8587611696565b612e8e88612b6a565b604051602001612ea396959493929190615021565b60408051808303601f1901815291815260c083018290528251602080850151858401516060870151608088015160a08901519651600098612eff98612eeb9897909201614e78565b604051602081830303815290604052613df6565b905080604051602001612f129190615611565b60405160208183030381529060405292505050919050565b6010546001600160a01b03163314612f7c5760405162461bcd60e51b8152602060048201526015602482015274596f752063616e206e6f742063616c6c207468697360581b6044820152606401610c88565b6000918252601e602052604090912055565b600b546001600160a01b03163314612fb85760405162461bcd60e51b8152600401610c88906157f5565b805161142890602690602084019061470e565b6000612fd682613346565b612ff25760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f60205260408082205490516349ec3c7160e11b815260048101869052602481019190915290916001600160a01b031690829082906393d878e290604401612086565b600b546000906001600160a01b0316331461306b5760405162461bcd60e51b8152600401610c88906157f5565b6028546040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b1580156130cd57600080fd5b505afa1580156130e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131059190614d32565b10156131465760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204c494e4b2160801b6044820152606401610c88565b613154602754602854613f5c565b905090565b600b546001600160a01b031633146131835760405162461bcd60e51b8152600401610c88906157f5565b6001600160a01b0381166131e85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c88565b6124c081613c73565b6002600a5414156132145760405162461bcd60e51b8152600401610c889061587b565b6002600a55601d546001600160a01b0316331461326a5760405162461bcd60e51b8152602060048201526014602482015273139bdd0811da5d99585dd85e5cc81dd85b1b195d60621b6044820152606401610c88565b601b546301000000900460ff16156132945760405162461bcd60e51b8152600401610c88906158b2565b601b805463ff0000001916630100000017905560005b60148110156122b85760006132c26000806000613489565b6016805491925060006132d483615a29565b91905055506132e333826139c8565b50806132ee81615a29565b9150506132aa565b60006001600160e01b031982166380ac58cd60e01b148061332757506001600160e01b03198216635b5e139f60e01b145b80610b8857506301ffc9a760e01b6001600160e01b0319831614610b88565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613398826122c0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600f546040516331a9108f60e11b8152600481018390526000916001600160a01b03169033908290636352211e9060240160206040518083038186803b15801561341a57600080fd5b505afa15801561342e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134529190614909565b6001600160a01b0316141561346a5750600192915050565b50600092915050565b60008261348085846140e7565b14949350505050565b6000602954600014156134ea5760405162461bcd60e51b815260206004820152602360248201527f5652462052616e646f6d20526573756c7420686173206e6f74206265656e207360448201526265742160e81b6064820152608401610c88565b60006016546113886134fc919061599a565b9050600081156135165761351160018361599a565b613519565b60005b6029546113b254604051929350600092859261354892909163ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c61356b9190615a44565b90506000602a82611388811061358357613583615abd565b015461358f57816135a6565b602a8261138881106135a3576135a3615abd565b01545b9050602a8361138881106135bc576135bc615abd565b0154156135de57602a8361138881106135d7576135d7615abd565b01546135e0565b825b602a8361138881106135f4576135f4615abd565b01556029546113b254604051600092600a926136219263ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c6136449190615a58565b6113b28054919250829160009061366290849063ffffffff16615948565b825463ffffffff9182166101009390930a928302919092021990911617905550600e546040516375cf69f960e01b81528a15156004820152602481018a9052604481018990526001600160a01b039091169060009082906375cf69f99060640160006040518083038186803b1580156136da57600080fd5b505afa1580156136ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137169190810190614bbf565b60408051600580825260c0820190925291925060009182916020820160a08036833701905050905060005b83518110156137a15783818151811061375c5761375c615abd565b60200260200101518361376f9190615930565b92508282828151811061378457613784615abd565b60209081029190910101528061379981615a29565b915050613741565b506029546113b25460405160009285926137cc9263ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c6137ef9190615a44565b905060008260008151811061380657613806615abd565b6020026020010151821015801561383657508260018151811061382b5761382b615abd565b602002602001015182105b1561383f575060015b8260018151811061385257613852615abd565b6020026020010151821015801561388257508260028151811061387757613877615abd565b602002602001015182105b1561388b575060025b8260028151811061389e5761389e615abd565b602002602001015182101580156138ce5750826003815181106138c3576138c3615abd565b602002602001015182105b156138d7575060035b826003815181106138ea576138ea615abd565b6020026020010151821015801561391b57508260048151811061390f5761390f615abd565b60200260200101518211155b15613924575060045b60006015828154811061393957613939615abd565b9060005260206000200154111561399c576015818154811061395d5761395d615abd565b60009182526020822001805491613973836159dd565b90915550506000888152601f60209081526040808320849055601e9091529020600190556139b5565b6139a581614193565b6000898152601f60205260409020555b50959d9c50505050505050505050505050565b611428828260405180602001604052806000815250614247565b60006139ed82613346565b613a4e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610c88565b6000613a59836122c0565b9050806001600160a01b0316846001600160a01b03161480613a945750836001600160a01b0316613a8984610c20565b6001600160a01b0316145b806121d757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff166121d7565b826001600160a01b0316613adb826122c0565b6001600160a01b031614613b435760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610c88565b6001600160a01b038216613ba55760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c88565b613bb083838361427a565b613bbb600082613363565b6001600160a01b0383166000908152600360205260408120805460019290613be490849061599a565b90915550506001600160a01b0382166000908152600360205260408120805460019290613c12908490615930565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606081613ce95750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613d135780613cfd81615a29565b9150613d0c9050600a83615967565b9150613ced565b60008167ffffffffffffffff811115613d2e57613d2e615ad3565b6040519080825280601f01601f191660200182016040528015613d58576020820181803683370190505b5090505b84156121d757613d6d60018361599a565b9150613d7a600a86615a44565b613d85906030615930565b60f81b818381518110613d9a57613d9a615abd565b60200101906001600160f81b031916908160001a905350613dbc600a86615967565b9450613d5c565b613dce848484613ac8565b613dda84848484614332565b612c655760405162461bcd60e51b8152600401610c889061570a565b805160609080613e16575050604080516020810190915260008152919050565b60006003613e25836002615930565b613e2f9190615967565b613e3a90600461597b565b90506000613e49826020615930565b67ffffffffffffffff811115613e6157613e61615ad3565b6040519080825280601f01601f191660200182016040528015613e8b576020820181803683370190505b5090506000604051806060016040528060408152602001615b23604091399050600181016020830160005b86811015613f17576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613eb6565b506003860660018114613f315760028114613f4257613f4e565b613d3d60f01b600119830152613f4e565b603d60f81b6000198301525b505050918152949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001613fcc929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401613ff9939291906156d0565b602060405180830381600087803b15801561401357600080fd5b505af1158015614027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061404b9190614c57565b506000838152600c6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a0909101909252815191830191909120938790529190526140a7906001615930565b6000858152600c60205260409020556121d78482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600081815b845181101561418b57600085828151811061410957614109615abd565b6020026020010151905080831161414b576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250614178565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061418381615a29565b9150506140ec565b509392505050565b6000806000601584815481106141ab576141ab615abd565b906000526020600020015411156141c3575090919050565b82600414156141d0575060005b826141d9575060015b600181151514156141f657826141ee81615a29565b935050614204565b82614200816159dd565b9350505b60006015848154811061421957614219615abd565b90600052602060002001541115614231575090919050565b61423a83614193565b9392505050565b50919050565b614251838361443f565b61425e6000848484614332565b610dbe5760405162461bcd60e51b8152600401610c889061570a565b6001600160a01b0383166142d5576142d081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6142f8565b816001600160a01b0316836001600160a01b0316146142f8576142f8838261457e565b6001600160a01b03821661430f57610dbe8161461b565b826001600160a01b0316826001600160a01b031614610dbe57610dbe82826146ca565b60006001600160a01b0384163b1561443457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614376903390899088908890600401615693565b602060405180830381600087803b15801561439057600080fd5b505af19250505080156143c0575060408051601f3d908101601f191682019092526143bd91810190614cb3565b60015b61441a573d8080156143ee576040519150601f19603f3d011682016040523d82523d6000602084013e6143f3565b606091505b5080516144125760405162461bcd60e51b8152600401610c889061570a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506121d7565b506001949350505050565b6001600160a01b0382166144955760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c88565b61449e81613346565b156144eb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c88565b6144f76000838361427a565b6001600160a01b0382166000908152600360205260408120805460019290614520908490615930565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161458b846123ad565b614595919061599a565b6000838152600760205260409020549091508082146145e8576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061462d9060019061599a565b6000838152600960205260408120546008805493945090928490811061465557614655615abd565b90600052602060002001549050806008838154811061467657614676615abd565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806146ae576146ae615aa7565b6001900381819060005260206000200160009055905550505050565b60006146d5836123ad565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461471a906159f4565b90600052602060002090601f01602090048101928261473c5760008555614782565b82601f1061475557805160ff1916838001178555614782565b82800160010185558215614782579182015b82811115614782578251825591602001919060010190614767565b5061478e92915061480d565b5090565b60405180604001604052806002905b60608152602001906001900390816147a15790505090565b8280548282559060005260206000209081019282156147825791602002820182811115614782578251825591602001919060010190614767565b6040805160e08101909152606081526006602082016147a1565b5b8082111561478e576000815560010161480e565b600067ffffffffffffffff83111561483c5761483c615ad3565b61484f601f8401601f19166020016158db565b905082815283838301111561486357600080fd5b828260208301376000602084830101529392505050565b600082601f83011261488b57600080fd5b813560206148a061489b8361590c565b6158db565b80838252828201915082860187848660051b89010111156148c057600080fd5b60005b858110156148df578135845292840192908401906001016148c3565b5090979650505050505050565b6000602082840312156148fe57600080fd5b813561423a81615ae9565b60006020828403121561491b57600080fd5b815161423a81615ae9565b6000806040838503121561493957600080fd5b823561494481615ae9565b9150602083013561495481615ae9565b809150509250929050565b60008060006060848603121561497457600080fd5b833561497f81615ae9565b9250602084013561498f81615ae9565b929592945050506040919091013590565b600080600080608085870312156149b657600080fd5b84356149c181615ae9565b935060208501356149d181615ae9565b925060408501359150606085013567ffffffffffffffff8111156149f457600080fd5b8501601f81018713614a0557600080fd5b614a1487823560208401614822565b91505092959194509250565b60008060408385031215614a3357600080fd5b8235614a3e81615ae9565b9150602083013561495481615afe565b60008060408385031215614a6157600080fd5b8235614a6c81615ae9565b946020939093013593505050565b600060208284031215614a8c57600080fd5b813567ffffffffffffffff811115614aa357600080fd5b6121d78482850161487a565b60008060408385031215614ac257600080fd5b823567ffffffffffffffff811115614ad957600080fd5b614ae58582860161487a565b95602094909401359450505050565b600080600060608486031215614b0957600080fd5b833567ffffffffffffffff80821115614b2157600080fd5b614b2d8783880161487a565b945060209150818601359350604086013581811115614b4b57600080fd5b86019050601f81018713614b5e57600080fd5b8035614b6c61489b8261590c565b8082825284820191508484018a868560051b8701011115614b8c57600080fd5b600094505b83851015614baf578035835260019490940193918501918501614b91565b5080955050505050509250925092565b60006020808385031215614bd257600080fd5b825167ffffffffffffffff811115614be957600080fd5b8301601f81018513614bfa57600080fd5b8051614c0861489b8261590c565b80828252848201915084840188868560051b8701011115614c2857600080fd5b600094505b83851015614c4b578051835260019490940193918501918501614c2d565b50979650505050505050565b600060208284031215614c6957600080fd5b815161423a81615afe565b60008060408385031215614c8757600080fd5b50508035926020909101359150565b600060208284031215614ca857600080fd5b813561423a81615b0c565b600060208284031215614cc557600080fd5b815161423a81615b0c565b600060208284031215614ce257600080fd5b813567ffffffffffffffff811115614cf957600080fd5b8201601f81018413614d0a57600080fd5b6121d784823560208401614822565b600060208284031215614d2b57600080fd5b5035919050565b600060208284031215614d4457600080fd5b5051919050565b60008151808452614d638160208601602086016159b1565b601f01601f19169290920160200192915050565b60008151614d898185602086016159b1565b9290920192915050565b8054600090600181811c9080831680614dad57607f831692505b6020808410821415614dcf57634e487b7160e01b600052602260045260246000fd5b818015614de35760018114614df457614e21565b60ff19861689528489019650614e21565b60008881526020902060005b86811015614e195781548b820152908501908301614e00565b505084890196505b50505050505092915050565b60008251614e3f8184602087016159b1565b9190910192915050565b60008351614e5b8184602088016159b1565b835190830190614e6f8183602088016159b1565b01949350505050565b600088516020614e8b8285838e016159b1565b895191840191614e9e8184848e016159b1565b8951920191614eb08184848d016159b1565b8851920191614ec28184848c016159b1565b8751920191614ed48184848b016159b1565b8651920191614ee68184848a016159b1565b8551920191614ef881848489016159b1565b919091019a9950505050505050505050565b60008551614f1c818460208a016159b1565b8083019050602d60f81b8082528651614f3c816001850160208b016159b1565b600192019182018190528551614f59816002850160208a016159b1565b600292019182018190528451614f768160038501602089016159b1565b60039201918201526004019695505050505050565b60008651614f9d818460208b016159b1565b8083019050602d60f81b8082528751614fbd816001850160208c016159b1565b600192019182018190528651614fda816002850160208b016159b1565b600292019182018190528551614ff7816003850160208a016159b1565b600392019182015283516150128160048401602088016159b1565b01600401979650505050505050565b61174b60f21b8152711130b734b6b0ba34b7b72fbab936111d101160711b600282015260006150536014830189614d93565b643f646e613d60d81b8082528851615072816005850160208d016159b1565b632669643d60e01b600593909101928301528751615097816009850160208c016159b1565b61088b60f21b600993909101928301526e1134b33930b6b2afbab936111d101160891b600b8301526150cc601a830188614d93565b91508082525084516150e58160058401602089016159b1565b61512761511a61510d615107600585870101632669643d60e01b815260040190565b88614d77565b601160f91b815260010190565b607d60f81b815260010190565b9a9950505050505050505050565b607b60f81b81527f2274726169745f74797065223a202255706772616465202332222c0000000000600182015269113b30b63ab2911d101160b11b601c820152825160009061518b8160268501602088016159b1565b61202b60f01b60269184019182015283516151ad8160288401602088016159b1565b601160f91b60289290910191820152611f4b60f21b6029820152602b01949350505050565b607b60f81b81527f226e616d65223a20224379626572205570677261646520230000000000000000600182015260008851615214816019850160208d016159b1565b68010142632bb32b61d160bd1b601991840191820152885161523d816022840160208d016159b1565b620a488b60ea1b60229290910191820152691134b6b0b3b2911d101160b11b602582015261526e602f820189614d93565b90508651615280818360208b016159b1565b61537b6153606153116153036152fd6152ed6152e76152d66152d06152b38a8c01650b9a9c19c88b60d21b815260060190565b701132bc3a32b93730b62fbab936111d101160791b815260110190565b8f614d93565b643f646e613d60d81b815260050190565b8c614d77565b632669643d60e01b815260040190565b89614d77565b61088b60f21b815260020190565b7f226465736372697074696f6e223a202255706772616465732077616974696e6781527f20746f20626520636f6e6e656374656420746f20706c61796572732e222c00006020820152603e0190565b6e2261747472696275746573223a205b60881b8152600f0190565b9b9a5050505050505050505050565b607b60f81b81527f2274726169745f74797065223a20224175676d656e746174696f6e202331222c600182015269113b30b63ab2911d101160b11b602182015281516000906153e081602b8501602087016159b1565b601160f91b602b939091019283015250611f4b60f21b602c820152602e01919050565b6000607b60f81b8083527f2274726169745f74797065223a20224175676d656e746174696f6e202332222c600184015269113b30b63ab2911d101160b11b6021840152845161545981602b8601602089016159b1565b601160f91b602b918501918201819052611f4b60f21b602c830152602e8201929092527f2274726169745f74797065223a202241697264726f7073222c00000000000000602f8201526a044ecc2d8eaca44744044f60ab1b60488201528451916154ca8360538401602089016159b1565b91016053810191909152607d60f81b6054820152605581016120fd565b6000607b60f81b8083527f2274726169745f74797065223a2022526172697479222c000000000000000000600184015269113b30b63ab2911d101160b11b806018850152855161553e816022870160208a016159b1565b601160f91b6022918601918201819052611f4b60f21b60238301819052602583019490945275089d1c985a5d17dd1e5c19488e880893195d995b088b60521b6026830152603c820183905286519361559d856046850160208b016159b1565b60469290940191820152604781019290925250604901949350505050565b607b60f81b81527f2274726169745f74797065223a202255706772616465202331222c0000000000600182015269113b30b63ab2911d101160b11b601c820152825160009061518b8160268501602088016159b1565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161564981601d8501602087016159b1565b91909101601d0192915050565b94855260e09390931b6001600160e01b031916602085015260609190911b6001600160601b03191660248401526038830152605882015260780190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906156c690830184614d4b565b9695505050505050565b60018060a01b03841681528260208201526060604082015260006120fd6060830184614d4b565b60208152600061423a6020830184614d4b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526019908201527f496e636f7272656374206d696e7420636f73742076616c756500000000000000604082015260600190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b6020808252601e908201527f57686974656c697374206d696e74206e6f742073746172746564207965740000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600f908201526e416c7265616479206d696e7465642160881b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561590457615904615ad3565b604052919050565b600067ffffffffffffffff82111561592657615926615ad3565b5060051b60200190565b6000821982111561594357615943615a7b565b500190565b600063ffffffff808316818516808303821115614e6f57614e6f615a7b565b60008261597657615976615a91565b500490565b600081600019048311821515161561599557615995615a7b565b500290565b6000828210156159ac576159ac615a7b565b500390565b60005b838110156159cc5781810151838201526020016159b4565b83811115612c655750506000910152565b6000816159ec576159ec615a7b565b506000190190565b600181811c90821680615a0857607f821691505b6020821081141561424157634e487b7160e01b600052602260045260246000fd5b6000600019821415615a3d57615a3d615a7b565b5060010190565b600082615a5357615a53615a91565b500690565b600063ffffffff80841680615a6f57615a6f615a91565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146124c057600080fd5b80151581146124c057600080fd5b6001600160e01b0319811681146124c057600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220f6bb635a5ad82bb127badb714437154da0b6abfada8bb20def5922f9593526bc64736f6c63430008070033

Deployed Bytecode

0x6080604052600436106103b85760003560e01c8063666c27d4116101f2578063a272fbae1161010d578063d08b4add116100a0578063e985e9c51161006f578063e985e9c514610acf578063f2fde38b14610b18578063fc59d96214610b38578063fdda339114610b4d57600080fd5b8063d08b4add14610a64578063d5a10a1514610a84578063dbdff2c114610aa4578063e831574214610ab957600080fd5b8063b2596a67116100dc578063b2596a67146109d7578063b88d4fde14610a04578063c87b56dd14610a24578063caf7c44514610a4457600080fd5b8063a272fbae1461096d578063aeceadbf1461098d578063afe29f71146109a2578063b102b6bc146109c257600080fd5b80638cfec4c0116101855780638f5dac6e116101545780638f5dac6e1461090557806394985ddd1461091857806395d89b4114610938578063a22cb4651461094d57600080fd5b80638cfec4c0146108915780638da5cb5b146108a75780638eb8c81c146108c55780638ebb25ca146108e557600080fd5b80637390c786116101c15780637390c7861461080f5780637d91b7b214610824578063871105cc146108445780638b58c5691461086457600080fd5b8063666c27d4146107a557806370a08231146107c5578063715018a6146107e55780637362377b146107fa57600080fd5b806330176e13116102e25780634f6ccce7116102755780635aa28742116102445780635aa28742146107235780635d41c19c14610743578063601fb175146107585780636352211e1461078557600080fd5b80634f6ccce7146106b057806350d5e770146106d057806353b93557146106e3578063556b5dd41461070357600080fd5b806342842e0e116102b157806342842e0e146106305780634336316c14610650578063434b3c1214610670578063487586971461069057600080fd5b806330176e13146105bd578063383aa784146105dd578063422627c3146105f05780634233429c1461061057600080fd5b806317b8e1cf1161035a57806323b872dd1161032957806323b872dd14610547578063276aeac1146105675780632ddbd13a146105875780632f745c591461059d57600080fd5b806317b8e1cf146104d257806318160ddd146104f2578063216c3019146105075780632374c9241461052757600080fd5b8063081812fc11610396578063081812fc14610438578063095ea7b31461047057806313e46f74146104925780631710fef8146104b257600080fd5b806301de34f8146103bd57806301ffc9a7146103e657806306fdde0314610416575b600080fd5b3480156103c957600080fd5b506103d360145481565b6040519081526020015b60405180910390f35b3480156103f257600080fd5b50610406610401366004614c96565b610b63565b60405190151581526020016103dd565b34801561042257600080fd5b5061042b610b8e565b6040516103dd91906156f7565b34801561044457600080fd5b50610458610453366004614d19565b610c20565b6040516001600160a01b0390911681526020016103dd565b34801561047c57600080fd5b5061049061048b366004614a4e565b610cad565b005b34801561049e57600080fd5b506104906104ad366004614af4565b610dc3565b3480156104be57600080fd5b506104906104cd3660046148ec565b6110a3565b3480156104de57600080fd5b506103d36104ed366004614d19565b6110ef565b3480156104fe57600080fd5b506008546103d3565b34801561051357600080fd5b50610406610522366004614d19565b611110565b34801561053357600080fd5b5061042b610542366004614d19565b61113c565b34801561055357600080fd5b5061049061056236600461495f565b6112ae565b34801561057357600080fd5b5061042b610582366004614d19565b6112df565b34801561059357600080fd5b506103d360165481565b3480156105a957600080fd5b506103d36105b8366004614a4e565b611355565b3480156105c957600080fd5b506104906105d8366004614cd0565b6113eb565b6104906105eb366004614aaf565b61142c565b3480156105fc57600080fd5b5061042b61060b366004614d19565b611696565b34801561061c57600080fd5b5061049061062b366004614d19565b611a0a565b34801561063c57600080fd5b5061049061064b36600461495f565b611a39565b34801561065c57600080fd5b5061049061066b3660046148ec565b611a54565b34801561067c57600080fd5b5061049061068b3660046148ec565b611aa0565b34801561069c57600080fd5b5061042b6106ab366004614d19565b611aec565b3480156106bc57600080fd5b506103d36106cb366004614d19565b611bd6565b6104906106de366004614af4565b611c69565b3480156106ef57600080fd5b506103d36106fe366004614d19565b612007565b34801561070f57600080fd5b506103d361071e366004614d19565b612017565b34801561072f57600080fd5b506103d361073e366004614d19565b612106565b34801561074f57600080fd5b506104906121df565b34801561076457600080fd5b506103d3610773366004614d19565b6000908152601e602052604090205490565b34801561079157600080fd5b506104586107a0366004614d19565b6122c0565b3480156107b157600080fd5b5061042b6107c0366004614d19565b612337565b3480156107d157600080fd5b506103d36107e03660046148ec565b6123ad565b3480156107f157600080fd5b50610490612434565b34801561080657600080fd5b5061049061246a565b34801561081b57600080fd5b506103d36124c3565b34801561083057600080fd5b5061049061083f366004614a7a565b6124f7565b34801561085057600080fd5b5061049061085f3660046148ec565b612590565b34801561087057600080fd5b506103d361087f366004614d19565b601f6020526000908152604090205481565b34801561089d57600080fd5b506103d3601a5481565b3480156108b357600080fd5b50600b546001600160a01b0316610458565b3480156108d157600080fd5b506103d36108e0366004614d19565b6125dc565b3480156108f157600080fd5b50610490610900366004614d19565b61265f565b610490610913366004614d19565b61268e565b34801561092457600080fd5b50610490610933366004614c74565b6128e7565b34801561094457600080fd5b5061042b612965565b34801561095957600080fd5b50610490610968366004614a20565b612974565b34801561097957600080fd5b5061042b610988366004614d19565b612a39565b34801561099957600080fd5b50610490612aaf565b3480156109ae57600080fd5b5061042b6109bd366004614d19565b612b6a565b3480156109ce57600080fd5b50610490612b75565b3480156109e357600080fd5b506103d36109f2366004614d19565b601e6020526000908152604090205481565b348015610a1057600080fd5b50610490610a1f3660046149a0565b612c33565b348015610a3057600080fd5b5061042b610a3f366004614d19565b612c6b565b348015610a5057600080fd5b50610490610a5f366004614c74565b612f2a565b348015610a7057600080fd5b50610490610a7f366004614cd0565b612f8e565b348015610a9057600080fd5b506103d3610a9f366004614d19565b612fcb565b348015610ab057600080fd5b506103d361303e565b348015610ac557600080fd5b506103d361138881565b348015610adb57600080fd5b50610406610aea366004614926565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610b2457600080fd5b50610490610b333660046148ec565b613159565b348015610b4457600080fd5b506104906131f1565b348015610b5957600080fd5b506103d360195481565b60006001600160e01b0319821663780e9d6360e01b1480610b885750610b88826132f6565b92915050565b606060008054610b9d906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc9906159f4565b8015610c165780601f10610beb57610100808354040283529160200191610c16565b820191906000526020600020905b815481529060010190602001808311610bf957829003601f168201915b5050505050905090565b6000610c2b82613346565b610c915760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610cb8826122c0565b9050806001600160a01b0316836001600160a01b03161415610d265760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c88565b336001600160a01b0382161480610d425750610d428133610aea565b610db45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610c88565b610dbe8383613363565b505050565b6002600a541415610de65760405162461bcd60e51b8152600401610c889061587b565b6002600a556019544211610e0c5760405162461bcd60e51b8152600401610c88906157be565b6113888151601654610e1e9190615930565b10610e6b5760405162461bcd60e51b815260206004820152601e60248201527f4d696e74206f76657220746865206d617820746f6b656e73206c696d697400006044820152606401610c88565b60005b8151811015610f5157610e99828281518110610e8c57610e8c615abd565b60200260200101516133d1565b610ed75760405162461bcd60e51b815260206004820152600f60248201526e2737ba102b30bab63a1037bbb732b960891b6044820152606401610c88565b610ef9828281518110610eec57610eec615abd565b6020026020010151611110565b15610f3f5760405162461bcd60e51b815260206004820152601660248201527515985d5b1d081dd85cc8185b1c9958591e481d5cd95960521b6044820152606401610c88565b80610f4981615a29565b915050610e6e565b506040516001600160601b03193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050610fb08560138681548110610f9f57610f9f615abd565b906000526020600020015483613473565b15610fc457610fc1846103e861597b565b91505b60005b8351811015611096576000610fff6001610ff9878581518110610fec57610fec615abd565b60200260200101516125dc565b86613489565b905060016011600087858151811061101957611019615abd565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055506016600081548092919061105990615a29565b90915550506014805490600061106e836159dd565b919050555061108361107d3390565b826139c8565b508061108e81615a29565b915050610fc7565b50506001600a5550505050565b600b546001600160a01b031633146110cd5760405162461bcd60e51b8152600401610c88906157f5565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b601581815481106110ff57600080fd5b600091825260209091200154905081565b60008181526011602052604081205460ff1615156001141561113457506001919050565b506000919050565b606061114782613346565b6111635760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051631ef2f77160e01b81526060926001600160a01b0316916022918391631ef2f771916111b2918991600401918252602082015260400190565b60206040518083038186803b1580156111ca57600080fd5b505afa1580156111de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112029190614d32565b8154811061121257611212615abd565b906000526020600020018054611227906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611253906159f4565b80156112a05780601f10611275576101008083540402835291602001916112a0565b820191906000526020600020905b81548152906001019060200180831161128357829003601f168201915b509398975050505050505050565b6112b833826139e2565b6112d45760405162461bcd60e51b8152600401610c889061582a565b610dbe838383613ac8565b60606112ea82613346565b6113065760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051632311963b60e01b81526060926001600160a01b0316916021918391632311963b916111b2918991600401918252602082015260400190565b6000611360836123ad565b82106113c25760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c88565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600b546001600160a01b031633146114155760405162461bcd60e51b8152600401610c88906157f5565b805161142890602590602084019061470e565b5050565b6002600a54141561144f5760405162461bcd60e51b8152600401610c889061587b565b6002600a5560195442116114755760405162461bcd60e51b8152600401610c88906157be565b6014546016546114879061138861599a565b116114d45760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e67206f766572207661756c7420686f6c646572206c696d6974006044820152606401610c88565b611388601654106115275760405162461bcd60e51b815260206004820152601d60248201527f416c6c20746f6b656e732061726520616c7265616479206d696e7465640000006044820152606401610c88565b60175434146115485760405162461bcd60e51b8152600401610c889061575c565b3360009081526012602052604090205460011161159f5760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610c88565b6040516001600160601b03193360601b1660208201526000906034016040516020818303038152906040528051906020012090506115ea8360138481548110610f9f57610f9f615abd565b6116265760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610c88565b6000611634836103e861597b565b9050600061164460008084613489565b60168054919250600061165683615a29565b919050555080601260006116673390565b6001600160a01b0316815260208101919091526040016000205561168a3361107d565b50506001600a55505050565b60606116a182613346565b6116ed5760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610c88565b600d546000838152601f6020526040808220549051632311963b60e01b81526001600160a01b03909316928391632311963b91611737918891600401918252602082015260400190565b60206040518083038186803b15801561174f57600080fd5b505afa158015611763573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117879190614d32565b6000858152601f6020526040808220549051631ef2f77160e01b8152600481018890526024810191909152919250906001600160a01b03841690631ef2f7719060440160206040518083038186803b1580156117e257600080fd5b505afa1580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190614d32565b9050611824614792565b6000868152601f602052604090205461183c90612b6a565b6000878152601e602052604090205461185490612b6a565b61185d85612b6a565b6118696109bd8a612017565b60405160200161187c9493929190614f0a565b60408051808303601f19018152919052815261189782612b6a565b6118a36109bd88612fcb565b6000888152601f6020526040908190205490516307568f4b60e01b8152600481018a90526024810191909152611938906001600160a01b038816906307568f4b906044015b60206040518083038186803b15801561190057600080fd5b505afa158015611914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bd9190614d32565b6000898152601f602052604090819020549051637c9cead360e01b8152600481018b90526024810191909152611981906001600160a01b03891690637c9cead3906044016118e8565b61198d6109bd8b612106565b6040516020016119a1959493929190614f8b565b60408051808303601f190181529181526020808401839052835191516000936119cd9392909101614e49565b6040516020818303038152906040529050806040516020016119ef9190614e2d565b60405160208183030381529060405295505050505050919050565b600b546001600160a01b03163314611a345760405162461bcd60e51b8152600401610c88906157f5565b601955565b610dbe83838360405180602001604052806000815250612c33565b600b546001600160a01b03163314611a7e5760405162461bcd60e51b8152600401610c88906157f5565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b600b546001600160a01b03163314611aca5760405162461bcd60e51b8152600401610c88906157f5565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6060611af782613346565b611b135760405162461bcd60e51b8152600401610c8890615793565b60606020601f60008581526020019081526020016000205481548110611b3b57611b3b615abd565b906000526020600020018054611b50906159f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7c906159f4565b8015611bc95780601f10611b9e57610100808354040283529160200191611bc9565b820191906000526020600020905b815481529060010190602001808311611bac57829003601f168201915b5093979650505050505050565b6000611be160085490565b8210611c445760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c88565b60088281548110611c5757611c57615abd565b90600052602060002001549050919050565b6002600a541415611c8c5760405162461bcd60e51b8152600401610c889061587b565b6002600a556019544211611cb25760405162461bcd60e51b8152600401610c88906157be565b61138881516016546001611cc69190615930565b611cd09190615930565b10611d1d5760405162461bcd60e51b815260206004820152601e60248201527f4d696e74206f76657220746865206d617820746f6b656e73206c696d697400006044820152606401610c88565b6017543414611d3e5760405162461bcd60e51b8152600401610c889061575c565b33600090815260126020526040902054600111611d955760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610c88565b60005b8151811015611e6157611db6828281518110610e8c57610e8c615abd565b611df45760405162461bcd60e51b815260206004820152600f60248201526e2737ba102b30bab63a1037bbb732b960891b6044820152606401610c88565b611e09828281518110610eec57610eec615abd565b15611e4f5760405162461bcd60e51b815260206004820152601660248201527515985d5b1d081dd85cc8185b1c9958591e481d5cd95960521b6044820152606401610c88565b80611e5981615a29565b915050611d98565b506040516001600160601b03193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050611eaf8560138681548110610f9f57610f9f615abd565b611eeb5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610c88565b611ef7846103e861597b565b915060005b8351811015611fb2576000611f216001610ff9878581518110610fec57610fec615abd565b9050600160116000878581518110611f3b57611f3b615abd565b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555060166000815480929190611f7b90615a29565b909155505060148054906000611f90836159dd565b9190505550611f9f61107d3390565b5080611faa81615a29565b915050611efc565b506000611fc160008085613489565b601680549192506000611fd383615a29565b91905055508060126000611fe43390565b6001600160a01b031681526020810191909152604001600020556110963361107d565b601381815481106110ff57600080fd5b600061202282613346565b61203e5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604080822054905163d913a56760e01b815260048101869052602481019190915290916001600160a01b0316908290829063d913a567906044015b60206040518083038186803b15801561209e57600080fd5b505afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190614d32565b6000868152601e60205260409020549091506120f2908261597b565b6120fd906001615930565b95945050505050565b600061211182613346565b61212d5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601e6020908152604080832054601f909252808320549051633570d40760e11b815260048101879052602481019190915291926001600160a01b0316918290636ae1a80e9060440160206040518083038186803b15801561219557600080fd5b505afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190614d32565b6121d79190615930565b949350505050565b6002600a5414156122025760405162461bcd60e51b8152600401610c889061587b565b6002600a55601c546001600160a01b031633146122505760405162461bcd60e51b815260206004820152600c60248201526b04e6f7420436f6465203230360a41b6044820152606401610c88565b601b5462010000900460ff16156122795760405162461bcd60e51b8152600401610c88906158b2565b601b805462ff00001916620100001790556000612297818080613489565b6016805491925060006122a983615a29565b91905055506122b833826139c8565b506001600a55565b6000818152600260205260408120546001600160a01b031680610b885760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610c88565b606061234282613346565b61235e5760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f602052604090819020549051637c9cead360e01b81526060926001600160a01b0316916024918391637c9cead3916111b2918991600401918252602082015260400190565b60006001600160a01b0382166124185760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610c88565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b0316331461245e5760405162461bcd60e51b8152600401610c88906157f5565b6124686000613c73565b565b600b546001600160a01b031633146124945760405162461bcd60e51b8152600401610c88906157f5565b60405133904780156108fc02916000818181858888f193505050501580156124c0573d6000803e3d6000fd5b50565b600b546000906001600160a01b031633146124f05760405162461bcd60e51b8152600401610c88906157f5565b5060295490565b600b546001600160a01b031633146125215760405162461bcd60e51b8152600401610c88906157f5565b604080516000815260208101918290525161253e916013916147b9565b5060005b815181101561142857601382828151811061255f5761255f615abd565b602090810291909101810151825460018101845560009384529190922001558061258881615a29565b915050612542565b600b546001600160a01b031633146125ba5760405162461bcd60e51b8152600401610c88906157f5565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600d546040516323ae320760e21b81526004810183905260009182916001600160a01b03909116908190638eb8c81c9060240160206040518083038186803b15801561262757600080fd5b505afa15801561263b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d79190614d32565b600b546001600160a01b031633146126895760405162461bcd60e51b8152600401610c88906157f5565b601a55565b6002600a5414156126b15760405162461bcd60e51b8152600401610c889061587b565b6002600a55601a5442116127075760405162461bcd60e51b815260206004820152601d60248201527f5075626c6963206d696e7420646964206e6f74207374617274207965740000006044820152606401610c88565b6014546016546127199061138861599a565b116127665760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e67206f766572207661756c7420686f6c646572206c696d6974006044820152606401610c88565b611388816016546127779190615930565b106127c45760405162461bcd60e51b815260206004820152601d60248201527f416c6c20746f6b656e732061726520616c7265616479206d696e7465640000006044820152606401610c88565b600081116128145760405162461bcd60e51b815260206004820152601860248201527f43616e206e6f74206d696e74207a65726f20746f6b656e7300000000000000006044820152606401610c88565b600b81106128645760405162461bcd60e51b815260206004820152601a60248201527f526571756573742065786365656473206d617820746f6b656e730000000000006044820152606401610c88565b80601854612872919061597b565b34146128905760405162461bcd60e51b8152600401610c889061575c565b60015b818110156128de5760006128aa6000806000613489565b6016805491925060006128bc83615a29565b91905055506128cb61107d3390565b50806128d681615a29565b915050612893565b50506001600a55565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952161461295f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610c88565b60295550565b606060018054610b9d906159f4565b6001600160a01b0382163314156129cd5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c88565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060612a4482613346565b612a605760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f6020526040908190205490516307568f4b60e01b81526060926001600160a01b03169160239183916307568f4b916111b2918991600401918252602082015260400190565b600b546001600160a01b03163314612ad95760405162461bcd60e51b8152600401610c88906157f5565b6002600a541415612afc5760405162461bcd60e51b8152600401610c889061587b565b6002600a55601b5460ff1615612b245760405162461bcd60e51b8152600401610c88906158b2565b601b805460ff191660011790556000612b3e818080613489565b601680549192506000612b5083615a29565b91905055506122b861107d600b546001600160a01b031690565b6060610b8882613cc5565b6002600a541415612b985760405162461bcd60e51b8152600401610c889061587b565b6002600a55601b5464010000000090046001600160a01b03163314612bef5760405162461bcd60e51b815260206004820152600d60248201526c139bdd08115c9c9bdc880d0c0d609a1b6044820152606401610c88565b601b54610100900460ff1615612c175760405162461bcd60e51b8152600401610c88906158b2565b601b805461ff0019166101001790556000612297818080613489565b612c3d33836139e2565b612c595760405162461bcd60e51b8152600401610c889061582a565b612c6584848484613dc3565b50505050565b6060612c7682613346565b612cc25760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610c88565b612cca6147f3565b612cd383612b6a565b6000848152601e6020526040902054612ceb90612b6a565b6000858152601f6020526040902054602590612d0690612b6a565b6026612d1188611696565b612d1a89612b6a565b604051602001612d3097969594939291906151d2565b60408051808303601f190181529190528152612d4b83611aec565b6000848152601e6020526040902054612d6390612b6a565b604051602001612d749291906154e7565b60408051808303601f190181529190526020820152612d92836112df565b612d9e6109bd85612017565b604051602001612daf9291906155bb565b60408051808303601f19018152918152820152612dcb8361113c565b612dd76109bd85612fcb565b604051602001612de8929190615135565b60408051808303601f190181529190526060820152612e0683612a39565b604051602001612e16919061538a565b60408051808303601f190181529190526080820152612e3483612337565b612e406109bd85612106565b604051602001612e51929190615403565b60408051808303601f1901815291905260a08201526026612e7184611696565b612e7a85612b6a565b6026612e8587611696565b612e8e88612b6a565b604051602001612ea396959493929190615021565b60408051808303601f1901815291815260c083018290528251602080850151858401516060870151608088015160a08901519651600098612eff98612eeb9897909201614e78565b604051602081830303815290604052613df6565b905080604051602001612f129190615611565b60405160208183030381529060405292505050919050565b6010546001600160a01b03163314612f7c5760405162461bcd60e51b8152602060048201526015602482015274596f752063616e206e6f742063616c6c207468697360581b6044820152606401610c88565b6000918252601e602052604090912055565b600b546001600160a01b03163314612fb85760405162461bcd60e51b8152600401610c88906157f5565b805161142890602690602084019061470e565b6000612fd682613346565b612ff25760405162461bcd60e51b8152600401610c8890615793565b600d546000838152601f60205260408082205490516349ec3c7160e11b815260048101869052602481019190915290916001600160a01b031690829082906393d878e290604401612086565b600b546000906001600160a01b0316331461306b5760405162461bcd60e51b8152600401610c88906157f5565b6028546040516370a0823160e01b81523060048201527f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316906370a082319060240160206040518083038186803b1580156130cd57600080fd5b505afa1580156130e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131059190614d32565b10156131465760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204c494e4b2160801b6044820152606401610c88565b613154602754602854613f5c565b905090565b600b546001600160a01b031633146131835760405162461bcd60e51b8152600401610c88906157f5565b6001600160a01b0381166131e85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c88565b6124c081613c73565b6002600a5414156132145760405162461bcd60e51b8152600401610c889061587b565b6002600a55601d546001600160a01b0316331461326a5760405162461bcd60e51b8152602060048201526014602482015273139bdd0811da5d99585dd85e5cc81dd85b1b195d60621b6044820152606401610c88565b601b546301000000900460ff16156132945760405162461bcd60e51b8152600401610c88906158b2565b601b805463ff0000001916630100000017905560005b60148110156122b85760006132c26000806000613489565b6016805491925060006132d483615a29565b91905055506132e333826139c8565b50806132ee81615a29565b9150506132aa565b60006001600160e01b031982166380ac58cd60e01b148061332757506001600160e01b03198216635b5e139f60e01b145b80610b8857506301ffc9a760e01b6001600160e01b0319831614610b88565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613398826122c0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600f546040516331a9108f60e11b8152600481018390526000916001600160a01b03169033908290636352211e9060240160206040518083038186803b15801561341a57600080fd5b505afa15801561342e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134529190614909565b6001600160a01b0316141561346a5750600192915050565b50600092915050565b60008261348085846140e7565b14949350505050565b6000602954600014156134ea5760405162461bcd60e51b815260206004820152602360248201527f5652462052616e646f6d20526573756c7420686173206e6f74206265656e207360448201526265742160e81b6064820152608401610c88565b60006016546113886134fc919061599a565b9050600081156135165761351160018361599a565b613519565b60005b6029546113b254604051929350600092859261354892909163ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c61356b9190615a44565b90506000602a82611388811061358357613583615abd565b015461358f57816135a6565b602a8261138881106135a3576135a3615abd565b01545b9050602a8361138881106135bc576135bc615abd565b0154156135de57602a8361138881106135d7576135d7615abd565b01546135e0565b825b602a8361138881106135f4576135f4615abd565b01556029546113b254604051600092600a926136219263ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c6136449190615a58565b6113b28054919250829160009061366290849063ffffffff16615948565b825463ffffffff9182166101009390930a928302919092021990911617905550600e546040516375cf69f960e01b81528a15156004820152602481018a9052604481018990526001600160a01b039091169060009082906375cf69f99060640160006040518083038186803b1580156136da57600080fd5b505afa1580156136ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137169190810190614bbf565b60408051600580825260c0820190925291925060009182916020820160a08036833701905050905060005b83518110156137a15783818151811061375c5761375c615abd565b60200260200101518361376f9190615930565b92508282828151811061378457613784615abd565b60209081029190910101528061379981615a29565b915050613741565b506029546113b25460405160009285926137cc9263ffffffff90911690339044904290602001615656565b6040516020818303038152906040528051906020012060001c6137ef9190615a44565b905060008260008151811061380657613806615abd565b6020026020010151821015801561383657508260018151811061382b5761382b615abd565b602002602001015182105b1561383f575060015b8260018151811061385257613852615abd565b6020026020010151821015801561388257508260028151811061387757613877615abd565b602002602001015182105b1561388b575060025b8260028151811061389e5761389e615abd565b602002602001015182101580156138ce5750826003815181106138c3576138c3615abd565b602002602001015182105b156138d7575060035b826003815181106138ea576138ea615abd565b6020026020010151821015801561391b57508260048151811061390f5761390f615abd565b60200260200101518211155b15613924575060045b60006015828154811061393957613939615abd565b9060005260206000200154111561399c576015818154811061395d5761395d615abd565b60009182526020822001805491613973836159dd565b90915550506000888152601f60209081526040808320849055601e9091529020600190556139b5565b6139a581614193565b6000898152601f60205260409020555b50959d9c50505050505050505050505050565b611428828260405180602001604052806000815250614247565b60006139ed82613346565b613a4e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610c88565b6000613a59836122c0565b9050806001600160a01b0316846001600160a01b03161480613a945750836001600160a01b0316613a8984610c20565b6001600160a01b0316145b806121d757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff166121d7565b826001600160a01b0316613adb826122c0565b6001600160a01b031614613b435760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610c88565b6001600160a01b038216613ba55760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c88565b613bb083838361427a565b613bbb600082613363565b6001600160a01b0383166000908152600360205260408120805460019290613be490849061599a565b90915550506001600160a01b0382166000908152600360205260408120805460019290613c12908490615930565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606081613ce95750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613d135780613cfd81615a29565b9150613d0c9050600a83615967565b9150613ced565b60008167ffffffffffffffff811115613d2e57613d2e615ad3565b6040519080825280601f01601f191660200182016040528015613d58576020820181803683370190505b5090505b84156121d757613d6d60018361599a565b9150613d7a600a86615a44565b613d85906030615930565b60f81b818381518110613d9a57613d9a615abd565b60200101906001600160f81b031916908160001a905350613dbc600a86615967565b9450613d5c565b613dce848484613ac8565b613dda84848484614332565b612c655760405162461bcd60e51b8152600401610c889061570a565b805160609080613e16575050604080516020810190915260008152919050565b60006003613e25836002615930565b613e2f9190615967565b613e3a90600461597b565b90506000613e49826020615930565b67ffffffffffffffff811115613e6157613e61615ad3565b6040519080825280601f01601f191660200182016040528015613e8b576020820181803683370190505b5090506000604051806060016040528060408152602001615b23604091399050600181016020830160005b86811015613f17576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613eb6565b506003860660018114613f315760028114613f4257613f4e565b613d3d60f01b600119830152613f4e565b603d60f81b6000198301525b505050918152949350505050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001613fcc929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401613ff9939291906156d0565b602060405180830381600087803b15801561401357600080fd5b505af1158015614027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061404b9190614c57565b506000838152600c6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a0909101909252815191830191909120938790529190526140a7906001615930565b6000858152600c60205260409020556121d78482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600081815b845181101561418b57600085828151811061410957614109615abd565b6020026020010151905080831161414b576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250614178565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061418381615a29565b9150506140ec565b509392505050565b6000806000601584815481106141ab576141ab615abd565b906000526020600020015411156141c3575090919050565b82600414156141d0575060005b826141d9575060015b600181151514156141f657826141ee81615a29565b935050614204565b82614200816159dd565b9350505b60006015848154811061421957614219615abd565b90600052602060002001541115614231575090919050565b61423a83614193565b9392505050565b50919050565b614251838361443f565b61425e6000848484614332565b610dbe5760405162461bcd60e51b8152600401610c889061570a565b6001600160a01b0383166142d5576142d081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6142f8565b816001600160a01b0316836001600160a01b0316146142f8576142f8838261457e565b6001600160a01b03821661430f57610dbe8161461b565b826001600160a01b0316826001600160a01b031614610dbe57610dbe82826146ca565b60006001600160a01b0384163b1561443457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614376903390899088908890600401615693565b602060405180830381600087803b15801561439057600080fd5b505af19250505080156143c0575060408051601f3d908101601f191682019092526143bd91810190614cb3565b60015b61441a573d8080156143ee576040519150601f19603f3d011682016040523d82523d6000602084013e6143f3565b606091505b5080516144125760405162461bcd60e51b8152600401610c889061570a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506121d7565b506001949350505050565b6001600160a01b0382166144955760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c88565b61449e81613346565b156144eb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c88565b6144f76000838361427a565b6001600160a01b0382166000908152600360205260408120805460019290614520908490615930565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161458b846123ad565b614595919061599a565b6000838152600760205260409020549091508082146145e8576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061462d9060019061599a565b6000838152600960205260408120546008805493945090928490811061465557614655615abd565b90600052602060002001549050806008838154811061467657614676615abd565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806146ae576146ae615aa7565b6001900381819060005260206000200160009055905550505050565b60006146d5836123ad565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461471a906159f4565b90600052602060002090601f01602090048101928261473c5760008555614782565b82601f1061475557805160ff1916838001178555614782565b82800160010185558215614782579182015b82811115614782578251825591602001919060010190614767565b5061478e92915061480d565b5090565b60405180604001604052806002905b60608152602001906001900390816147a15790505090565b8280548282559060005260206000209081019282156147825791602002820182811115614782578251825591602001919060010190614767565b6040805160e08101909152606081526006602082016147a1565b5b8082111561478e576000815560010161480e565b600067ffffffffffffffff83111561483c5761483c615ad3565b61484f601f8401601f19166020016158db565b905082815283838301111561486357600080fd5b828260208301376000602084830101529392505050565b600082601f83011261488b57600080fd5b813560206148a061489b8361590c565b6158db565b80838252828201915082860187848660051b89010111156148c057600080fd5b60005b858110156148df578135845292840192908401906001016148c3565b5090979650505050505050565b6000602082840312156148fe57600080fd5b813561423a81615ae9565b60006020828403121561491b57600080fd5b815161423a81615ae9565b6000806040838503121561493957600080fd5b823561494481615ae9565b9150602083013561495481615ae9565b809150509250929050565b60008060006060848603121561497457600080fd5b833561497f81615ae9565b9250602084013561498f81615ae9565b929592945050506040919091013590565b600080600080608085870312156149b657600080fd5b84356149c181615ae9565b935060208501356149d181615ae9565b925060408501359150606085013567ffffffffffffffff8111156149f457600080fd5b8501601f81018713614a0557600080fd5b614a1487823560208401614822565b91505092959194509250565b60008060408385031215614a3357600080fd5b8235614a3e81615ae9565b9150602083013561495481615afe565b60008060408385031215614a6157600080fd5b8235614a6c81615ae9565b946020939093013593505050565b600060208284031215614a8c57600080fd5b813567ffffffffffffffff811115614aa357600080fd5b6121d78482850161487a565b60008060408385031215614ac257600080fd5b823567ffffffffffffffff811115614ad957600080fd5b614ae58582860161487a565b95602094909401359450505050565b600080600060608486031215614b0957600080fd5b833567ffffffffffffffff80821115614b2157600080fd5b614b2d8783880161487a565b945060209150818601359350604086013581811115614b4b57600080fd5b86019050601f81018713614b5e57600080fd5b8035614b6c61489b8261590c565b8082825284820191508484018a868560051b8701011115614b8c57600080fd5b600094505b83851015614baf578035835260019490940193918501918501614b91565b5080955050505050509250925092565b60006020808385031215614bd257600080fd5b825167ffffffffffffffff811115614be957600080fd5b8301601f81018513614bfa57600080fd5b8051614c0861489b8261590c565b80828252848201915084840188868560051b8701011115614c2857600080fd5b600094505b83851015614c4b578051835260019490940193918501918501614c2d565b50979650505050505050565b600060208284031215614c6957600080fd5b815161423a81615afe565b60008060408385031215614c8757600080fd5b50508035926020909101359150565b600060208284031215614ca857600080fd5b813561423a81615b0c565b600060208284031215614cc557600080fd5b815161423a81615b0c565b600060208284031215614ce257600080fd5b813567ffffffffffffffff811115614cf957600080fd5b8201601f81018413614d0a57600080fd5b6121d784823560208401614822565b600060208284031215614d2b57600080fd5b5035919050565b600060208284031215614d4457600080fd5b5051919050565b60008151808452614d638160208601602086016159b1565b601f01601f19169290920160200192915050565b60008151614d898185602086016159b1565b9290920192915050565b8054600090600181811c9080831680614dad57607f831692505b6020808410821415614dcf57634e487b7160e01b600052602260045260246000fd5b818015614de35760018114614df457614e21565b60ff19861689528489019650614e21565b60008881526020902060005b86811015614e195781548b820152908501908301614e00565b505084890196505b50505050505092915050565b60008251614e3f8184602087016159b1565b9190910192915050565b60008351614e5b8184602088016159b1565b835190830190614e6f8183602088016159b1565b01949350505050565b600088516020614e8b8285838e016159b1565b895191840191614e9e8184848e016159b1565b8951920191614eb08184848d016159b1565b8851920191614ec28184848c016159b1565b8751920191614ed48184848b016159b1565b8651920191614ee68184848a016159b1565b8551920191614ef881848489016159b1565b919091019a9950505050505050505050565b60008551614f1c818460208a016159b1565b8083019050602d60f81b8082528651614f3c816001850160208b016159b1565b600192019182018190528551614f59816002850160208a016159b1565b600292019182018190528451614f768160038501602089016159b1565b60039201918201526004019695505050505050565b60008651614f9d818460208b016159b1565b8083019050602d60f81b8082528751614fbd816001850160208c016159b1565b600192019182018190528651614fda816002850160208b016159b1565b600292019182018190528551614ff7816003850160208a016159b1565b600392019182015283516150128160048401602088016159b1565b01600401979650505050505050565b61174b60f21b8152711130b734b6b0ba34b7b72fbab936111d101160711b600282015260006150536014830189614d93565b643f646e613d60d81b8082528851615072816005850160208d016159b1565b632669643d60e01b600593909101928301528751615097816009850160208c016159b1565b61088b60f21b600993909101928301526e1134b33930b6b2afbab936111d101160891b600b8301526150cc601a830188614d93565b91508082525084516150e58160058401602089016159b1565b61512761511a61510d615107600585870101632669643d60e01b815260040190565b88614d77565b601160f91b815260010190565b607d60f81b815260010190565b9a9950505050505050505050565b607b60f81b81527f2274726169745f74797065223a202255706772616465202332222c0000000000600182015269113b30b63ab2911d101160b11b601c820152825160009061518b8160268501602088016159b1565b61202b60f01b60269184019182015283516151ad8160288401602088016159b1565b601160f91b60289290910191820152611f4b60f21b6029820152602b01949350505050565b607b60f81b81527f226e616d65223a20224379626572205570677261646520230000000000000000600182015260008851615214816019850160208d016159b1565b68010142632bb32b61d160bd1b601991840191820152885161523d816022840160208d016159b1565b620a488b60ea1b60229290910191820152691134b6b0b3b2911d101160b11b602582015261526e602f820189614d93565b90508651615280818360208b016159b1565b61537b6153606153116153036152fd6152ed6152e76152d66152d06152b38a8c01650b9a9c19c88b60d21b815260060190565b701132bc3a32b93730b62fbab936111d101160791b815260110190565b8f614d93565b643f646e613d60d81b815260050190565b8c614d77565b632669643d60e01b815260040190565b89614d77565b61088b60f21b815260020190565b7f226465736372697074696f6e223a202255706772616465732077616974696e6781527f20746f20626520636f6e6e656374656420746f20706c61796572732e222c00006020820152603e0190565b6e2261747472696275746573223a205b60881b8152600f0190565b9b9a5050505050505050505050565b607b60f81b81527f2274726169745f74797065223a20224175676d656e746174696f6e202331222c600182015269113b30b63ab2911d101160b11b602182015281516000906153e081602b8501602087016159b1565b601160f91b602b939091019283015250611f4b60f21b602c820152602e01919050565b6000607b60f81b8083527f2274726169745f74797065223a20224175676d656e746174696f6e202332222c600184015269113b30b63ab2911d101160b11b6021840152845161545981602b8601602089016159b1565b601160f91b602b918501918201819052611f4b60f21b602c830152602e8201929092527f2274726169745f74797065223a202241697264726f7073222c00000000000000602f8201526a044ecc2d8eaca44744044f60ab1b60488201528451916154ca8360538401602089016159b1565b91016053810191909152607d60f81b6054820152605581016120fd565b6000607b60f81b8083527f2274726169745f74797065223a2022526172697479222c000000000000000000600184015269113b30b63ab2911d101160b11b806018850152855161553e816022870160208a016159b1565b601160f91b6022918601918201819052611f4b60f21b60238301819052602583019490945275089d1c985a5d17dd1e5c19488e880893195d995b088b60521b6026830152603c820183905286519361559d856046850160208b016159b1565b60469290940191820152604781019290925250604901949350505050565b607b60f81b81527f2274726169745f74797065223a202255706772616465202331222c0000000000600182015269113b30b63ab2911d101160b11b601c820152825160009061518b8160268501602088016159b1565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161564981601d8501602087016159b1565b91909101601d0192915050565b94855260e09390931b6001600160e01b031916602085015260609190911b6001600160601b03191660248401526038830152605882015260780190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906156c690830184614d4b565b9695505050505050565b60018060a01b03841681528260208201526060604082015260006120fd6060830184614d4b565b60208152600061423a6020830184614d4b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526019908201527f496e636f7272656374206d696e7420636f73742076616c756500000000000000604082015260600190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b6020808252601e908201527f57686974656c697374206d696e74206e6f742073746172746564207965740000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600f908201526e416c7265616479206d696e7465642160881b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561590457615904615ad3565b604052919050565b600067ffffffffffffffff82111561592657615926615ad3565b5060051b60200190565b6000821982111561594357615943615a7b565b500190565b600063ffffffff808316818516808303821115614e6f57614e6f615a7b565b60008261597657615976615a91565b500490565b600081600019048311821515161561599557615995615a7b565b500290565b6000828210156159ac576159ac615a7b565b500390565b60005b838110156159cc5781810151838201526020016159b4565b83811115612c655750506000910152565b6000816159ec576159ec615a7b565b506000190190565b600181811c90821680615a0857607f821691505b6020821081141561424157634e487b7160e01b600052602260045260246000fd5b6000600019821415615a3d57615a3d615a7b565b5060010190565b600082615a5357615a53615a91565b500690565b600063ffffffff80841680615a6f57615a6f615a91565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146124c057600080fd5b80151581146124c057600080fd5b6001600160e01b0319811681146124c057600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220f6bb635a5ad82bb127badb714437154da0b6abfada8bb20def5922f9593526bc64736f6c63430008070033

Deployed Bytecode Sourcemap

62933:24356:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63449:37;;;;;;;;;;;;;;;;;;;33672:25:1;;;33660:2;33645:18;63449:37:0;;;;;;;;53900:224;;;;;;;;;;-1:-1:-1;53900:224:0;;;;;:::i;:::-;;:::i;:::-;;;33165:14:1;;33158:22;33140:41;;33128:2;33113:18;53900:224:0;33000:187:1;41052:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42581:221::-;;;;;;;;;;-1:-1:-1;42581:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;32073:32:1;;;32055:51;;32043:2;32028:18;42581:221:0;31909:203:1;42104:411:0;;;;;;;;;;-1:-1:-1;42104:411:0;;;;;:::i;:::-;;:::i;:::-;;76459:1198;;;;;;;;;;-1:-1:-1;76459:1198:0;;;;;:::i;:::-;;:::i;64931:126::-;;;;;;;;;;-1:-1:-1;64931:126:0;;;;;:::i;:::-;;:::i;63495:22::-;;;;;;;;;;-1:-1:-1;63495:22:0;;;;;:::i;:::-;;:::i;54540:113::-;;;;;;;;;;-1:-1:-1;54628:10:0;:17;54540:113;;79691:176;;;;;;;;;;-1:-1:-1;79691:176:0;;;;;:::i;:::-;;:::i;66964:349::-;;;;;;;;;;-1:-1:-1;66964:349:0;;;;;:::i;:::-;;:::i;43471:339::-;;;;;;;;;;-1:-1:-1;43471:339:0;;;;;:::i;:::-;;:::i;65824:346::-;;;;;;;;;;-1:-1:-1;65824:346:0;;;;;:::i;:::-;;:::i;63569:21::-;;;;;;;;;;;;;;;;54208:256;;;;;;;;;;-1:-1:-1;54208:256:0;;;;;:::i;:::-;;:::i;69651:102::-;;;;;;;;;;-1:-1:-1;69651:102:0;;;;;:::i;:::-;;:::i;74661:1020::-;;;;;;:::i;:::-;;:::i;73008:1352::-;;;;;;;;;;-1:-1:-1;73008:1352:0;;;;;:::i;:::-;;:::i;64569:117::-;;;;;;;;;;-1:-1:-1;64569:117:0;;;;;:::i;:::-;;:::i;43881:185::-;;;;;;;;;;-1:-1:-1;43881:185:0;;;;;:::i;:::-;;:::i;64416:145::-;;;;;;;;;;-1:-1:-1;64416:145:0;;;;;:::i;:::-;;:::i;64811:112::-;;;;;;;;;;-1:-1:-1;64811:112:0;;;;;:::i;:::-;;:::i;65204:251::-;;;;;;;;;;-1:-1:-1;65204:251:0;;;;;:::i;:::-;;:::i;54730:233::-;;;;;;;;;;-1:-1:-1;54730:233:0;;;;;:::i;:::-;;:::i;77669:1550::-;;;;;;:::i;:::-;;:::i;63370:27::-;;;;;;;;;;-1:-1:-1;63370:27:0;;;;;:::i;:::-;;:::i;66178:402::-;;;;;;;;;;-1:-1:-1;66178:402:0;;;;;:::i;:::-;;:::i;69269:339::-;;;;;;;;;;-1:-1:-1;69269:339:0;;;;;:::i;:::-;;:::i;80695:303::-;;;;;;;;;;;;;:::i;74368:107::-;;;;;;;;;;-1:-1:-1;74368:107:0;;;;;:::i;:::-;74428:4;74452:15;;;:6;:15;;;;;;;74368:107;40746:239;;;;;;;;;;-1:-1:-1;40746:239:0;;;;;:::i;:::-;;:::i;68903:358::-;;;;;;;;;;-1:-1:-1;68903:358:0;;;;;:::i;:::-;;:::i;40476:208::-;;;;;;;;;;-1:-1:-1;40476:208:0;;;;;:::i;:::-;;:::i;25498:94::-;;;;;;;;;;;;;:::i;87171:113::-;;;;;;;;;;;;;:::i;82867:102::-;;;;;;;;;;;;;:::i;64047:228::-;;;;;;;;;;-1:-1:-1;64047:228:0;;;;;:::i;:::-;;:::i;64283:125::-;;;;;;;;;;-1:-1:-1;64283:125:0;;;;;:::i;:::-;;:::i;63982:35::-;;;;;;;;;;-1:-1:-1;63982:35:0;;;;;:::i;:::-;;;;;;;;;;;;;;63706:27;;;;;;;;;;;;;;;;24847:87;;;;;;;;;;-1:-1:-1;24920:6:0;;-1:-1:-1;;;;;24920:6:0;24847:87;;79876:240;;;;;;;;;;-1:-1:-1;79876:240:0;;;;;:::i;:::-;;:::i;64695:111::-;;;;;;;;;;-1:-1:-1;64695:111:0;;;;;:::i;:::-;;:::i;75689:762::-;;;;;;:::i;:::-;;:::i;15512:210::-;;;;;;;;;;-1:-1:-1;15512:210:0;;;;;:::i;:::-;;:::i;41221:104::-;;;;;;;;;;;;;:::i;42874:295::-;;;;;;;;;;-1:-1:-1;42874:295:0;;;;;:::i;:::-;;:::i;68129:355::-;;;;;;;;;;-1:-1:-1;68129:355:0;;;;;:::i;:::-;;:::i;80121:255::-;;;;;;;;;;;;;:::i;72877:105::-;;;;;;;;;;-1:-1:-1;72877:105:0;;;;;:::i;:::-;;:::i;80381:308::-;;;;;;;;;;;;;:::i;63920:35::-;;;;;;;;;;-1:-1:-1;63920:35:0;;;;;:::i;:::-;;;;;;;;;;;;;;44137:328;;;;;;;;;;-1:-1:-1;44137:328:0;;;;;:::i;:::-;;:::i;69899:2956::-;;;;;;;;;;-1:-1:-1;69899:2956:0;;;;;:::i;:::-;;:::i;74483:173::-;;;;;;;;;;-1:-1:-1;74483:173:0;;;;;:::i;:::-;;:::i;69794:100::-;;;;;;;;;;-1:-1:-1;69794:100:0;;;;;:::i;:::-;;:::i;67321:406::-;;;;;;;;;;-1:-1:-1;67321:406:0;;;;;:::i;:::-;;:::i;82525:205::-;;;;;;;;;;;;;:::i;63403:37::-;;;;;;;;;;;;63436:4;63403:37;;43240:164;;;;;;;;;;-1:-1:-1;43240:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;43361:25:0;;;43337:4;43361:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;43240:164;25747:192;;;;;;;;;;-1:-1:-1;25747:192:0;;;;;:::i;:::-;;:::i;81004:393::-;;;;;;;;;;;;;:::i;63669:30::-;;;;;;;;;;;;;;;;53900:224;54002:4;-1:-1:-1;;;;;;54026:50:0;;-1:-1:-1;;;54026:50:0;;:90;;;54080:36;54104:11;54080:23;:36::i;:::-;54019:97;53900:224;-1:-1:-1;;53900:224:0:o;41052:100::-;41106:13;41139:5;41132:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41052:100;:::o;42581:221::-;42657:7;42685:16;42693:7;42685;:16::i;:::-;42677:73;;;;-1:-1:-1;;;42677:73:0;;44501:2:1;42677:73:0;;;44483:21:1;44540:2;44520:18;;;44513:30;44579:34;44559:18;;;44552:62;-1:-1:-1;;;44630:18:1;;;44623:42;44682:19;;42677:73:0;;;;;;;;;-1:-1:-1;42770:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;42770:24:0;;42581:221::o;42104:411::-;42185:13;42201:23;42216:7;42201:14;:23::i;:::-;42185:39;;42249:5;-1:-1:-1;;;;;42243:11:0;:2;-1:-1:-1;;;;;42243:11:0;;;42235:57;;;;-1:-1:-1;;;42235:57:0;;46405:2:1;42235:57:0;;;46387:21:1;46444:2;46424:18;;;46417:30;46483:34;46463:18;;;46456:62;-1:-1:-1;;;46534:18:1;;;46527:31;46575:19;;42235:57:0;46203:397:1;42235:57:0;23801:10;-1:-1:-1;;;;;42327:21:0;;;;:62;;-1:-1:-1;42352:37:0;42369:5;23801:10;43240:164;:::i;42352:37::-;42305:168;;;;-1:-1:-1;;;42305:168:0;;40075:2:1;42305:168:0;;;40057:21:1;40114:2;40094:18;;;40087:30;40153:34;40133:18;;;40126:62;40224:26;40204:18;;;40197:54;40268:19;;42305:168:0;39873:420:1;42305:168:0;42486:21;42495:2;42499:7;42486:8;:21::i;:::-;42174:341;42104:411;;:::o;76459:1198::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;76590::::1;::::0;76611:15:::1;-1:-1:-1::0;76582:79:0::1;;;;-1:-1:-1::0;;;76582:79:0::1;;;;;;;:::i;:::-;63436:4;76688:8;:15;76680:5;;:23;;;;:::i;:::-;:35;76672:78;;;::::0;-1:-1:-1;;;76672:78:0;;42376:2:1;76672:78:0::1;::::0;::::1;42358:21:1::0;42415:2;42395:18;;;42388:30;42454:32;42434:18;;;42427:60;42504:18;;76672:78:0::1;42174:354:1::0;76672:78:0::1;76768:6;76763:209;76782:8;:15;76778:1;:19;76763:209;;;76827:35;76850:8;76859:1;76850:11;;;;;;;;:::i;:::-;;;;;;;76827:22;:35::i;:::-;76819:63;;;::::0;-1:-1:-1;;;76819:63:0;;36742:2:1;76819:63:0::1;::::0;::::1;36724:21:1::0;36781:2;36761:18;;;36754:30;-1:-1:-1;;;36800:18:1;;;36793:45;36855:18;;76819:63:0::1;36540:339:1::0;76819:63:0::1;76906:27;76921:8;76930:1;76921:11;;;;;;;;:::i;:::-;;;;;;;76906:14;:27::i;:::-;76905:28;76897:63;;;::::0;-1:-1:-1;;;76897:63:0;;49047:2:1;76897:63:0::1;::::0;::::1;49029:21:1::0;49086:2;49066:18;;;49059:30;-1:-1:-1;;;49105:18:1;;;49098:52;49167:18;;76897:63:0::1;48845:346:1::0;76897:63:0::1;76799:3:::0;::::1;::::0;::::1;:::i;:::-;;;;76763:209;;;-1:-1:-1::0;77153:28:0::1;::::0;-1:-1:-1;;;;;;77170:10:0::1;11891:2:1::0;11887:15;11883:53;77153:28:0::1;::::0;::::1;11871:66:1::0;77059:15:0::1;::::0;;;11953:12:1;;77153:28:0::1;;;;;;;;;;;;77143:39;;;;;;77128:54;;77195:56;77214:5;77221:10;77232:11;77221:23;;;;;;;;:::i;:::-;;;;;;;;;77246:4;77195:18;:56::i;:::-;77191:110;;;77275:18;:11:::0;77289:4:::1;77275:18;:::i;:::-;77262:31;;77191:110;77318:6;77313:335;77332:8;:15;77328:1;:19;77313:335;;;77404:12;77419:64;77437:4;77443:27;77458:8;77467:1;77458:11;;;;;;;;:::i;:::-;;;;;;;77443:14;:27::i;:::-;77472:10;77419:17;:64::i;:::-;77404:79;;77525:4;77498:11;:24;77510:8;77519:1;77510:11;;;;;;;;:::i;:::-;;;;;;;77498:24;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;77546:5;;:7;;;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;77568:19:0::1;:21:::0;;;:19:::1;:21;::::0;::::1;:::i;:::-;;;;;;77604:32;77614:12;23801:10:::0;;23721:98;77614:12:::1;77628:7;77604:9;:32::i;:::-;-1:-1:-1::0;77349:3:0;::::1;::::0;::::1;:::i;:::-;;;;77313:335;;;-1:-1:-1::0;;27736:1:0;28688:7;:22;-1:-1:-1;;;;76459:1198:0:o;64931:126::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65015:15:::1;:34:::0;;-1:-1:-1;;;;;;65015:34:0::1;-1:-1:-1::0;;;;;65015:34:0;;;::::1;::::0;;;::::1;::::0;;64931:126::o;63495:22::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63495:22:0;:::o;79691:176::-;79747:4;79768:21;;;:11;:21;;;;;;;;:29;;:21;:29;79764:73;;;-1:-1:-1;79821:4:0;;79691:176;-1:-1:-1;79691:176:0:o;79764:73::-;-1:-1:-1;79854:5:0;;79691:176;-1:-1:-1;79691:176:0:o;66964:349::-;67025:13;67059:16;67067:7;67059;:16::i;:::-;67051:46;;;;-1:-1:-1;;;67051:46:0;;;;;;;:::i;:::-;67177:12;;67141:22;67260:15;;;:6;:15;;;;;;;;67225:51;;-1:-1:-1;;;67225:51:0;;67112:20;;-1:-1:-1;;;;;67177:12:0;;67214:10;;67177:12;;67225:25;;:51;;67251:7;;67225:51;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;67225:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67214:63;;;;;;;;:::i;:::-;;;;;;;;67205:72;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67205:72:0;;66964:349;-1:-1:-1;;;;;;;;66964:349:0:o;43471:339::-;43666:41;23801:10;43699:7;43666:18;:41::i;:::-;43658:103;;;;-1:-1:-1;;;43658:103:0;;;;;;;:::i;:::-;43774:28;43784:4;43790:2;43794:7;43774:9;:28::i;65824:346::-;65884:13;65918:16;65926:7;65918;:16::i;:::-;65910:46;;;;-1:-1:-1;;;65910:46:0;;;;;;;:::i;:::-;66036:12;;66000:22;66117:15;;;:6;:15;;;;;;;;66083:50;;-1:-1:-1;;;66083:50:0;;65971:20;;-1:-1:-1;;;;;66036:12:0;;66073:9;;66036:12;;66083:24;;:50;;66108:7;;66083:50;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;54208:256:0;54305:7;54341:23;54358:5;54341:16;:23::i;:::-;54333:5;:31;54325:87;;;;-1:-1:-1;;;54325:87:0;;35911:2:1;54325:87:0;;;35893:21:1;35950:2;35930:18;;;35923:30;35989:34;35969:18;;;35962:62;-1:-1:-1;;;36040:18:1;;;36033:41;36091:19;;54325:87:0;35709:407:1;54325:87:0;-1:-1:-1;;;;;;54430:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;54208:256::o;69651:102::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;69726:19;;::::1;::::0;:12:::1;::::0;:19:::1;::::0;::::1;::::0;::::1;:::i;:::-;;69651:102:::0;:::o;74661:1020::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;74774::::1;::::0;74795:15:::1;-1:-1:-1::0;74766:79:0::1;;;;-1:-1:-1::0;;;74766:79:0::1;;;;;;;:::i;:::-;74884:19;::::0;74876:5:::1;::::0;74864:17:::1;::::0;63436:4:::1;74864:17;:::i;:::-;:39;74856:83;;;::::0;-1:-1:-1;;;74856:83:0;;45685:2:1;74856:83:0::1;::::0;::::1;45667:21:1::0;45724:2;45704:18;;;45697:30;45763:33;45743:18;;;45736:61;45814:18;;74856:83:0::1;45483:355:1::0;74856:83:0::1;63436:4;74958:5;;:17;74950:59;;;::::0;-1:-1:-1;;;74950:59:0;;37850:2:1;74950:59:0::1;::::0;::::1;37832:21:1::0;37889:2;37869:18;;;37862:30;37928:31;37908:18;;;37901:59;37977:18;;74950:59:0::1;37648:353:1::0;74950:59:0::1;75035:8;;75022:9;:21;75014:59;;;;-1:-1:-1::0;;;75014:59:0::1;;;;;;;:::i;:::-;23801:10:::0;75092:31:::1;::::0;;;:17:::1;:31;::::0;;;;;75126:1:::1;-1:-1:-1::0;75084:69:0::1;;;::::0;-1:-1:-1;;;75084:69:0;;40846:2:1;75084:69:0::1;::::0;::::1;40828:21:1::0;40885:2;40865:18;;;40858:30;-1:-1:-1;;;40904:18:1;;;40897:51;40965:18;;75084:69:0::1;40644:345:1::0;75084:69:0::1;75216:28;::::0;-1:-1:-1;;;;;;75233:10:0::1;11891:2:1::0;11887:15;11883:53;75216:28:0::1;::::0;::::1;11871:66:1::0;75191:12:0::1;::::0;11953::1;;75216:28:0::1;;;;;;;;;;;;75206:39;;;;;;75191:54;;75258:56;75277:5;75284:10;75295:11;75284:23;;;;;;;;:::i;75258:56::-;75250:82;;;::::0;-1:-1:-1;;;75250:82:0;;47987:2:1;75250:82:0::1;::::0;::::1;47969:21:1::0;48026:2;48006:18;;;47999:30;-1:-1:-1;;;48045:18:1;;;48038:43;48098:18;;75250:82:0::1;47785:337:1::0;75250:82:0::1;75341:15;75359:18;:11:::0;75373:4:::1;75359:18;:::i;:::-;75341:36;;75433:12;75448:39;75466:5;75473:1:::0;75476:10:::1;75448:17;:39::i;:::-;75492:5;:7:::0;;75433:54;;-1:-1:-1;75492:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;75623;75589:17;:31;75607:12;23801:10:::0;;23721:98;75607:12:::1;-1:-1:-1::0;;;;;75589:31:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;75589:31:0;:41;75637:32:::1;23801:10:::0;75647:12:::1;23721:98:::0;75637:32:::1;-1:-1:-1::0;;27736:1:0;28688:7;:22;-1:-1:-1;;;74661:1020:0:o;73008:1352::-;73062:13;73096:16;73104:7;73096;:16::i;:::-;73088:58;;;;-1:-1:-1;;;73088:58:0;;43788:2:1;73088:58:0;;;43770:21:1;43827:2;43807:18;;;43800:30;43866:31;43846:18;;;43839:59;43915:18;;73088:58:0;43586:353:1;73088:58:0;73195:12;;73159:22;73306:15;;;:6;:15;;;;;;;73272:50;;-1:-1:-1;;;73272:50:0;;-1:-1:-1;;;;;73195:12:0;;;;;;73272:24;;:50;;73297:7;;73272:50;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;73272:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73364:20;73422:15;;;:6;:15;;;;;;;73387:51;;-1:-1:-1;;;73387:51:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;73250:72:0;;-1:-1:-1;73364:20:0;-1:-1:-1;;;;;73387:25:0;;;;;33855:18:1;;73387:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73364:74;;73451:20;;:::i;:::-;73551:15;;;;:6;:15;;;;;;73549:18;;:1;:18::i;:::-;73593:15;;;;:6;:15;;;;;;73591:18;;:1;:18::i;:::-;73633:17;73635:14;73633:1;:17::i;:::-;73674:29;73676:26;73694:7;73676:17;:26::i;73674:29::-;73514:209;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;73514:209:0;;;;;;73484:250;;73811:18;73813:15;73811:1;:18::i;:::-;73853:30;73855:27;73874:7;73855:18;:27::i;73853:30::-;73946:15;;;;:6;:15;;;;;;;;73909:53;;-1:-1:-1;;;73909:53:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;73907:56:0;;-1:-1:-1;;;;;73909:27:0;;;;;33855:18:1;;73909:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;73907:56::-;74027:15;;;;:6;:15;;;;;;;;73989:54;;-1:-1:-1;;;73989:54:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;73987:57:0;;-1:-1:-1;;;;;73989:28:0;;;;;33855:18:1;;73989:54:0;33708:248:1;73987:57:0;74068:23;74070:20;74082:7;74070:11;:20::i;74068:23::-;73776:330;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;73776:330:0;;;;;;73755:6;;;;:356;;;74219:6;;74176:105;;74124:20;;74176:105;;74219:6;73776:330;;74176:105;;:::i;:::-;;;;;;;;;;;;;74124:176;;74344:6;74327:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;74313:39;;;;;;;73008:1352;;;:::o;64569:117::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64647:18:::1;:31:::0;64569:117::o;43881:185::-;44019:39;44036:4;44042:2;44046:7;44019:39;;;;;;;;;;;;:16;:39::i;64416:145::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64513:18:::1;:40:::0;;-1:-1:-1;;;;;;64513:40:0::1;-1:-1:-1::0;;;;;64513:40:0;;;::::1;::::0;;;::::1;::::0;;64416:145::o;64811:112::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64887:12:::1;:28:::0;;-1:-1:-1;;;;;;64887:28:0::1;-1:-1:-1::0;;;;;64887:28:0;;;::::1;::::0;;;::::1;::::0;;64811:112::o;65204:251::-;65261:13;65295:16;65303:7;65295;:16::i;:::-;65287:46;;;;-1:-1:-1;;;65287:46:0;;;;;;;:::i;:::-;65348:20;65392:10;65403:6;:15;65410:7;65403:15;;;;;;;;;;;;65392:27;;;;;;;;:::i;:::-;;;;;;;;65383:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65383:36:0;;65204:251;-1:-1:-1;;;;;;;65204:251:0:o;54730:233::-;54805:7;54841:30;54628:10;:17;;54540:113;54841:30;54833:5;:38;54825:95;;;;-1:-1:-1;;;54825:95:0;;47574:2:1;54825:95:0;;;47556:21:1;47613:2;47593:18;;;47586:30;47652:34;47632:18;;;47625:62;-1:-1:-1;;;47703:18:1;;;47696:42;47755:19;;54825:95:0;47372:408:1;54825:95:0;54938:10;54949:5;54938:17;;;;;;;;:::i;:::-;;;;;;;;;54931:24;;54730:233;;;:::o;77669:1550::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;77816::::1;::::0;77837:15:::1;-1:-1:-1::0;77808:79:0::1;;;;-1:-1:-1::0;;;77808:79:0::1;;;;;;;:::i;:::-;63436:4;77918:8;:15;77906:5;;77914:1;77906:9;;;;:::i;:::-;:27;;;;:::i;:::-;:39;77898:82;;;::::0;-1:-1:-1;;;77898:82:0;;42376:2:1;77898:82:0::1;::::0;::::1;42358:21:1::0;42415:2;42395:18;;;42388:30;42454:32;42434:18;;;42427:60;42504:18;;77898:82:0::1;42174:354:1::0;77898:82:0::1;78012:8;;77999:9;:21;77991:59;;;;-1:-1:-1::0;;;77991:59:0::1;;;;;;;:::i;:::-;23801:10:::0;78069:31:::1;::::0;;;:17:::1;:31;::::0;;;;;78103:1:::1;-1:-1:-1::0;78061:69:0::1;;;::::0;-1:-1:-1;;;78061:69:0;;40846:2:1;78061:69:0::1;::::0;::::1;40828:21:1::0;40885:2;40865:18;;;40858:30;-1:-1:-1;;;40904:18:1;;;40897:51;40965:18;;78061:69:0::1;40644:345:1::0;78061:69:0::1;78148:6;78143:209;78162:8;:15;78158:1;:19;78143:209;;;78207:35;78230:8;78239:1;78230:11;;;;;;;;:::i;78207:35::-;78199:63;;;::::0;-1:-1:-1;;;78199:63:0;;36742:2:1;78199:63:0::1;::::0;::::1;36724:21:1::0;36781:2;36761:18;;;36754:30;-1:-1:-1;;;36800:18:1;;;36793:45;36855:18;;78199:63:0::1;36540:339:1::0;78199:63:0::1;78286:27;78301:8;78310:1;78301:11;;;;;;;;:::i;78286:27::-;78285:28;78277:63;;;::::0;-1:-1:-1;;;78277:63:0;;49047:2:1;78277:63:0::1;::::0;::::1;49029:21:1::0;49086:2;49066:18;;;49059:30;-1:-1:-1;;;49105:18:1;;;49098:52;49167:18;;78277:63:0::1;48845:346:1::0;78277:63:0::1;78179:3:::0;::::1;::::0;::::1;:::i;:::-;;;;78143:209;;;-1:-1:-1::0;78458:28:0::1;::::0;-1:-1:-1;;;;;;78475:10:0::1;11891:2:1::0;11887:15;11883:53;78458:28:0::1;::::0;::::1;11871:66:1::0;78364:15:0::1;::::0;;;11953:12:1;;78458:28:0::1;;;;;;;;;;;;78448:39;;;;;;78433:54;;78500:56;78519:5;78526:10;78537:11;78526:23;;;;;;;;:::i;78500:56::-;78492:82;;;::::0;-1:-1:-1;;;78492:82:0;;47987:2:1;78492:82:0::1;::::0;::::1;47969:21:1::0;48026:2;48006:18;;;47999:30;-1:-1:-1;;;48045:18:1;;;48038:43;48098:18;;78492:82:0::1;47785:337:1::0;78492:82:0::1;78602:18;:11:::0;78616:4:::1;78602:18;:::i;:::-;78589:31;;78675:6;78670:300;78689:8;:15;78685:1;:19;78670:300;;;78726:12;78741:64;78759:4;78765:27;78780:8;78789:1;78780:11;;;;;;;;:::i;78741:64::-;78726:79;;78847:4;78820:11;:24;78832:8;78841:1;78832:11;;;;;;;;:::i;:::-;;;;;;;78820:24;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;78868:5;;:7;;;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;78890:19:0::1;:21:::0;;;:19:::1;:21;::::0;::::1;:::i;:::-;;;;;;78926:32;78936:12;23801:10:::0;;23721:98;78926:32:::1;-1:-1:-1::0;78706:3:0;::::1;::::0;::::1;:::i;:::-;;;;78670:300;;;;79012:22;79037:39;79055:5;79062:1:::0;79065:10:::1;79037:17;:39::i;:::-;79087:5;:7:::0;;79012:64;;-1:-1:-1;79087:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;79139:17;79105;:31;79123:12;23801:10:::0;;23721:98;79123:12:::1;-1:-1:-1::0;;;;;79105:31:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;79105:31:0;:51;79167:42:::1;23801:10:::0;79177:12:::1;23721:98:::0;63370:27;;;;;;;;;;;;66178:402;66243:4;66268:16;66276:7;66268;:16::i;:::-;66260:46;;;;-1:-1:-1;;;66260:46:0;;;;;;;:::i;:::-;66377:12;;66321:11;66460:15;;;:6;:15;;;;;;;66421:55;;-1:-1:-1;;;66421:55:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;66321:11:0;;-1:-1:-1;;;;;66377:12:0;;66321:11;;66377:12;;66421:29;;33855:18:1;;66421:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74428:4;74452:15;;;:6;:15;;;;;;66399:77;;-1:-1:-1;66501:38:0;;:14;:38;:::i;:::-;66500:44;;66543:1;66500:44;:::i;:::-;66491:53;66178:402;-1:-1:-1;;;;;66178:402:0:o;69269:339::-;69328:4;69353:16;69361:7;69353;:16::i;:::-;69345:46;;;;-1:-1:-1;;;69345:46:0;;;;;;;:::i;:::-;69462:12;;69406:11;74452:15;;;:6;:15;;;;;;;;;69532:6;:15;;;;;;;69499:49;;-1:-1:-1;;;69499:49:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;69406:11:0;;-1:-1:-1;;;;;69462:12:0;;;;69499:23;;33855:18:1;;69499:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;;;;:::i;:::-;69490:82;69269:339;-1:-1:-1;;;;69269:339:0:o;80695:303::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;80766:14:::1;::::0;-1:-1:-1;;;;;80766:14:0::1;80752:10;:28;80744:53;;;::::0;-1:-1:-1;;;80744:53:0;;38208:2:1;80744:53:0::1;::::0;::::1;38190:21:1::0;38247:2;38227:18;;;38220:30;-1:-1:-1;;;38266:18:1;;;38259:42;38318:18;;80744:53:0::1;38006:336:1::0;80744:53:0::1;80810:13;::::0;;;::::1;;;:22;80802:50;;;;-1:-1:-1::0;;;80802:50:0::1;;;;;;;:::i;:::-;80861:13;:20:::0;;-1:-1:-1;;80861:20:0::1;::::0;::::1;::::0;;;80901:30:::1;80861:20:::0;;;80901:17:::1;:30::i;:::-;80942:5;:7:::0;;80886:45;;-1:-1:-1;80942:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;80960:30;80970:10;80982:7;80960:9;:30::i;:::-;-1:-1:-1::0;27736:1:0;28688:7;:22;80695:303::o;40746:239::-;40818:7;40854:16;;;:7;:16;;;;;;-1:-1:-1;;;;;40854:16:0;40889:19;40881:73;;;;-1:-1:-1;;;40881:73:0;;41607:2:1;40881:73:0;;;41589:21:1;41646:2;41626:18;;;41619:30;41685:34;41665:18;;;41658:62;-1:-1:-1;;;41736:18:1;;;41729:39;41785:19;;40881:73:0;41405:405:1;68903:358:0;68967:13;69001:16;69009:7;69001;:16::i;:::-;68993:46;;;;-1:-1:-1;;;68993:46:0;;;;;;;:::i;:::-;69119:12;;69083:22;69208:15;;;:6;:15;;;;;;;;69170:54;;-1:-1:-1;;;69170:54:0;;69054:20;;-1:-1:-1;;;;;69119:12:0;;69156:13;;69119:12;;69170:28;;:54;;69199:7;;69170:54;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;40476:208:0;40548:7;-1:-1:-1;;;;;40576:19:0;;40568:74;;;;-1:-1:-1;;;40568:74:0;;41196:2:1;40568:74:0;;;41178:21:1;41235:2;41215:18;;;41208:30;41274:34;41254:18;;;41247:62;-1:-1:-1;;;41325:18:1;;;41318:40;41375:19;;40568:74:0;40994:406:1;40568:74:0;-1:-1:-1;;;;;;40660:16:0;;;;;:9;:16;;;;;;;40476:208::o;25498:94::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;25563:21:::1;25581:1;25563:9;:21::i;:::-;25498:94::o:0;87171:113::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;87224:51:::1;::::0;87232:10:::1;::::0;87253:21:::1;87224:51:::0;::::1;;;::::0;::::1;::::0;;;87253:21;87232:10;87224:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;87171:113::o:0;82867:102::-;24920:6;;82925:4;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;-1:-1:-1;82949:12:0::1;::::0;82867:102;:::o;64047:228::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64143:16:::1;::::0;;64157:1:::1;64143:16:::0;;::::1;::::0;::::1;::::0;;;;64130:29;::::1;::::0;:10:::1;::::0;:29:::1;:::i;:::-;;64175:6;64170:98;64189:9;:16;64185:1;:20;64170:98;;;64227:10;64243:9;64253:1;64243:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;64227:29;;::::1;::::0;::::1;::::0;;-1:-1:-1;64227:29:0;;;;;;;::::1;::::0;64207:3;::::1;::::0;::::1;:::i;:::-;;;;64170:98;;64283:125:::0;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64370:13:::1;:30:::0;;-1:-1:-1;;;;;;64370:30:0::1;-1:-1:-1::0;;;;;64370:30:0;;;::::1;::::0;;;::::1;::::0;;64283:125::o;79876:240::-;80005:12;;80042:36;;-1:-1:-1;;;80042:36:0;;;;;33672:25:1;;;79936:4:0;;;;-1:-1:-1;;;;;80005:12:0;;;;;;80042:26;;33645:18:1;;80042:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;64695:111::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;64770:15:::1;:28:::0;64695:111::o;75689:762::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;75778:15:::1;::::0;75796::::1;-1:-1:-1::0;75770:75:0::1;;;::::0;-1:-1:-1;;;75770:75:0;;48689:2:1;75770:75:0::1;::::0;::::1;48671:21:1::0;48728:2;48708:18;;;48701:30;48767:31;48747:18;;;48740:59;48816:18;;75770:75:0::1;48487:353:1::0;75770:75:0::1;75884:19;::::0;75876:5:::1;::::0;75864:17:::1;::::0;63436:4:::1;75864:17;:::i;:::-;:39;75856:83;;;::::0;-1:-1:-1;;;75856:83:0;;45685:2:1;75856:83:0::1;::::0;::::1;45667:21:1::0;45724:2;45704:18;;;45697:30;45763:33;45743:18;;;45736:61;45814:18;;75856:83:0::1;45483:355:1::0;75856:83:0::1;63436:4;75966:14;75958:5;;:22;;;;:::i;:::-;:34;75950:76;;;::::0;-1:-1:-1;;;75950:76:0;;37850:2:1;75950:76:0::1;::::0;::::1;37832:21:1::0;37889:2;37869:18;;;37862:30;37928:31;37908:18;;;37901:59;37977:18;;75950:76:0::1;37648:353:1::0;75950:76:0::1;76062:1;76045:14;:18;76037:55;;;::::0;-1:-1:-1;;;76037:55:0;;34809:2:1;76037:55:0::1;::::0;::::1;34791:21:1::0;34848:2;34828:18;;;34821:30;34887:26;34867:18;;;34860:54;34931:18;;76037:55:0::1;34607:348:1::0;76037:55:0::1;76128:2;76111:14;:19;76103:58;;;::::0;-1:-1:-1;;;76103:58:0;;44146:2:1;76103:58:0::1;::::0;::::1;44128:21:1::0;44185:2;44165:18;;;44158:30;44224:28;44204:18;;;44197:56;44270:18;;76103:58:0::1;43944:350:1::0;76103:58:0::1;76204:14;76187;;:31;;;;:::i;:::-;76174:9;:44;76166:82;;;;-1:-1:-1::0;;;76166:82:0::1;;;;;;;:::i;:::-;76273:1;76261:181;76280:14;76276:1;:18;76261:181;;;76316:12;76331:30;76349:5;76356:1:::0;76359::::1;76331:17;:30::i;:::-;76376:5;:7:::0;;76316:45;;-1:-1:-1;76376:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;76398:32;76408:12;23801:10:::0;;23721:98;76398:32:::1;-1:-1:-1::0;76296:3:0;::::1;::::0;::::1;:::i;:::-;;;;76261:181;;;-1:-1:-1::0;;27736:1:0;28688:7;:22;75689:762::o;15512:210::-;15605:10;-1:-1:-1;;;;;15619:14:0;15605:28;;15597:72;;;;-1:-1:-1;;;15597:72:0;;46045:2:1;15597:72:0;;;46027:21:1;46084:2;46064:18;;;46057:30;46123:33;46103:18;;;46096:61;46174:18;;15597:72:0;45843:355:1;15597:72:0;82828:12;:25;-1:-1:-1;69651:102:0:o;41221:104::-;41277:13;41310:7;41303:14;;;;;:::i;42874:295::-;-1:-1:-1;;;;;42977:24:0;;23801:10;42977:24;;42969:62;;;;-1:-1:-1;;;42969:62:0;;38954:2:1;42969:62:0;;;38936:21:1;38993:2;38973:18;;;38966:30;39032:27;39012:18;;;39005:55;39077:18;;42969:62:0;38752:349:1;42969:62:0;23801:10;43044:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;43044:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;43044:53:0;;;;;;;;;;43113:48;;33140:41:1;;;43044:42:0;;23801:10;43113:48;;33113:18:1;43113:48:0;;;;;;;42874:295;;:::o;68129:355::-;68192:13;68226:16;68234:7;68226;:16::i;:::-;68218:46;;;;-1:-1:-1;;;68218:46:0;;;;;;;:::i;:::-;68344:12;;68308:22;68431:15;;;:6;:15;;;;;;;;68394:53;;-1:-1:-1;;;68394:53:0;;68279:20;;-1:-1:-1;;;;;68344:12:0;;68381;;68344;;68394:27;;:53;;68422:7;;68394:53;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;80121:255:0;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;27780:1:::1;28376:7;;:19;;28368:63;;;;-1:-1:-1::0;;;28368:63:0::1;;;;;;;:::i;:::-;27780:1;28509:7;:18:::0;80189:14:::2;::::0;::::2;;:23;80181:51;;;;-1:-1:-1::0;;;80181:51:0::2;;;;;;;:::i;:::-;80241:14;:21:::0;;-1:-1:-1;;80241:21:0::2;80258:4;80241:21;::::0;;:14:::2;80282:30;80241:14:::0;;;80282:17:::2;:30::i;:::-;80323:5;:7:::0;;80267:45;;-1:-1:-1;80323:5:0::2;:7;::::0;::::2;:::i;:::-;;;;;;80341:27;80351:7;24920:6:::0;;-1:-1:-1;;;;;24920:6:0;;24847:87;72877:105;72924:13;72951:26;72968:8;72951:16;:26::i;80381:308::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;80453:15:::1;::::0;;;::::1;-1:-1:-1::0;;;;;80453:15:0::1;80439:10;:29;80431:55;;;::::0;-1:-1:-1;;;80431:55:0;;42735:2:1;80431:55:0::1;::::0;::::1;42717:21:1::0;42774:2;42754:18;;;42747:30;-1:-1:-1;;;42793:18:1;;;42786:43;42846:18;;80431:55:0::1;42533:337:1::0;80431:55:0::1;80499:14;::::0;::::1;::::0;::::1;;;:23;80491:51;;;;-1:-1:-1::0;;;80491:51:0::1;;;;;;;:::i;:::-;80551:14;:21:::0;;-1:-1:-1;;80551:21:0::1;;;::::0;;;80592:30:::1;80551:21:::0;;;80592:17:::1;:30::i;44137:328::-:0;44312:41;23801:10;44345:7;44312:18;:41::i;:::-;44304:103;;;;-1:-1:-1;;;44304:103:0;;;;;;;:::i;:::-;44418:39;44432:4;44438:2;44442:7;44451:5;44418:13;:39::i;:::-;44137:328;;;;:::o;69899:2956::-;69962:13;69996:17;70004:8;69996:7;:17::i;:::-;69988:59;;;;-1:-1:-1;;;69988:59:0;;43788:2:1;69988:59:0;;;43770:21:1;43827:2;43807:18;;;43800:30;43866:31;43846:18;;;43839:59;43915:18;;69988:59:0;43586:353:1;69988:59:0;70060:21;;:::i;:::-;70183:11;70185:8;70183:1;:11::i;:::-;74428:4;74452:15;;;:6;:15;;;;;;70209:25;;72877:105;:::i;70209:25::-;70290:16;;;;:6;:16;;;;;;70274:12;;70288:19;;:1;:19::i;:::-;70357:11;70379:16;70386:8;70379:6;:16::i;:::-;70405:11;70407:8;70405:1;:11::i;:::-;70116:442;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;70116:442:0;;;;;;70094:469;;70679:19;70689:8;70679:9;:19::i;:::-;74428:4;74452:15;;;:6;:15;;;;;;70832:25;;72877:105;:::i;70832:25::-;70598:302;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;70598:302:0;;;;;;70576:7;;;:329;71053:22;71066:8;71053:12;:22::i;:::-;71084:30;71086:27;71104:8;71086:17;:27::i;71084:30::-;70938:219;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;70938:219:0;;;;;;70916:7;;:246;71312:23;71326:8;71312:13;:23::i;:::-;71343:31;71345:28;71364:8;71345:18;:28::i;71343:31::-;71197:220;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;71197:220:0;;;;;;71175:7;;;:247;71575:25;71591:8;71575:15;:25::i;:::-;71455:188;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;71455:188:0;;;;;;71433:7;;;:215;71813:26;71830:8;71813:16;:26::i;:::-;71962:24;71964:21;71976:8;71964:11;:21::i;71962:24::-;71681:347;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;71681:347:0;;;;;;71659:7;;;:374;72128:11;72150:16;72157:8;72150:6;:16::i;:::-;72177:11;72179:8;72177:1;:11::i;:::-;72233;72255:16;72262:8;72255:6;:16::i;:::-;72282:11;72284:8;72282:1;:11::i;:::-;72066:252;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;72066:252:0;;;;;;72044:7;;;:279;;;72483:7;;72044;72517;;;;72551;;;;72585;;;;72619;;;;72653;;;;72440:277;;72336:20;;72359:403;;72440:277;;72483:7;72653;;72440:277;;:::i;:::-;;;;;;;;;;;;;72359:13;:403::i;:::-;72336:426;;72839:6;72789:57;;;;;;;;:::i;:::-;;;;;;;;;;;;;72775:72;;;;69899:2956;;;:::o;74483:173::-;74573:15;;-1:-1:-1;;;;;74573:15:0;74559:10;:29;74551:63;;;;-1:-1:-1;;;74551:63:0;;43077:2:1;74551:63:0;;;43059:21:1;43116:2;43096:18;;;43089:30;-1:-1:-1;;;43135:18:1;;;43128:51;43196:18;;74551:63:0;42875:345:1;74551:63:0;74625:15;;;;:6;:15;;;;;;:23;74483:173::o;69794:100::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;69868:18;;::::1;::::0;:11:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;67321:406::-:0;67387:4;67412:16;67420:7;67412;:16::i;:::-;67404:46;;;;-1:-1:-1;;;67404:46:0;;;;;;;:::i;:::-;67521:12;;67465:11;67606:15;;;:6;:15;;;;;;;67566:56;;-1:-1:-1;;;67566:56:0;;;;;33882:25:1;;;33923:18;;;33916:34;;;;67465:11:0;;-1:-1:-1;;;;;67521:12:0;;67465:11;;67521:12;;67566:30;;33855:18:1;;67566:56:0;33708:248:1;82525:205:0;24920:6;;82578:17;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;82649:3:::1;::::0;82616:29:::1;::::0;-1:-1:-1;;;82616:29:0;;82639:4:::1;82616:29;::::0;::::1;32055:51:1::0;82616:4:0::1;-1:-1:-1::0;;;;;82616:14:0::1;::::0;::::1;::::0;32028:18:1;;82616:29:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;82608:65;;;::::0;-1:-1:-1;;;82608:65:0;;35162:2:1;82608:65:0::1;::::0;::::1;35144:21:1::0;35201:2;35181:18;;;35174:30;-1:-1:-1;;;35220:18:1;;;35213:46;35276:18;;82608:65:0::1;34960:340:1::0;82608:65:0::1;82691:31;82709:7;;82718:3;;82691:17;:31::i;:::-;82684:38;;82525:205:::0;:::o;25747:192::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;25836:22:0;::::1;25828:73;;;::::0;-1:-1:-1;;;25828:73:0;;37086:2:1;25828:73:0::1;::::0;::::1;37068:21:1::0;37125:2;37105:18;;;37098:30;37164:34;37144:18;;;37137:62;-1:-1:-1;;;37215:18:1;;;37208:36;37261:19;;25828:73:0::1;36884:402:1::0;25828:73:0::1;25912:19;25922:8;25912:9;:19::i;81004:393::-:0;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;81077:16:::1;::::0;-1:-1:-1;;;;;81077:16:0::1;81063:10;:30;81055:63;;;::::0;-1:-1:-1;;;81055:63:0;;46807:2:1;81055:63:0::1;::::0;::::1;46789:21:1::0;46846:2;46826:18;;;46819:30;-1:-1:-1;;;46865:18:1;;;46858:50;46925:18;;81055:63:0::1;46605:344:1::0;81055:63:0::1;81131:15;::::0;;;::::1;;;:24;81123:52;;;;-1:-1:-1::0;;;81123:52:0::1;;;;;;;:::i;:::-;81184:15;:22:::0;;-1:-1:-1;;81184:22:0::1;::::0;::::1;::::0;;;81219:167:::1;81238:2;81234:1;:6;81219:167;;;81262:12;81277:30;81295:5;81302:1:::0;81305::::1;81277:17;:30::i;:::-;81322:5;:7:::0;;81262:45;;-1:-1:-1;81322:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;81344:30;81354:10;81366:7;81344:9;:30::i;:::-;-1:-1:-1::0;81242:3:0;::::1;::::0;::::1;:::i;:::-;;;;81219:167;;40107:305:::0;40209:4;-1:-1:-1;;;;;;40246:40:0;;-1:-1:-1;;;40246:40:0;;:105;;-1:-1:-1;;;;;;;40303:48:0;;-1:-1:-1;;;40303:48:0;40246:105;:158;;;-1:-1:-1;;;;;;;;;;38823:40:0;;;40368:36;38714:157;45975:127;46040:4;46064:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46064:16:0;:30;;;45975:127::o;49957:174::-;50032:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;50032:29:0;-1:-1:-1;;;;;50032:29:0;;;;;;;;:24;;50086:23;50032:24;50086:14;:23::i;:::-;-1:-1:-1;;;;;50077:46:0;;;;;;;;;;;49957:174;;:::o;79227:267::-;79347:13;;79375:35;;-1:-1:-1;;;79375:35:0;;;;;33672:25:1;;;79296:4:0;;-1:-1:-1;;;;;79347:13:0;;79414:10;;79347:13;;79375:25;;33645:18:1;;79375:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;79375:49:0;;79372:92;;;-1:-1:-1;79448:4:0;;79227:267;-1:-1:-1;;79227:267:0:o;79372:92::-;-1:-1:-1;79481:5:0;;79227:267;-1:-1:-1;;79227:267:0:o;1714:190::-;1839:4;1892;1863:25;1876:5;1883:4;1863:12;:25::i;:::-;:33;;1714:190;-1:-1:-1;;;;1714:190:0:o;83256:3069::-;83352:4;83377:12;;83393:1;83377:17;;83369:65;;;;-1:-1:-1;;;83369:65:0;;35507:2:1;83369:65:0;;;35489:21:1;35546:2;35526:18;;;35519:30;35585:34;35565:18;;;35558:62;-1:-1:-1;;;35636:18:1;;;35629:33;35679:19;;83369:65:0;35305:399:1;83369:65:0;83483:21;83519:5;;63436:4;83507:17;;;;:::i;:::-;83483:41;-1:-1:-1;83606:14:0;83623:21;;:48;;83651:20;83670:1;83651:16;:20;:::i;:::-;83623:48;;;83647:1;83623:48;83754:12;;83768:5;;83737:84;;83606:65;;-1:-1:-1;83709:10:0;;83826:16;;83737:84;;83754:12;;83768:5;;;;;83775:10;;83787:16;;83805:15;;83737:84;;;:::i;:::-;;;;;;;;;;;;;83727:95;;;;;;83722:101;;:120;;;;:::i;:::-;83709:133;;83859:12;83898:7;83906:5;83898:14;;;;;;;:::i;:::-;;;:43;;83936:5;83898:43;;;83920:7;83928:5;83920:14;;;;;;;:::i;:::-;;;83898:43;83888:53;;83969:7;83977:9;83969:18;;;;;;;:::i;:::-;;;:23;:56;;84007:7;84015:9;84007:18;;;;;;;:::i;:::-;;;83969:56;;;83995:9;83969:56;83952:7;83960:5;83952:14;;;;;;;:::i;:::-;;:73;84099:12;;84113:5;;84082:84;;84038:16;;84172:2;;84082:84;;84113:5;;;;;84120:10;;84132:16;;84150:15;;84082:84;;;:::i;:::-;;;;;;;;;;;;;84072:95;;;;;;84064:104;;84057:117;;;;:::i;:::-;84185:5;:18;;84038:136;;-1:-1:-1;84038:136:0;;84185:5;;:18;;84038:136;;84185:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84322:18:0;;84384:66;;-1:-1:-1;;;84384:66:0;;33413:14:1;;33406:22;84384:66:0;;;33388:41:1;33445:18;;;33438:34;;;33488:18;;;33481:34;;;-1:-1:-1;;;;;84322:18:0;;;;-1:-1:-1;;84322:18:0;;84384:30;;33361:18:1;;84384:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84384:66:0;;;;;;;;;;;;:::i;:::-;84689:13;;;84700:1;84689:13;;;;;;;;;84352:98;;-1:-1:-1;84629:15:0;;;;84689:13;;;;;;;;;;-1:-1:-1;84689:13:0;84655:47;;84718:6;84713:155;84732:15;:22;84728:1;:26;84713:155;;;84790:15;84806:1;84790:18;;;;;;;;:::i;:::-;;;;;;;84776:32;;;;;:::i;:::-;;;84846:10;84823:17;84841:1;84823:20;;;;;;;;:::i;:::-;;;;;;;;;;:33;84756:3;;;;:::i;:::-;;;;84713:155;;;-1:-1:-1;84995:12:0;;85009:5;;84978:84;;84944:16;;85067:10;;84978:84;;85009:5;;;;;85016:10;;85028:16;;85046:15;;84978:84;;;:::i;:::-;;;;;;;;;;;;;84968:95;;;;;;84963:101;;:114;;;;:::i;:::-;84944:133;;85090:17;85212;85230:1;85212:20;;;;;;;;:::i;:::-;;;;;;;85197:11;:35;;:73;;;;;85250:17;85268:1;85250:20;;;;;;;;:::i;:::-;;;;;;;85236:11;:34;85197:73;85193:134;;;-1:-1:-1;85302:1:0;85193:134;85356:17;85374:1;85356:20;;;;;;;;:::i;:::-;;;;;;;85341:11;:35;;:73;;;;;85394:17;85412:1;85394:20;;;;;;;;:::i;:::-;;;;;;;85380:11;:34;85341:73;85337:130;;;-1:-1:-1;85446:1:0;85337:130;85496:17;85514:1;85496:20;;;;;;;;:::i;:::-;;;;;;;85481:11;:35;;:73;;;;;85534:17;85552:1;85534:20;;;;;;;;:::i;:::-;;;;;;;85520:11;:34;85481:73;85477:130;;;-1:-1:-1;85586:1:0;85477:130;85636:17;85654:1;85636:20;;;;;;;;:::i;:::-;;;;;;;85621:11;:35;;:74;;;;;85675:17;85693:1;85675:20;;;;;;;;:::i;:::-;;;;;;;85660:11;:35;;85621:74;85617:136;;;-1:-1:-1;85727:1:0;85617:136;85863:1;85838:8;85847:12;85838:22;;;;;;;;:::i;:::-;;;;;;;;;:26;85834:457;;;85895:8;85904:12;85895:22;;;;;;;;:::i;:::-;;;;;;;;;:24;;;;;;:::i;:::-;;;;-1:-1:-1;;86040:15:0;;;;:6;:15;;;;;;;;:30;;;86125:6;:15;;;;;86143:1;86125:19;;85834:457;;;86250:29;86266:12;86250:15;:29::i;:::-;86232:15;;;;:6;:15;;;;;:47;85834:457;-1:-1:-1;86310:7:0;;83256:3069;-1:-1:-1;;;;;;;;;;;;;83256:3069:0:o;46959:110::-;47035:26;47045:2;47049:7;47035:26;;;;;;;;;;;;:9;:26::i;46269:348::-;46362:4;46387:16;46395:7;46387;:16::i;:::-;46379:73;;;;-1:-1:-1;;;46379:73:0;;39308:2:1;46379:73:0;;;39290:21:1;39347:2;39327:18;;;39320:30;39386:34;39366:18;;;39359:62;-1:-1:-1;;;39437:18:1;;;39430:42;39489:19;;46379:73:0;39106:408:1;46379:73:0;46463:13;46479:23;46494:7;46479:14;:23::i;:::-;46463:39;;46532:5;-1:-1:-1;;;;;46521:16:0;:7;-1:-1:-1;;;;;46521:16:0;;:51;;;;46565:7;-1:-1:-1;;;;;46541:31:0;:20;46553:7;46541:11;:20::i;:::-;-1:-1:-1;;;;;46541:31:0;;46521:51;:87;;;-1:-1:-1;;;;;;43361:25:0;;;43337:4;43361:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;46576:32;43240:164;49261:578;49420:4;-1:-1:-1;;;;;49393:31:0;:23;49408:7;49393:14;:23::i;:::-;-1:-1:-1;;;;;49393:31:0;;49385:85;;;;-1:-1:-1;;;49385:85:0;;45275:2:1;49385:85:0;;;45257:21:1;45314:2;45294:18;;;45287:30;45353:34;45333:18;;;45326:62;-1:-1:-1;;;45404:18:1;;;45397:39;45453:19;;49385:85:0;45073:405:1;49385:85:0;-1:-1:-1;;;;;49489:16:0;;49481:65;;;;-1:-1:-1;;;49481:65:0;;38549:2:1;49481:65:0;;;38531:21:1;38588:2;38568:18;;;38561:30;38627:34;38607:18;;;38600:62;-1:-1:-1;;;38678:18:1;;;38671:34;38722:19;;49481:65:0;38347:400:1;49481:65:0;49559:39;49580:4;49586:2;49590:7;49559:20;:39::i;:::-;49663:29;49680:1;49684:7;49663:8;:29::i;:::-;-1:-1:-1;;;;;49705:15:0;;;;;;:9;:15;;;;;:20;;49724:1;;49705:15;:20;;49724:1;;49705:20;:::i;:::-;;;;-1:-1:-1;;;;;;;49736:13:0;;;;;;:9;:13;;;;;:18;;49753:1;;49736:13;:18;;49753:1;;49736:18;:::i;:::-;;;;-1:-1:-1;;49765:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49765:21:0;-1:-1:-1;;;;;49765:21:0;;;;;;;;;49804:27;;49765:16;;49804:27;;;;;;;49261:578;;;:::o;25947:173::-;26022:6;;;-1:-1:-1;;;;;26039:17:0;;;-1:-1:-1;;;;;;26039:17:0;;;;;;;26072:40;;26022:6;;;26039:17;26022:6;;26072:40;;26003:16;;26072:40;25992:128;25947:173;:::o;21418:723::-;21474:13;21695:10;21691:53;;-1:-1:-1;;21722:10:0;;;;;;;;;;;;-1:-1:-1;;;21722:10:0;;;;;21418:723::o;21691:53::-;21769:5;21754:12;21810:78;21817:9;;21810:78;;21843:8;;;;:::i;:::-;;-1:-1:-1;21866:10:0;;-1:-1:-1;21874:2:0;21866:10;;:::i;:::-;;;21810:78;;;21898:19;21930:6;21920:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21920:17:0;;21898:39;;21948:154;21955:10;;21948:154;;21982:11;21992:1;21982:11;;:::i;:::-;;-1:-1:-1;22051:10:0;22059:2;22051:5;:10;:::i;:::-;22038:24;;:2;:24;:::i;:::-;22025:39;;22008:6;22015;22008:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;22008:56:0;;;;;;;;-1:-1:-1;22079:11:0;22088:2;22079:11;;:::i;:::-;;;21948:154;;45347:315;45504:28;45514:4;45520:2;45524:7;45504:9;:28::i;:::-;45551:48;45574:4;45580:2;45584:7;45593:5;45551:22;:48::i;:::-;45543:111;;;;-1:-1:-1;;;45543:111:0;;;;;;;:::i;60395:1607::-;60493:11;;60453:13;;60519:8;60515:23;;-1:-1:-1;;60529:9:0;;;;;;;;;-1:-1:-1;60529:9:0;;;60395:1607;-1:-1:-1;60395:1607:0:o;60515:23::-;60590:18;60628:1;60617:7;:3;60623:1;60617:7;:::i;:::-;60616:13;;;;:::i;:::-;60611:19;;:1;:19;:::i;:::-;60590:40;-1:-1:-1;60688:19:0;60720:15;60590:40;60733:2;60720:15;:::i;:::-;60710:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60710:26:0;;60688:48;;60749:18;60770:5;;;;;;;;;;;;;;;;;60749:26;;60839:1;60832:5;60828:13;60884:2;60876:6;60872:15;60935:1;60903:777;60958:3;60955:1;60952:10;60903:777;;;61013:1;61056:12;;;;;61050:19;61151:4;61139:2;61135:14;;;;;61117:40;;61111:47;61260:2;61256:14;;;61252:25;;61238:40;;61232:47;61389:1;61385:13;;;61381:24;;61367:39;;61361:46;61509:16;;;;61495:31;;61489:38;61187:1;61183:11;;;61281:4;61228:58;;;61219:68;61312:11;;61357:57;;;61348:67;;;;61440:11;;61485:49;;61476:59;61564:3;61560:13;61593:22;;61663:1;61648:17;;;;61006:9;60903:777;;;60907:44;61712:1;61707:3;61703:11;61733:1;61728:84;;;;61831:1;61826:82;;;;61696:212;;61728:84;-1:-1:-1;;;;;61761:17:0;;61754:43;61728:84;;61826:82;-1:-1:-1;;;;;61859:17:0;;61852:41;61696:212;-1:-1:-1;;;61924:26:0;;;61931:6;60395:1607;-1:-1:-1;;;;60395:1607:0:o;13629:1034::-;13706:17;13732:4;-1:-1:-1;;;;;13732:20:0;;13753:14;13769:4;13786:8;12459:1;13775:43;;;;;;;;33882:25:1;;;33938:2;33923:18;;33916:34;33870:2;33855:18;;33708:248;13775:43:0;;;;;;;;;;;;;13732:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;14054:15:0;14137:16;;;:6;:16;;;;;;;;;3916:51;;;;;34192:25:1;;;34233:18;;;34226:34;;;14130:4:0;34276:18:1;;;34269:60;34345:18;;;;34338:34;;;3916:51:0;;;;;;;;;;34164:19:1;;;;3916:51:0;;;3906:62;;;;;;;;;14591:16;;;;;;;:20;;14610:1;14591:20;:::i;:::-;14572:16;;;;:6;:16;;;;;:39;14625:32;14579:8;14649:7;4486:41;;;;;;;12133:19:1;;;;12168:12;;;12161:28;;;;4486:41:0;;;;;;;;;12205:12:1;;;;4486:41:0;;4476:52;;;;;;4366:168;2266:701;2349:7;2392:4;2349:7;2407:523;2431:5;:12;2427:1;:16;2407:523;;;2465:20;2488:5;2494:1;2488:8;;;;;;;;:::i;:::-;;;;;;;2465:31;;2531:12;2515;:28;2511:408;;2668:44;;;;;;12133:19:1;;;12168:12;;;12161:28;;;12205:12;;2668:44:0;;;;;;;;;;;;2658:55;;;;;;2643:70;;2511:408;;;2858:44;;;;;;12133:19:1;;;12168:12;;;12161:28;;;12205:12;;2858:44:0;;;;;;;;;;;;2848:55;;;;;;2833:70;;2511:408;-1:-1:-1;2445:3:0;;;;:::i;:::-;;;;2407:523;;;-1:-1:-1;2947:12:0;2266:701;-1:-1:-1;;;2266:701:0:o;86333:734::-;86395:4;86410:14;86492:1;86467:8;86476:12;86467:22;;;;;;;;:::i;:::-;;;;;;;;;:26;86463:595;;;-1:-1:-1;86517:12:0;;86333:734;-1:-1:-1;86333:734:0:o;86463:595::-;86574:12;86590:1;86574:17;86571:74;;;-1:-1:-1;86624:5:0;86571:74;86662:17;86659:69;;-1:-1:-1;86711:4:0;86659:69;86758:4;86745:17;;;;86742:126;;;86783:14;;;;:::i;:::-;;;;86742:126;;;86838:14;;;;:::i;:::-;;;;86742:126;86911:1;86886:8;86895:12;86886:22;;;;;;;;:::i;:::-;;;;;;;;;:26;86882:165;;;-1:-1:-1;86942:12:0;;86333:734;-1:-1:-1;86333:734:0:o;86882:165::-;87002:29;87018:12;87002:15;:29::i;:::-;86995:36;86333:734;-1:-1:-1;;;86333:734:0:o;86882:165::-;86401:666;86333:734;;;:::o;47296:321::-;47426:18;47432:2;47436:7;47426:5;:18::i;:::-;47477:54;47508:1;47512:2;47516:7;47525:5;47477:22;:54::i;:::-;47455:154;;;;-1:-1:-1;;;47455:154:0;;;;;;;:::i;55576:589::-;-1:-1:-1;;;;;55782:18:0;;55778:187;;55817:40;55849:7;56992:10;:17;;56965:24;;;;:15;:24;;;;;:44;;;57020:24;;;;;;;;;;;;56888:164;55817:40;55778:187;;;55887:2;-1:-1:-1;;;;;55879:10:0;:4;-1:-1:-1;;;;;55879:10:0;;55875:90;;55906:47;55939:4;55945:7;55906:32;:47::i;:::-;-1:-1:-1;;;;;55979:16:0;;55975:183;;56012:45;56049:7;56012:36;:45::i;55975:183::-;56085:4;-1:-1:-1;;;;;56079:10:0;:2;-1:-1:-1;;;;;56079:10:0;;56075:83;;56106:40;56134:2;56138:7;56106:27;:40::i;50696:803::-;50851:4;-1:-1:-1;;;;;50872:13:0;;31219:20;31267:8;50868:624;;50908:72;;-1:-1:-1;;;50908:72:0;;-1:-1:-1;;;;;50908:36:0;;;;;:72;;23801:10;;50959:4;;50965:7;;50974:5;;50908:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50908:72:0;;;;;;;;-1:-1:-1;;50908:72:0;;;;;;;;;;;;:::i;:::-;;;50904:533;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51154:13:0;;51150:272;;51197:60;;-1:-1:-1;;;51197:60:0;;;;;;;:::i;51150:272::-;51372:6;51366:13;51357:6;51353:2;51349:15;51342:38;50904:533;-1:-1:-1;;;;;;51031:55:0;-1:-1:-1;;;51031:55:0;;-1:-1:-1;51024:62:0;;50868:624;-1:-1:-1;51476:4:0;50696:803;;;;;;:::o;47953:382::-;-1:-1:-1;;;;;48033:16:0;;48025:61;;;;-1:-1:-1;;;48025:61:0;;43427:2:1;48025:61:0;;;43409:21:1;;;43446:18;;;43439:30;43505:34;43485:18;;;43478:62;43557:18;;48025:61:0;43225:356:1;48025:61:0;48106:16;48114:7;48106;:16::i;:::-;48105:17;48097:58;;;;-1:-1:-1;;;48097:58:0;;37493:2:1;48097:58:0;;;37475:21:1;37532:2;37512:18;;;37505:30;37571;37551:18;;;37544:58;37619:18;;48097:58:0;37291:352:1;48097:58:0;48168:45;48197:1;48201:2;48205:7;48168:20;:45::i;:::-;-1:-1:-1;;;;;48226:13:0;;;;;;:9;:13;;;;;:18;;48243:1;;48226:13;:18;;48243:1;;48226:18;:::i;:::-;;;;-1:-1:-1;;48255:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48255:21:0;-1:-1:-1;;;;;48255:21:0;;;;;;;;48294:33;;48255:16;;;48294:33;;48255:16;;48294:33;47953:382;;:::o;57679:988::-;57945:22;57995:1;57970:22;57987:4;57970:16;:22::i;:::-;:26;;;;:::i;:::-;58007:18;58028:26;;;:17;:26;;;;;;57945:51;;-1:-1:-1;58161:28:0;;;58157:328;;-1:-1:-1;;;;;58228:18:0;;58206:19;58228:18;;;:12;:18;;;;;;;;:34;;;;;;;;;58279:30;;;;;;:44;;;58396:30;;:17;:30;;;;;:43;;;58157:328;-1:-1:-1;58581:26:0;;;;:17;:26;;;;;;;;58574:33;;;-1:-1:-1;;;;;58625:18:0;;;;;:12;:18;;;;;:34;;;;;;;58618:41;57679:988::o;58962:1079::-;59240:10;:17;59215:22;;59240:21;;59260:1;;59240:21;:::i;:::-;59272:18;59293:24;;;:15;:24;;;;;;59666:10;:26;;59215:46;;-1:-1:-1;59293:24:0;;59215:46;;59666:26;;;;;;:::i;:::-;;;;;;;;;59644:48;;59730:11;59705:10;59716;59705:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;59810:28;;;:15;:28;;;;;;;:41;;;59982:24;;;;;59975:31;60017:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59033:1008;;;58962:1079;:::o;56466:221::-;56551:14;56568:20;56585:2;56568:16;:20::i;:::-;-1:-1:-1;;;;;56599:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;56644:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;56466:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:673::-;479:5;532:3;525:4;517:6;513:17;509:27;499:55;;550:1;547;540:12;499:55;586:6;573:20;612:4;636:60;652:43;692:2;652:43;:::i;:::-;636:60;:::i;:::-;718:3;742:2;737:3;730:15;770:2;765:3;761:12;754:19;;805:2;797:6;793:15;857:3;852:2;846;843:1;839:10;831:6;827:23;823:32;820:41;817:61;;;874:1;871;864:12;817:61;896:1;906:163;920:2;917:1;914:9;906:163;;;977:17;;965:30;;1015:12;;;;1047;;;;938:1;931:9;906:163;;;-1:-1:-1;1087:5:1;;425:673;-1:-1:-1;;;;;;;425:673:1:o;1103:247::-;1162:6;1215:2;1203:9;1194:7;1190:23;1186:32;1183:52;;;1231:1;1228;1221:12;1183:52;1270:9;1257:23;1289:31;1314:5;1289:31;:::i;1355:251::-;1425:6;1478:2;1466:9;1457:7;1453:23;1449:32;1446:52;;;1494:1;1491;1484:12;1446:52;1526:9;1520:16;1545:31;1570:5;1545:31;:::i;1611:388::-;1679:6;1687;1740:2;1728:9;1719:7;1715:23;1711:32;1708:52;;;1756:1;1753;1746:12;1708:52;1795:9;1782:23;1814:31;1839:5;1814:31;:::i;:::-;1864:5;-1:-1:-1;1921:2:1;1906:18;;1893:32;1934:33;1893:32;1934:33;:::i;:::-;1986:7;1976:17;;;1611:388;;;;;:::o;2004:456::-;2081:6;2089;2097;2150:2;2138:9;2129:7;2125:23;2121:32;2118:52;;;2166:1;2163;2156:12;2118:52;2205:9;2192:23;2224:31;2249:5;2224:31;:::i;:::-;2274:5;-1:-1:-1;2331:2:1;2316:18;;2303:32;2344:33;2303:32;2344:33;:::i;:::-;2004:456;;2396:7;;-1:-1:-1;;;2450:2:1;2435:18;;;;2422:32;;2004:456::o;2465:794::-;2560:6;2568;2576;2584;2637:3;2625:9;2616:7;2612:23;2608:33;2605:53;;;2654:1;2651;2644:12;2605:53;2693:9;2680:23;2712:31;2737:5;2712:31;:::i;:::-;2762:5;-1:-1:-1;2819:2:1;2804:18;;2791:32;2832:33;2791:32;2832:33;:::i;:::-;2884:7;-1:-1:-1;2938:2:1;2923:18;;2910:32;;-1:-1:-1;2993:2:1;2978:18;;2965:32;3020:18;3009:30;;3006:50;;;3052:1;3049;3042:12;3006:50;3075:22;;3128:4;3120:13;;3116:27;-1:-1:-1;3106:55:1;;3157:1;3154;3147:12;3106:55;3180:73;3245:7;3240:2;3227:16;3222:2;3218;3214:11;3180:73;:::i;:::-;3170:83;;;2465:794;;;;;;;:::o;3264:382::-;3329:6;3337;3390:2;3378:9;3369:7;3365:23;3361:32;3358:52;;;3406:1;3403;3396:12;3358:52;3445:9;3432:23;3464:31;3489:5;3464:31;:::i;:::-;3514:5;-1:-1:-1;3571:2:1;3556:18;;3543:32;3584:30;3543:32;3584:30;:::i;3651:315::-;3719:6;3727;3780:2;3768:9;3759:7;3755:23;3751:32;3748:52;;;3796:1;3793;3786:12;3748:52;3835:9;3822:23;3854:31;3879:5;3854:31;:::i;:::-;3904:5;3956:2;3941:18;;;;3928:32;;-1:-1:-1;;;3651:315:1:o;3971:348::-;4055:6;4108:2;4096:9;4087:7;4083:23;4079:32;4076:52;;;4124:1;4121;4114:12;4076:52;4164:9;4151:23;4197:18;4189:6;4186:30;4183:50;;;4229:1;4226;4219:12;4183:50;4252:61;4305:7;4296:6;4285:9;4281:22;4252:61;:::i;4324:416::-;4417:6;4425;4478:2;4466:9;4457:7;4453:23;4449:32;4446:52;;;4494:1;4491;4484:12;4446:52;4534:9;4521:23;4567:18;4559:6;4556:30;4553:50;;;4599:1;4596;4589:12;4553:50;4622:61;4675:7;4666:6;4655:9;4651:22;4622:61;:::i;:::-;4612:71;4730:2;4715:18;;;;4702:32;;-1:-1:-1;;;;4324:416:1:o;4745:1217::-;4872:6;4880;4888;4941:2;4929:9;4920:7;4916:23;4912:32;4909:52;;;4957:1;4954;4947:12;4909:52;4997:9;4984:23;5026:18;5067:2;5059:6;5056:14;5053:34;;;5083:1;5080;5073:12;5053:34;5106:61;5159:7;5150:6;5139:9;5135:22;5106:61;:::i;:::-;5096:71;;5186:2;5176:12;;5235:2;5224:9;5220:18;5207:32;5197:42;;5292:2;5281:9;5277:18;5264:32;5321:2;5311:8;5308:16;5305:36;;;5337:1;5334;5327:12;5305:36;5360:24;;;-1:-1:-1;5415:4:1;5407:13;;5403:27;-1:-1:-1;5393:55:1;;5444:1;5441;5434:12;5393:55;5480:2;5467:16;5503:60;5519:43;5559:2;5519:43;:::i;5503:60::-;5585:3;5609:2;5604:3;5597:15;5637:2;5632:3;5628:12;5621:19;;5668:2;5664;5660:11;5716:7;5711:2;5705;5702:1;5698:10;5694:2;5690:19;5686:28;5683:41;5680:61;;;5737:1;5734;5727:12;5680:61;5759:1;5750:10;;5769:163;5783:2;5780:1;5777:9;5769:163;;;5840:17;;5828:30;;5801:1;5794:9;;;;;5878:12;;;;5910;;5769:163;;;5773:3;5951:5;5941:15;;;;;;;4745:1217;;;;;:::o;5967:892::-;6062:6;6093:2;6136;6124:9;6115:7;6111:23;6107:32;6104:52;;;6152:1;6149;6142:12;6104:52;6185:9;6179:16;6218:18;6210:6;6207:30;6204:50;;;6250:1;6247;6240:12;6204:50;6273:22;;6326:4;6318:13;;6314:27;-1:-1:-1;6304:55:1;;6355:1;6352;6345:12;6304:55;6384:2;6378:9;6407:60;6423:43;6463:2;6423:43;:::i;6407:60::-;6489:3;6513:2;6508:3;6501:15;6541:2;6536:3;6532:12;6525:19;;6572:2;6568;6564:11;6620:7;6615:2;6609;6606:1;6602:10;6598:2;6594:19;6590:28;6587:41;6584:61;;;6641:1;6638;6631:12;6584:61;6663:1;6654:10;;6673:156;6687:2;6684:1;6681:9;6673:156;;;6744:10;;6732:23;;6705:1;6698:9;;;;;6775:12;;;;6807;;6673:156;;;-1:-1:-1;6848:5:1;5967:892;-1:-1:-1;;;;;;;5967:892:1:o;6864:245::-;6931:6;6984:2;6972:9;6963:7;6959:23;6955:32;6952:52;;;7000:1;6997;6990:12;6952:52;7032:9;7026:16;7051:28;7073:5;7051:28;:::i;7114:248::-;7182:6;7190;7243:2;7231:9;7222:7;7218:23;7214:32;7211:52;;;7259:1;7256;7249:12;7211:52;-1:-1:-1;;7282:23:1;;;7352:2;7337:18;;;7324:32;;-1:-1:-1;7114:248:1:o;7367:245::-;7425:6;7478:2;7466:9;7457:7;7453:23;7449:32;7446:52;;;7494:1;7491;7484:12;7446:52;7533:9;7520:23;7552:30;7576:5;7552:30;:::i;7617:249::-;7686:6;7739:2;7727:9;7718:7;7714:23;7710:32;7707:52;;;7755:1;7752;7745:12;7707:52;7787:9;7781:16;7806:30;7830:5;7806:30;:::i;7871:450::-;7940:6;7993:2;7981:9;7972:7;7968:23;7964:32;7961:52;;;8009:1;8006;7999:12;7961:52;8049:9;8036:23;8082:18;8074:6;8071:30;8068:50;;;8114:1;8111;8104:12;8068:50;8137:22;;8190:4;8182:13;;8178:27;-1:-1:-1;8168:55:1;;8219:1;8216;8209:12;8168:55;8242:73;8307:7;8302:2;8289:16;8284:2;8280;8276:11;8242:73;:::i;8326:180::-;8385:6;8438:2;8426:9;8417:7;8413:23;8409:32;8406:52;;;8454:1;8451;8444:12;8406:52;-1:-1:-1;8477:23:1;;8326:180;-1:-1:-1;8326:180:1:o;8511:184::-;8581:6;8634:2;8622:9;8613:7;8609:23;8605:32;8602:52;;;8650:1;8647;8640:12;8602:52;-1:-1:-1;8673:16:1;;8511:184;-1:-1:-1;8511:184:1:o;8953:257::-;8994:3;9032:5;9026:12;9059:6;9054:3;9047:19;9075:63;9131:6;9124:4;9119:3;9115:14;9108:4;9101:5;9097:16;9075:63;:::i;:::-;9192:2;9171:15;-1:-1:-1;;9167:29:1;9158:39;;;;9199:4;9154:50;;8953:257;-1:-1:-1;;8953:257:1:o;9215:185::-;9257:3;9295:5;9289:12;9310:52;9355:6;9350:3;9343:4;9336:5;9332:16;9310:52;:::i;:::-;9378:16;;;;;9215:185;-1:-1:-1;;9215:185:1:o;9405:973::-;9490:12;;9455:3;;9545:1;9565:18;;;;9618;;;;9645:61;;9699:4;9691:6;9687:17;9677:27;;9645:61;9725:2;9773;9765:6;9762:14;9742:18;9739:38;9736:161;;;9819:10;9814:3;9810:20;9807:1;9800:31;9854:4;9851:1;9844:15;9882:4;9879:1;9872:15;9736:161;9913:18;9940:104;;;;10058:1;10053:319;;;;9906:466;;9940:104;-1:-1:-1;;9973:24:1;;9961:37;;10018:16;;;;-1:-1:-1;9940:104:1;;10053:319;50516:1;50509:14;;;50553:4;50540:18;;10147:1;10161:165;10175:6;10172:1;10169:13;10161:165;;;10253:14;;10240:11;;;10233:35;10296:16;;;;10190:10;;10161:165;;;10165:3;;10355:6;10350:3;10346:16;10339:23;;9906:466;;;;;;;9405:973;;;;:::o;12480:276::-;12611:3;12649:6;12643:13;12665:53;12711:6;12706:3;12699:4;12691:6;12687:17;12665:53;:::i;:::-;12734:16;;;;;12480:276;-1:-1:-1;;12480:276:1:o;12761:470::-;12940:3;12978:6;12972:13;12994:53;13040:6;13035:3;13028:4;13020:6;13016:17;12994:53;:::i;:::-;13110:13;;13069:16;;;;13132:57;13110:13;13069:16;13166:4;13154:17;;13132:57;:::i;:::-;13205:20;;12761:470;-1:-1:-1;;;;12761:470:1:o;13236:1449::-;13655:3;13693:6;13687:13;13719:4;13732:51;13776:6;13771:3;13766:2;13758:6;13754:15;13732:51;:::i;:::-;13846:13;;13805:16;;;;13868:55;13846:13;13805:16;13890:15;;;13868:55;:::i;:::-;13990:13;;13945:20;;;14012:55;13990:13;13945:20;14034:15;;;14012:55;:::i;:::-;14134:13;;14089:20;;;14156:55;14134:13;14089:20;14178:15;;;14156:55;:::i;:::-;14278:13;;14233:20;;;14300:55;14278:13;14233:20;14322:15;;;14300:55;:::i;:::-;14422:13;;14377:20;;;14444:55;14422:13;14377:20;14466:15;;;14444:55;:::i;:::-;14566:13;;14521:20;;;14588:55;14566:13;14521:20;14610:15;;;14588:55;:::i;:::-;14659:20;;;;;13236:1449;-1:-1:-1;;;;;;;;;;13236:1449:1:o;14690:1438::-;15369:3;15407:6;15401:13;15423:53;15469:6;15464:3;15457:4;15449:6;15445:17;15423:53;:::i;:::-;15507:6;15502:3;15498:16;15485:29;;-1:-1:-1;;;15559:2:1;15552:5;15545:17;15593:6;15587:13;15609:65;15665:8;15661:1;15654:5;15650:13;15643:4;15635:6;15631:17;15609:65;:::i;:::-;15737:1;15693:20;;15729:10;;;15722:22;;;15769:13;;15791:62;15769:13;15840:1;15832:10;;15825:4;15813:17;;15791:62;:::i;:::-;15913:1;15872:17;;15905:10;;;15898:22;;;15945:13;;15967:62;15945:13;16016:1;16008:10;;16001:4;15989:17;;15967:62;:::i;:::-;16089:1;16048:17;;16081:10;;;16074:22;16120:1;16112:10;;14690:1438;-1:-1:-1;;;;;;14690:1438:1:o;16133:1610::-;16860:3;16898:6;16892:13;16914:53;16960:6;16955:3;16948:4;16940:6;16936:17;16914:53;:::i;:::-;16998:6;16993:3;16989:16;16976:29;;-1:-1:-1;;;17050:2:1;17043:5;17036:17;17084:6;17078:13;17100:65;17156:8;17152:1;17145:5;17141:13;17134:4;17126:6;17122:17;17100:65;:::i;:::-;17228:1;17184:20;;17220:10;;;17213:22;;;17260:13;;17282:62;17260:13;17331:1;17323:10;;17316:4;17304:17;;17282:62;:::i;:::-;17404:1;17363:17;;17396:10;;;17389:22;;;17436:13;;17458:62;17436:13;17507:1;17499:10;;17492:4;17480:17;;17458:62;:::i;:::-;17580:1;17539:17;;17572:10;;;17565:22;17612:13;;17634:62;17612:13;17683:1;17675:10;;17668:4;17656:17;;17634:62;:::i;:::-;17716:17;17735:1;17712:25;;16133:1610;-1:-1:-1;;;;;;;16133:1610:1:o;17748:2401::-;-1:-1:-1;;;19141:17:1;;-1:-1:-1;;;19183:1:1;19174:11;;19167:69;-1:-1:-1;19255:47:1;19298:2;19289:12;;19281:6;19255:47;:::i;:::-;-1:-1:-1;;;19348:2:1;19344;19337:14;19380:6;19374:13;19396:60;19449:6;19445:1;19441:2;19437:10;19430:4;19422:6;19418:17;19396:60;:::i;:::-;-1:-1:-1;;;19514:1:1;19475:15;;;;19506:10;;;19499:26;19550:13;;19572:62;19550:13;19621:1;19613:10;;19606:4;19594:17;;19572:62;:::i;:::-;-1:-1:-1;;;19694:1:1;19653:17;;;;19686:10;;;19679:34;-1:-1:-1;;;19737:2:1;19729:11;;19722:63;19804:46;19846:2;19838:11;;19830:6;19804:46;:::i;:::-;19794:56;;19870:2;19866;19859:14;;19904:6;19898:13;19920:62;19973:8;19969:1;19965:2;19961:10;19954:4;19946:6;19942:17;19920:62;:::i;:::-;19998:145;20028:114;20058:83;20084:56;20137:1;20126:8;20122:2;20118:17;20114:25;-1:-1:-1;;;10448:19:1;;10492:1;10483:11;;10383:117;20084:56;20076:6;20058:83;:::i;:::-;-1:-1:-1;;;11138:25:1;;11188:1;11179:11;;11073:123;20028:114;-1:-1:-1;;;11266:16:1;;11307:1;11298:11;;11201:114;19998:145;19991:152;17748:2401;-1:-1:-1;;;;;;;;;;17748:2401:1:o;20154:1409::-;-1:-1:-1;;;20957:16:1;;21002:66;20998:1;20989:11;;20982:87;-1:-1:-1;;;21094:2:1;21085:12;;21078:54;21155:13;;-1:-1:-1;;21177:62:1;21155:13;21227:2;21218:12;;21211:4;21199:17;;21177:62;:::i;:::-;-1:-1:-1;;;21298:2:1;21258:16;;;21290:11;;;21283:25;21333:13;;21355:63;21333:13;21404:2;21396:11;;21389:4;21377:17;;21355:63;:::i;:::-;-1:-1:-1;;;21478:2:1;21437:17;;;;21470:11;;;21463:33;-1:-1:-1;;;21520:2:1;21512:11;;21505:25;21554:2;21546:11;;20154:1409;-1:-1:-1;;;;20154:1409:1:o;21568:2698::-;-1:-1:-1;;;23218:3:1;23211:16;23256:66;23252:1;23247:3;23243:11;23236:87;23193:3;23352:6;23346:13;23368:62;23423:6;23418:2;23413:3;23409:12;23402:4;23394:6;23390:17;23368:62;:::i;:::-;-1:-1:-1;;;23489:2:1;23449:16;;;23481:11;;;23474:32;23531:13;;23553:63;23531:13;23602:2;23594:11;;23587:4;23575:17;;23553:63;:::i;:::-;-1:-1:-1;;;23676:2:1;23635:17;;;;23668:11;;;23661:37;-1:-1:-1;;;23722:2:1;23714:11;;23707:53;23779:46;23821:2;23813:11;;23805:6;23779:46;:::i;:::-;23769:56;;23856:6;23850:13;23872:54;23917:8;23913:2;23906:4;23898:6;23894:17;23872:54;:::i;:::-;23942:318;23972:287;24002:256;24027:230;24053:203;24083:172;24109:145;24139:114;24173:79;24203:48;24241:8;24237:2;24233:17;-1:-1:-1;;;11385:37:1;;11447:1;11438:11;;11320:135;24203:48;-1:-1:-1;;;10975:59:1;;11059:2;11050:12;;10910:158;24173:79;24165:6;24139:114;:::i;:::-;-1:-1:-1;;;11684:20:1;;11729:1;11720:11;;11619:118;24109:145;24101:6;24083:172;:::i;:::-;-1:-1:-1;;;10448:19:1;;10492:1;10483:11;;10383:117;24053:203;24045:6;24027:230;:::i;:::-;-1:-1:-1;;;10565:27:1;;10617:1;10608:11;;10505:120;24002:256;10707:66;10695:79;;10804:66;10799:2;10790:12;;10783:88;10896:2;10887:12;;10630:275;23972:287;-1:-1:-1;;;11525:55:1;;11605:2;11596:12;;11460:154;23942:318;23935:325;21568:2698;-1:-1:-1;;;;;;;;;;;21568:2698:1:o;24271:1078::-;-1:-1:-1;;;24925:16:1;;24970:66;24966:1;24957:11;;24950:87;-1:-1:-1;;;25062:2:1;25053:12;;25046:54;25123:13;;-1:-1:-1;;25145:60:1;25123:13;25193:2;25184:12;;25179:2;25167:15;;25145:60;:::i;:::-;-1:-1:-1;;;25264:2:1;25224:16;;;;25256:11;;;25249:33;-1:-1:-1;;;;25306:2:1;25298:11;;25291:25;25340:2;25332:11;;24271:1078;-1:-1:-1;24271:1078:1:o;25354:2072::-;26543:3;-1:-1:-1;;;26595:2:1;26590:3;26583:15;26627:66;26623:1;26618:3;26614:11;26607:87;26733:22;26728:3;26724:32;26719:2;26714:3;26710:12;26703:54;26786:6;26780:13;26802:60;26855:6;26850:2;26845:3;26841:12;26836:2;26828:6;26824:15;26802:60;:::i;:::-;-1:-1:-1;;;26952:2:1;26881:16;;;26944:11;;;26937:23;;;-1:-1:-1;;;26984:2:1;26976:11;;26969:25;27018:2;27010:11;;27003:23;;;;27055:66;27050:2;27042:11;;27035:87;-1:-1:-1;;;27146:2:1;27138:11;;27131:55;27211:13;;;27233:61;27211:13;27280:2;27272:11;;27267:2;27255:15;;27233:61;:::i;:::-;27313:17;;27354:2;27346:11;;27339:23;;;;-1:-1:-1;;;27416:2:1;27408:11;;11266:16;11298:11;;;27378:42;11201:114;27431:2076;28620:3;-1:-1:-1;;;28672:2:1;28667:3;28660:15;28704:66;28700:1;28695:3;28691:11;28684:87;28799:22;28794:3;28790:32;28852:2;28847;28842:3;28838:12;28831:24;28884:6;28878:13;28900:62;28955:6;28950:2;28945:3;28941:12;28934:4;28926:6;28922:17;28900:62;:::i;:::-;-1:-1:-1;;;29052:2:1;28981:16;;;29044:11;;;29037:23;;;-1:-1:-1;;;29107:2:1;29099:11;;29092:23;;;29139:2;29131:11;;29124:23;;;;-1:-1:-1;;;29171:2:1;29163:11;;29156:76;29256:2;29248:11;;29241:23;;;29289:13;;;29311:63;29289:13;29360:2;29352:11;;29345:4;29333:17;;29311:63;:::i;:::-;29434:2;29393:17;;;;29426:11;;;29419:23;29466:2;29458:11;;29451:23;;;;-1:-1:-1;29498:2:1;29490:11;;27431:2076;-1:-1:-1;;;;27431:2076:1:o;29512:1409::-;-1:-1:-1;;;30315:16:1;;30360:66;30356:1;30347:11;;30340:87;-1:-1:-1;;;30452:2:1;30443:12;;30436:54;30513:13;;-1:-1:-1;;30535:62:1;30513:13;30585:2;30576:12;;30569:4;30557:17;;30535:62;:::i;30926:448::-;31188:31;31183:3;31176:44;31158:3;31249:6;31243:13;31265:62;31320:6;31315:2;31310:3;31306:12;31299:4;31291:6;31287:17;31265:62;:::i;:::-;31347:16;;;;31365:2;31343:25;;30926:448;-1:-1:-1;;30926:448:1:o;31379:525::-;31618:19;;;31693:3;31671:16;;;;-1:-1:-1;;;;;;31667:43:1;31662:2;31653:12;;31646:65;31749:2;31745:15;;;;-1:-1:-1;;;;;;31741:53:1;31736:2;31727:12;;31720:75;31820:2;31811:12;;31804:28;31857:2;31848:12;;31841:28;31894:3;31885:13;;31379:525::o;32117:488::-;-1:-1:-1;;;;;32386:15:1;;;32368:34;;32438:15;;32433:2;32418:18;;32411:43;32485:2;32470:18;;32463:34;;;32533:3;32528:2;32513:18;;32506:31;;;32311:4;;32554:45;;32579:19;;32571:6;32554:45;:::i;:::-;32546:53;32117:488;-1:-1:-1;;;;;;32117:488:1:o;32610:385::-;32842:1;32838;32833:3;32829:11;32825:19;32817:6;32813:32;32802:9;32795:51;32882:6;32877:2;32866:9;32862:18;32855:34;32925:2;32920;32909:9;32905:18;32898:30;32776:4;32945:44;32985:2;32974:9;32970:18;32962:6;32945:44;:::i;34383:219::-;34532:2;34521:9;34514:21;34495:4;34552:44;34592:2;34581:9;34577:18;34569:6;34552:44;:::i;36121:414::-;36323:2;36305:21;;;36362:2;36342:18;;;36335:30;36401:34;36396:2;36381:18;;36374:62;-1:-1:-1;;;36467:2:1;36452:18;;36445:48;36525:3;36510:19;;36121:414::o;39519:349::-;39721:2;39703:21;;;39760:2;39740:18;;;39733:30;39799:27;39794:2;39779:18;;39772:55;39859:2;39844:18;;39519:349::o;40298:341::-;40500:2;40482:21;;;40539:2;40519:18;;;40512:30;-1:-1:-1;;;40573:2:1;40558:18;;40551:47;40630:2;40615:18;;40298:341::o;41815:354::-;42017:2;41999:21;;;42056:2;42036:18;;;42029:30;42095:32;42090:2;42075:18;;42068:60;42160:2;42145:18;;41815:354::o;44712:356::-;44914:2;44896:21;;;44933:18;;;44926:30;44992:34;44987:2;44972:18;;44965:62;45059:2;45044:18;;44712:356::o;46954:413::-;47156:2;47138:21;;;47195:2;47175:18;;;47168:30;47234:34;47229:2;47214:18;;47207:62;-1:-1:-1;;;47300:2:1;47285:18;;47278:47;47357:3;47342:19;;46954:413::o;48127:355::-;48329:2;48311:21;;;48368:2;48348:18;;;48341:30;48407:33;48402:2;48387:18;;48380:61;48473:2;48458:18;;48127:355::o;49196:339::-;49398:2;49380:21;;;49437:2;49417:18;;;49410:30;-1:-1:-1;;;49471:2:1;49456:18;;49449:45;49526:2;49511:18;;49196:339::o;49975:275::-;50046:2;50040:9;50111:2;50092:13;;-1:-1:-1;;50088:27:1;50076:40;;50146:18;50131:34;;50167:22;;;50128:62;50125:88;;;50193:18;;:::i;:::-;50229:2;50222:22;49975:275;;-1:-1:-1;49975:275:1:o;50255:183::-;50315:4;50348:18;50340:6;50337:30;50334:56;;;50370:18;;:::i;:::-;-1:-1:-1;50415:1:1;50411:14;50427:4;50407:25;;50255:183::o;50569:128::-;50609:3;50640:1;50636:6;50633:1;50630:13;50627:39;;;50646:18;;:::i;:::-;-1:-1:-1;50682:9:1;;50569:128::o;50702:228::-;50741:3;50769:10;50806:2;50803:1;50799:10;50836:2;50833:1;50829:10;50867:3;50863:2;50859:12;50854:3;50851:21;50848:47;;;50875:18;;:::i;50935:120::-;50975:1;51001;50991:35;;51006:18;;:::i;:::-;-1:-1:-1;51040:9:1;;50935:120::o;51060:168::-;51100:7;51166:1;51162;51158:6;51154:14;51151:1;51148:21;51143:1;51136:9;51129:17;51125:45;51122:71;;;51173:18;;:::i;:::-;-1:-1:-1;51213:9:1;;51060:168::o;51233:125::-;51273:4;51301:1;51298;51295:8;51292:34;;;51306:18;;:::i;:::-;-1:-1:-1;51343:9:1;;51233:125::o;51363:258::-;51435:1;51445:113;51459:6;51456:1;51453:13;51445:113;;;51535:11;;;51529:18;51516:11;;;51509:39;51481:2;51474:10;51445:113;;;51576:6;51573:1;51570:13;51567:48;;;-1:-1:-1;;51611:1:1;51593:16;;51586:27;51363:258::o;51626:136::-;51665:3;51693:5;51683:39;;51702:18;;:::i;:::-;-1:-1:-1;;;51738:18:1;;51626:136::o;51767:380::-;51846:1;51842:12;;;;51889;;;51910:61;;51964:4;51956:6;51952:17;51942:27;;51910:61;52017:2;52009:6;52006:14;51986:18;51983:38;51980:161;;;52063:10;52058:3;52054:20;52051:1;52044:31;52098:4;52095:1;52088:15;52126:4;52123:1;52116:15;52152:135;52191:3;-1:-1:-1;;52212:17:1;;52209:43;;;52232:18;;:::i;:::-;-1:-1:-1;52279:1:1;52268:13;;52152:135::o;52292:112::-;52324:1;52350;52340:35;;52355:18;;:::i;:::-;-1:-1:-1;52389:9:1;;52292:112::o;52409:183::-;52440:1;52466:10;52503:2;52500:1;52496:10;52525:3;52515:37;;52532:18;;:::i;:::-;52570:10;;52566:20;;;;;52409:183;-1:-1:-1;;52409:183:1:o;52597:127::-;52658:10;52653:3;52649:20;52646:1;52639:31;52689:4;52686:1;52679:15;52713:4;52710:1;52703:15;52729:127;52790:10;52785:3;52781:20;52778:1;52771:31;52821:4;52818:1;52811:15;52845:4;52842:1;52835:15;52861:127;52922:10;52917:3;52913:20;52910:1;52903:31;52953:4;52950:1;52943:15;52977:4;52974:1;52967:15;52993:127;53054:10;53049:3;53045:20;53042:1;53035:31;53085:4;53082:1;53075:15;53109:4;53106:1;53099:15;53125:127;53186:10;53181:3;53177:20;53174:1;53167:31;53217:4;53214:1;53207:15;53241:4;53238:1;53231:15;53257:131;-1:-1:-1;;;;;53332:31:1;;53322:42;;53312:70;;53378:1;53375;53368:12;53393:118;53479:5;53472:13;53465:21;53458:5;53455:32;53445:60;;53501:1;53498;53491:12;53516:131;-1:-1:-1;;;;;;53590:32:1;;53580:43;;53570:71;;53637:1;53634;53627:12

Swarm Source

ipfs://f6bb635a5ad82bb127badb714437154da0b6abfada8bb20def5922f9593526bc
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.