ETH Price: $3,898.65 (+0.36%)

Contract

0x588Ca95d76c6a7ab121746bd209F2994B7Ba5F10
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Buy152471222022-07-31 0:50:18868 days ago1659228618IN
0x588Ca95d...4B7Ba5F10
0.01416 ETH0.000076523
Close Shop134037092021-10-12 12:45:041160 days ago1634042704IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0016293566.65128074
Confirm Shipping130605932021-08-20 6:34:591213 days ago1629441299IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0017224644
Ship To Me130432642021-08-17 14:29:331216 days ago1629210573IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0034005760.11584642
Confirm Shipping129139612021-07-28 10:41:541236 days ago1627468914IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0030308133
Ship To Me127355142021-06-30 13:08:431264 days ago1625058523IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0011941814
Confirm Shipping126769532021-06-21 9:57:261273 days ago1624269446IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0029389732
Assign Purchased...126717872021-06-20 14:46:311274 days ago1624200391IN
0x588Ca95d...4B7Ba5F10
0 ETH0.0192469815.00000145
Buy126068972021-06-10 12:54:461284 days ago1623329686IN
0x588Ca95d...4B7Ba5F10
0.03243353 ETH0.000375578.4
Buy125937182021-06-08 11:55:001286 days ago1623153300IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.005425312
Buy125871012021-06-07 11:17:191287 days ago1623064639IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0076742711.50000067
Buy125870902021-06-07 11:14:511287 days ago1623064491IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0072418111
Buy125870662021-06-07 11:09:521287 days ago1623064192IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0072697911
Buy125792722021-06-06 6:23:051288 days ago1622960585IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.005616
Buy125771942021-06-05 22:44:481288 days ago1622933088IN
0x588Ca95d...4B7Ba5F10
0.00447573 ETH0.0023099711
Buy125760592021-06-05 18:32:511288 days ago1622917971IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0059238312
Buy125760082021-06-05 18:21:161288 days ago1622917276IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0071339114
Buy125760072021-06-05 18:21:051288 days ago1622917265IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0059238312
Buy125759552021-06-05 18:11:561288 days ago1622916716IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0074593915.4
Buy125757782021-06-05 17:30:591288 days ago1622914259IN
0x588Ca95d...4B7Ba5F10
0.03243353 ETH0.0193878114
Buy125740192021-06-05 10:43:191289 days ago1622889799IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0082489912.26078717
Buy125740112021-06-05 10:41:551289 days ago1622889715IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0082005212.26078717
Buy125740112021-06-05 10:41:551289 days ago1622889715IN
0x588Ca95d...4B7Ba5F10
0.0064867 ETH0.0078871812.26078717
Buy125733162021-06-05 8:08:361289 days ago1622880516IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0069566416
Buy125730832021-06-05 7:16:291289 days ago1622877389IN
0x588Ca95d...4B7Ba5F10
0.00324335 ETH0.0063264614
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
125937182021-06-08 11:55:001286 days ago1623153300
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125871012021-06-07 11:17:191287 days ago1623064639
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125870902021-06-07 11:14:511287 days ago1623064491
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125870662021-06-07 11:09:521287 days ago1623064192
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125792722021-06-06 6:23:051288 days ago1622960585
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125771942021-06-05 22:44:481288 days ago1622933088
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125760592021-06-05 18:32:511288 days ago1622917971
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125760082021-06-05 18:21:161288 days ago1622917276
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125760072021-06-05 18:21:051288 days ago1622917265
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125759552021-06-05 18:11:561288 days ago1622916716
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125757782021-06-05 17:30:591288 days ago1622914259
0x588Ca95d...4B7Ba5F10
0.03243353 ETH
125740192021-06-05 10:43:191289 days ago1622889799
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125740112021-06-05 10:41:551289 days ago1622889715
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125740112021-06-05 10:41:551289 days ago1622889715
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125733162021-06-05 8:08:361289 days ago1622880516
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125730832021-06-05 7:16:291289 days ago1622877389
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125730832021-06-05 7:16:291289 days ago1622877389
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125702942021-06-04 20:48:451289 days ago1622839725
0x588Ca95d...4B7Ba5F10
0.00457217 ETH
125702942021-06-04 20:48:451289 days ago1622839725
0x588Ca95d...4B7Ba5F10
0.03243353 ETH
125691012021-06-04 16:27:521289 days ago1622824072
0x588Ca95d...4B7Ba5F10
0.00324335 ETH
125675902021-06-04 11:08:361290 days ago1622804916
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125675322021-06-04 10:54:561290 days ago1622804096
0x588Ca95d...4B7Ba5F10
0.0064867 ETH
125445772021-05-31 21:31:271293 days ago1622496687
0x588Ca95d...4B7Ba5F10
0.0370057 ETH
125444612021-05-31 21:10:231293 days ago1622495423
0x588Ca95d...4B7Ba5F10
0.0370057 ETH
125423402021-05-31 13:17:411294 days ago1622467061
0x588Ca95d...4B7Ba5F10
0.00370057 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CS2OnChainShop

Compiler Version
v0.6.10+commit.00c0fcaf

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-06-22
*/

/*
 * Crypto stamp 2 On-Chain Shop
 * Ability to purchase pseudo-random digital-physical collectible postage stamps
 * and to redeem Crypto stamp 2 pre-sale vouchers in a similar manner
 *
 * Developed by Capacity Blockchain Solutions GmbH <capacity.at>
 * for Österreichische Post AG <post.at>
 */


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

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

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

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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

pragma solidity ^0.6.2;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transfered 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`, `to` cannot be zero.
     * - `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`, `to` cannot be zero.
     * - `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`, `to` cannot be zero.
      * - `tokenId` token must exist and be owned by `from`.
      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
      *
      * Emits a {Transfer} event.
      */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

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

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: contracts/ENSReverseRegistrarI.sol

/*
 * Interfaces for ENS Reverse Registrar
 * See https://github.com/ensdomains/ens/blob/master/contracts/ReverseRegistrar.sol for full impl
 * Also see https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/ENSReverseRegister.sol
 *
 * Use this as follows (registryAddress is the address of the ENS registry to use):
 * -----
 * // This hex value is caclulated by namehash('addr.reverse')
 * bytes32 public constant ENS_ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
 * function registerReverseENS(address registryAddress, string memory calldata) external {
 *     require(registryAddress != address(0), "need a valid registry");
 *     address reverseRegistrarAddress = ENSRegistryOwnerI(registryAddress).owner(ENS_ADDR_REVERSE_NODE)
 *     require(reverseRegistrarAddress != address(0), "need a valid reverse registrar");
 *     ENSReverseRegistrarI(reverseRegistrarAddress).setName(name);
 * }
 * -----
 * or
 * -----
 * function registerReverseENS(address reverseRegistrarAddress, string memory calldata) external {
 *    require(reverseRegistrarAddress != address(0), "need a valid reverse registrar");
 *     ENSReverseRegistrarI(reverseRegistrarAddress).setName(name);
 * }
 * -----
 * ENS deployments can be found at https://docs.ens.domains/ens-deployments
 * E.g. Etherscan can be used to look up that owner on those contracts.
 * namehash.hash("addr.reverse") == "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2"
 * Ropsten: ens.owner(namehash.hash("addr.reverse")) == "0x6F628b68b30Dc3c17f345c9dbBb1E483c2b7aE5c"
 * Mainnet: ens.owner(namehash.hash("addr.reverse")) == "0x084b1c3C81545d370f3634392De611CaaBFf8148"
 */
pragma solidity ^0.6.0;

interface ENSRegistryOwnerI {
    function owner(bytes32 node) external view returns (address);
}

interface ENSReverseRegistrarI {
    function setName(string calldata name) external returns (bytes32 node);
}

// File: contracts/OracleRequest.sol

/*
Interface for requests to the rate oracle (for EUR/ETH)
Copy this to projects that need to access the oracle.
See rate-oracle project for implementation.
*/
pragma solidity ^0.6.0;


abstract contract OracleRequest {

    uint256 public EUR_WEI; //number of wei per EUR

    uint256 public lastUpdate; //timestamp of when the last update occurred

    function ETH_EUR() public view virtual returns (uint256); //number of EUR per ETH (rounded down!)

    function ETH_EURCENT() public view virtual returns (uint256); //number of EUR cent per ETH (rounded down!)

}

// File: contracts/CS2PropertiesI.sol

/*
Interface for CS2 properties.
*/
pragma solidity ^0.6.0;

interface CS2PropertiesI {

    enum AssetType {
        Honeybadger,
        Llama,
        Panda,
        Doge
    }

    enum Colors {
        Black,
        Green,
        Blue,
        Yellow,
        Red
    }

    function getType(uint256 tokenId) external view returns (AssetType);
    function getColor(uint256 tokenId) external view returns (Colors);

}

// File: contracts/OZ_ERC1155/IERC1155.sol

pragma solidity ^0.6.0;


/**
    @title ERC-1155 Multi Token Standard basic interface
    @dev See https://eips.ethereum.org/EIPS/eip-1155
 */
abstract contract IERC1155 is IERC165 {
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    function balanceOf(address account, uint256 id) public view virtual returns (uint256);

    function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual returns (uint256[] memory);

    function setApprovalForAll(address operator, bool approved) external virtual;

    function isApprovedForAll(address account, address operator) external view virtual returns (bool);

    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external virtual;

    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external virtual;
}

// File: contracts/CS2PresaleRedeemI.sol

/*
Interface for CS2 on-chain presale for usage with redeemer (OCS) contract.
*/
pragma solidity ^0.6.0;


abstract contract CS2PresaleRedeemI is IERC1155 {
    enum AssetType {
        Honeybadger,
        Llama,
        Panda,
        Doge
    }

    // Redeem assets of a multiple types/animals at once.
    // This burns them in this contract, but should be called by a contract that assigns/creates the final assets in turn.
    function redeemBatch(address owner, AssetType[] calldata _type, uint256[] calldata _count) external virtual;
}

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

pragma solidity ^0.6.2;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

// File: contracts/ERC721ExistsI.sol

pragma solidity ^0.6.0;


/**
 * @dev ERC721 compliant contract with an exists() function.
 */
abstract contract ERC721ExistsI is IERC721 {

    // Returns whether the specified token exists
    function exists(uint256 tokenId) public view virtual returns (bool);

}

// File: contracts/CS2OCSBaseI.sol

pragma solidity ^0.6.0;



/**
 * @dev ERC721 compliant contract with an exists() function.
 */
abstract contract CS2OCSBaseI is ERC721ExistsI, IERC721Enumerable {

    // Issue a crypto stamp with a merkle proof.
    function createWithProof(bytes32 tokenData, bytes32[] memory merkleProof) public virtual returns (uint256);

}

// File: contracts/CS2OnChainShop.sol

/*
Implements an on-chain shop for Crypto stamp Edition 2
*/
pragma solidity ^0.6.0;









contract CS2OnChainShop {
    using SafeMath for uint256;

    CS2OCSBaseI internal CS2;
    CS2PresaleRedeemI internal CS2Presale;
    OracleRequest internal oracle;

    address payable public beneficiary;
    address public shippingControl;
    address public tokenAssignmentControl;

    uint256 public basePriceEurCent;
    uint256 public priceTargetTimestamp;
    uint256[4] public lastSaleTimestamp; // Every AssetType has their own sale/price tracking.
    uint256[4] public lastSalePriceEurCent;
    uint256[4] public lastSlotPriceEurCent;
    uint256 public slotSeconds = 600;
    uint256 public increaseFactorMicro; // 2500 for 0.25% (0.0025 * 1M)

    struct SoldInfo {
        address recipient;
        uint256 blocknumber;
        uint256 tokenId;
        bool presale;
        CS2PropertiesI.AssetType aType;
    }

    SoldInfo[] public soldSequence;
    uint256 public lastAssignedSequence;
    uint256 public lastRetrievedSequence;

    address[8] public tokenPools; // Pools for every AssetType as well as "normal" OCS and presale.
    uint256[8] public startIds;
    uint256[8] public tokenPoolSize;
    uint256[8] public unassignedInPool;
    uint256[2500][8] public tokenIdPools; // Max 2500 IDs per pool.

    bool internal _isOpen = true;

    enum ShippingStatus{
        Initial,
        Sold,
        ShippingSubmitted,
        ShippingConfirmed
    }

    mapping(uint256 => ShippingStatus) public deliveryStatus;

    event BasePriceChanged(uint256 previousBasePriceEurCent, uint256 newBasePriceEurCent);
    event PriceTargetTimeChanged(uint256 previousPriceTargetTimestamp, uint256 newPriceTargetTimestamp);
    event IncreaseFactorChanged(uint256 previousIncreaseFactorMicro, uint256 newIncreaseFactorMicro);
    event OracleChanged(address indexed previousOracle, address indexed newOracle);
    event BeneficiaryTransferred(address indexed previousBeneficiary, address indexed newBeneficiary);
    event TokenAssignmentControlTransferred(address indexed previousTokenAssignmentControl, address indexed newTokenAssignmentControl);
    event ShippingControlTransferred(address indexed previousShippingControl, address indexed newShippingControl);
    event ShopOpened();
    event ShopClosed();
    event AssetSold(address indexed buyer, address recipient, bool indexed presale, CS2PropertiesI.AssetType indexed aType, uint256 sequenceNumber, uint256 priceWei);
    event AssetAssigned(address indexed recipient, uint256 indexed tokenId, uint256 sequenceNumber);
    event AssignedAssetRetrieved(uint256 indexed tokenId, address indexed recipient);
    event ShippingSubmitted(address indexed owner, uint256[] tokenIds, string deliveryInfo);
    event ShippingFailed(address indexed owner, uint256 indexed tokenId, string reason);
    event ShippingConfirmed(address indexed owner, uint256 indexed tokenId);
    // ERC721 event - never emitted in this contract but helpful for running our tests.
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    // ERC1155 event - never emitted in this contract but helpful for running our tests.
    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    constructor(OracleRequest _oracle,
        address _CS2Address,
        address _CS2PresaleAddress,
        uint256 _basePriceEurCent,
        uint256 _priceTargetTimestamp,
        uint256 _increaseFactorMicro,
        address payable _beneficiary,
        address _shippingControl,
        address _tokenAssignmentControl,
        uint256 _tokenPoolSize,
        address[] memory _tokenPools,
        uint256[] memory _startIds)
    public
    {
        oracle = _oracle;
        require(address(oracle) != address(0x0), "You need to provide an actual Oracle contract.");
        CS2 = CS2OCSBaseI(_CS2Address);
        require(address(CS2) != address(0x0), "You need to provide an actual Cryptostamp 2 contract.");
        CS2Presale = CS2PresaleRedeemI(_CS2PresaleAddress);
        require(address(CS2Presale) != address(0x0), "You need to provide an actual Cryptostamp 2 Presale contract.");
        beneficiary = _beneficiary;
        require(address(beneficiary) != address(0x0), "You need to provide an actual beneficiary address.");
        shippingControl = _shippingControl;
        require(address(shippingControl) != address(0x0), "You need to provide an actual shippingControl address.");
        tokenAssignmentControl = _tokenAssignmentControl;
        require(address(tokenAssignmentControl) != address(0x0), "You need to provide an actual tokenAssignmentControl address.");
        basePriceEurCent = _basePriceEurCent;
        require(basePriceEurCent > 0, "You need to provide a non-zero base price.");
        priceTargetTimestamp = _priceTargetTimestamp;
        require(priceTargetTimestamp > now, "You need to provide a price target time in the future.");
        increaseFactorMicro = _increaseFactorMicro;
        uint256 poolnum = tokenPools.length;
        require(_tokenPools.length == poolnum, "Need correct amount of token pool addresses.");
        require(_startIds.length == poolnum, "Need correct amount of token pool start IDs.");
        for (uint256 i = 0; i < poolnum; i++) {
            tokenPools[i] = _tokenPools[i];
            startIds[i] = _startIds[i];
            tokenPoolSize[i] = _tokenPoolSize;
        }
    }

    modifier onlyBeneficiary() {
        require(msg.sender == beneficiary, "Only the current benefinicary can call this function.");
        _;
    }

    modifier onlyShippingControl() {
        require(msg.sender == shippingControl, "shippingControl key required for this function.");
        _;
    }

    modifier onlyTokenAssignmentControl() {
        require(msg.sender == tokenAssignmentControl, "tokenAssignmentControl key required for this function.");
        _;
    }

    modifier requireOpen() {
        require(isOpen() == true, "This call only works when the shop is open.");
        _;
    }

    /*** Enable adjusting variables after deployment ***/

    function setBasePrice(uint256 _newBasePriceEurCent)
    public
    onlyBeneficiary
    {
        require(_newBasePriceEurCent > 0, "You need to provide a non-zero price.");
        emit BasePriceChanged(basePriceEurCent, _newBasePriceEurCent);
        basePriceEurCent = _newBasePriceEurCent;
    }

    function setPriceTargetTime(uint256 _newPriceTargetTimestamp)
    public
    onlyBeneficiary
    {
        require(_newPriceTargetTimestamp > now, "You need to provide a price target time in the future.");
        emit PriceTargetTimeChanged(priceTargetTimestamp, _newPriceTargetTimestamp);
        priceTargetTimestamp = _newPriceTargetTimestamp;
    }

    function setIncreaseFactor(uint256 _newIncreaseFactorMicro)
    public
    onlyBeneficiary
    {
        emit IncreaseFactorChanged(increaseFactorMicro, _newIncreaseFactorMicro);
        increaseFactorMicro = _newIncreaseFactorMicro;
    }

    function setOracle(OracleRequest _newOracle)
    public
    onlyBeneficiary
    {
        require(address(_newOracle) != address(0x0), "You need to provide an actual Oracle contract.");
        emit OracleChanged(address(oracle), address(_newOracle));
        oracle = _newOracle;
    }

    function transferBeneficiary(address payable _newBeneficiary)
    public
    onlyBeneficiary
    {
        require(_newBeneficiary != address(0), "beneficiary cannot be the zero address.");
        emit BeneficiaryTransferred(beneficiary, _newBeneficiary);
        beneficiary = _newBeneficiary;
    }

    function transferTokenAssignmentControl(address _newTokenAssignmentControl)
    public
    onlyTokenAssignmentControl
    {
        require(_newTokenAssignmentControl != address(0), "tokenAssignmentControl cannot be the zero address.");
        emit TokenAssignmentControlTransferred(tokenAssignmentControl, _newTokenAssignmentControl);
        tokenAssignmentControl = _newTokenAssignmentControl;
    }

    function transferShippingControl(address _newShippingControl)
    public
    onlyShippingControl
    {
        require(_newShippingControl != address(0), "shippingControl cannot be the zero address.");
        emit ShippingControlTransferred(shippingControl, _newShippingControl);
        shippingControl = _newShippingControl;
    }

    function openShop()
    public
    onlyBeneficiary
    {
        _isOpen = true;
        emit ShopOpened();
    }

    function closeShop()
    public
    onlyBeneficiary
    {
        _isOpen = false;
        emit ShopClosed();
    }

    /*** Actual on-chain shop functionality ***/

    // Return true if OCS is currently open for purchases.
    // This can have additional conditions to just the variable, e.g. actually having items to sell.
    function isOpen()
    public view
    returns (bool)
    {
        return _isOpen;
    }

    // Calculate dynamic asset price in EUR cent.
    function priceEurCent(CS2PropertiesI.AssetType _type)
    public view
    returns (uint256)
    {
        return priceEurCentDynamic(true, _type);
    }

    // Calculate fully dynamic asset price in EUR cent, without any capping for a time period.
    // If freezeSaleSlot is true, the price from the last sale stays frozen during its slot.
    // If that parameter if false, any sale will increase the price, even within the slot (used internally).
    function priceEurCentDynamic(bool freezeSaleSlot, CS2PropertiesI.AssetType _type)
    public view
    returns (uint256)
    {
        uint256 nowSlot = getTimeSlot(now);
        uint256 typeNum = uint256(_type);
        if (lastSaleTimestamp[typeNum] == 0 || nowSlot == 0) {
            // The first stamp as well as any after the target time are sold for the base price.
            return basePriceEurCent;
        }
        uint256 lastSaleSlot = getTimeSlot(lastSaleTimestamp[typeNum]);
        if (freezeSaleSlot) {
            // Keep price static within a time slot of slotSeconds (default 10 minutes).
            if (nowSlot == lastSaleSlot) {
                return lastSlotPriceEurCent[typeNum];
            }
        }
        // The price is increased by a fixed percentage compared to the last sale,
        // and decreased linearly towards the target timestamp and the base price.
        // NOTE that due to the precision in EUR cent, we never end up with fractal EUR cent values.
        uint256 priceIncrease = lastSalePriceEurCent[typeNum] * increaseFactorMicro / 1_000_000;
        // Decrease: current overpricing multiplied by how much of the time between last sale and target has already passed.
        // NOTE: *current* overpricing needs to take the increase into account first (otherwise it's overpricing of last sale)
        // NOTE: getTimeSlot already reports the number of slots remaining to the target.
        uint256 priceDecrease = (lastSalePriceEurCent[typeNum] + priceIncrease - basePriceEurCent) * (lastSaleSlot - nowSlot) / lastSaleSlot;
        return lastSalePriceEurCent[typeNum] + priceIncrease - priceDecrease;
    }

    // Get number of time slot. Slot numbers decrease towards the target timestamp, 0 is anything after that target.
    function getTimeSlot(uint256 _timestamp)
    public view
    returns (uint256)
    {
        if (_timestamp >= priceTargetTimestamp) {
            return 0;
        }
        return (priceTargetTimestamp - _timestamp) / slotSeconds + 1;
    }

    // Calculate current asset price in wei.
    // Note: Price in EUR cent is available from basePriceEurCent().
    function priceWei(CS2PropertiesI.AssetType _type)
    public view
    returns (uint256)
    {
        return priceEurCent(_type).mul(oracle.EUR_WEI()).div(100);
    }

    // Get the index of the pool for presale or normal OCS assets of the given type.
    function getPoolIndex(bool _isPresale, CS2PropertiesI.AssetType _type)
    public pure
    returns (uint256)
    {
        return (_isPresale ? 4 : 0) + uint256(_type);
    }

    // Returns the amount of assets of that type still available for sale.
    function availableForSale(bool _presale, CS2PropertiesI.AssetType _type)
    public view
    returns (uint256)
    {
        uint256 poolIndex = getPoolIndex(_presale, _type);
        return tokenPoolSize[poolIndex].sub(unassignedInPool[poolIndex]);
    }

    // Returns true if the asset of the given type is sold out.
    function isSoldOut(bool _presale, CS2PropertiesI.AssetType _type)
    public view
    returns (bool)
    {
        return availableForSale(_presale, _type) == 0;
    }

    // Buy assets of a single type/animal.
    // The number of assets as well as the recipient are explicitly given.
    // This will fail when the full amount cannot be provided or the payment is too little for that amount.
    // The recipient does not need to match the buyer, so the assets can be sent elsewhere (e.g. into a collection).
    // tokenData and merkleProofs are are collection of mint proofs to optimistically try for retrieving assigned assets.
    function buy(CS2PropertiesI.AssetType _type, uint256 _amount, address payable _recipient, bytes32[] memory tokenData, bytes32[] memory merkleProofsAggregated)
    public payable
    requireOpen
    {
        if (tokenData.length > 0) {
            mintAssetsWithAggregatedProofs(tokenData, merkleProofsAggregated);
        }
        bool isPresale = false;
        require(_amount <= availableForSale(isPresale, _type), "Not enough assets available to buy that amount.");
        uint256 curPriceWei = priceWei(_type);
        uint256 payAmount = _amount.mul(curPriceWei);
        require(msg.value >= payAmount, "You need to send enough currency to buy the specified amount.");
        uint256 typeNum = uint256(_type);
        if (lastSaleTimestamp[typeNum] == 0 || getTimeSlot(now) != getTimeSlot(lastSaleTimestamp[typeNum])) {
            // This is only called when priceEurCent() actually returns something different than the last slot price.
            lastSlotPriceEurCent[typeNum] = priceEurCent(_type);
        }
        // Transfer the actual payment amount to the beneficiary.
        // NOTE: We know this is no contract that causes re-entrancy as we own it.
        (bool sendSuccess, /*bytes memory data*/) = beneficiary.call{value: payAmount}("");
        if (!sendSuccess) { revert("Error in sending payment!"); }
        for (uint256 i = 0; i < _amount; i++) {
            // Assign a sequence number and store block and owner for it.
            soldSequence.push(SoldInfo(_recipient, block.number, 0, isPresale, _type));
            emit AssetSold(msg.sender, _recipient, isPresale, _type, soldSequence.length, curPriceWei);
            // Adjust lastSale parameters for every sale so per-sale increase is calculated correctly.
            lastSalePriceEurCent[typeNum] = priceEurCentDynamic(false, _type);
            lastSaleTimestamp[typeNum] = now;
        }
        uint256 poolIndex = getPoolIndex(isPresale, _type);
        unassignedInPool[poolIndex] = unassignedInPool[poolIndex].add(_amount);
        // Assign a max of one asset/token more than we purchased.
        assignPurchasedAssets(_amount + 1);
        // Try retrieving a max of one asset/token more than we purchased.
        retrieveAssignedAssets(_amount + 1);
        // Send back change money. Do this last as msg.sender could cause re-entrancy.
        if (msg.value > payAmount) {
            (bool returnSuccess, /*bytes memory data*/) = msg.sender.call{value: msg.value.sub(payAmount)}("");
            if (!returnSuccess) { revert("Error in returning change!"); }
        }
    }

    // Redeem presale vouchers for assets of a single type/animal.
    // The number of assets as well as the recipient are explicitly given.
    // This will fail when the full amount cannot be provided or the buyer has too few vouchers.
    // The recipient does not need to match the buyer, so the assets can be sent elsewhere (e.g. into a collection).
    // tokenData and merkleProofs are are collection of mint proofs to optimistically try for retrieving assigned assets.
    function redeemVoucher(CS2PropertiesI.AssetType _type, uint256 _amount, address payable _recipient, bytes32[] memory tokenData, bytes32[] memory merkleProofsAggregated)
    public
    requireOpen
    {
        if (tokenData.length > 0) {
            mintAssetsWithAggregatedProofs(tokenData, merkleProofsAggregated);
        }
        bool isPresale = true;
        require(_amount <= availableForSale(isPresale, _type), "Not enough assets available to buy that amount.");
        uint256 typeNum = uint256(_type);
        require(CS2Presale.balanceOf(msg.sender, typeNum) >= _amount, "You need to own enough presale vouchers to redeem the specified amount.");
        // Redeem the vouchers.
        CS2PresaleRedeemI.AssetType[] memory redeemTypes = new CS2PresaleRedeemI.AssetType[](1);
        uint256[] memory redeemAmounts = new uint256[](1);
        redeemTypes[0] = CS2PresaleRedeemI.AssetType(typeNum);
        redeemAmounts[0] = _amount;
        CS2Presale.redeemBatch(msg.sender, redeemTypes, redeemAmounts);
        //CS2Presale.redeemBatch(msg.sender, [_type], [_amount]);
        for (uint256 i = 0; i < _amount; i++) {
            // Assign a sequence number and store block and owner for it.
            soldSequence.push(SoldInfo(_recipient, block.number, 0, isPresale, _type));
            emit AssetSold(msg.sender, _recipient, isPresale, _type, soldSequence.length, 0);
        }
        uint256 poolIndex = getPoolIndex(isPresale, _type);
        unassignedInPool[poolIndex] = unassignedInPool[poolIndex].add(_amount);
        // Assign a max of one asset/token more than we purchased.
        assignPurchasedAssets(_amount + 1);
        // Try retrieving a max of one asset/token more than we purchased.
        retrieveAssignedAssets(_amount + 1);
    }

    // Get total amount of not-yet-assigned assets
    function getUnassignedAssetCount()
    public view
    returns (uint256)
    {
        return soldSequence.length - lastAssignedSequence;
    }

    // Get total amount of not-yet-retrieved assets
    function getUnretrievedAssetCount()
    public view
    returns (uint256)
    {
        return soldSequence.length - lastRetrievedSequence;
    }

    // Get total amount of sold assets
    function getSoldCount()
    public view
    returns (uint256)
    {
        return soldSequence.length;
    }

    // Get the token ID for any sold asset with the given sequence number.
    // As we do not know the block hash of the current block in Solidity, this can be given from the outside.
    // NOTE that when you hand in a wrong block hash, you will get wrong results!
    function getSoldTokenId(uint256 _sequenceNumber, bytes32 _currentBlockHash)
    public view
    returns (uint256)
    {
        if (_sequenceNumber <= lastAssignedSequence) {
            // We can return the ID directly from the soldSequence.
            uint256 seqIdx = _sequenceNumber.sub(1);
            return soldSequence[seqIdx].tokenId;
        }
        // For unassigned assets, get pool and slot and then a token ID from that.
        uint256 poolIndex;
        uint256 slotIndex;
        if (_sequenceNumber == lastAssignedSequence.add(1)) {
            (poolIndex, slotIndex) = _getNextUnassignedPoolSlot(_currentBlockHash);
        }
        else {
            (poolIndex, slotIndex) = _getUnassignedPoolSlotDeep(_sequenceNumber, _currentBlockHash);
        }
        return _getTokenIdForPoolSlot(poolIndex, slotIndex);
    }

    // Get the actual token ID for a pool slot, including the dance of resolving "0" IDs.
    function _getTokenIdForPoolSlot(uint256 _poolIndex, uint256 _slotIndex)
    internal view
    returns (uint256)
    {
        uint256 tokenId = tokenIdPools[_poolIndex][_slotIndex];
        if (tokenId == 0) {
            // We know we don't have token ID 0 in the pool, so we'll calculate the actual ID.
            tokenId = startIds[_poolIndex].add(_slotIndex);
        }
        return tokenId;
    }

    // Get a slot index for the given sequence index (not sequence number!) and pool size.
    function _getSemiRandomSlotIndex(uint256 seqIdx, uint256 poolSize, bytes32 _currentBlockHash)
    internal view
    returns (uint256)
    {
        // Get block hash. As this only works for the last 256 blocks, fall back to the empty keccak256 hash to keep getting stable results.
        bytes32 bhash;
        if (soldSequence[seqIdx].blocknumber == block.number) {
          require(_currentBlockHash != bytes32(""), "For assets sold in the current block, provide a valid block hash.");
          bhash = _currentBlockHash;
        }
        else if (block.number < 256 || soldSequence[seqIdx].blocknumber >= block.number.sub(256)) {
          bhash = blockhash(soldSequence[seqIdx].blocknumber);
        }
        else {
          bhash = keccak256("");
        }
        return uint256(keccak256(abi.encodePacked(seqIdx, bhash))) % poolSize;
    }

    // Get the pool and slot indexes for the next asset to assign, which is a pretty straight-forward case.
    function _getNextUnassignedPoolSlot(bytes32 _currentBlockHash)
    internal view
    returns (uint256, uint256)
    {
        uint256 seqIdx = lastAssignedSequence; // last + 1 is next seqNo, seqIdx is seqNo - 1
        uint256 poolIndex = getPoolIndex(soldSequence[seqIdx].presale, soldSequence[seqIdx].aType);
        uint256 slotIndex = _getSemiRandomSlotIndex(seqIdx, tokenPoolSize[poolIndex], _currentBlockHash);
        return (poolIndex, slotIndex);
    }

    // Get the pool and slot indexes for any asset that is still to be assigned.
    // This case is rather complicated as it needs to calculate which assets would be removed in sequence before this one.
    function _getUnassignedPoolSlotDeep(uint256 _sequenceNumber, bytes32 _currentBlockHash)
    internal view
    returns (uint256, uint256)
    {
        require(_sequenceNumber > lastAssignedSequence, "The asset was assigned already.");
        require(_sequenceNumber <= soldSequence.length, "Exceeds maximum sequence number.");
        uint256 depth = _sequenceNumber.sub(lastAssignedSequence);
        uint256[] memory poolIndex = new uint256[](depth);
        uint256[] memory slotIndex = new uint256[](depth);
        uint256[] memory slotRedirect = new uint256[](depth);
        uint256[] memory poolSizeReduction = new uint256[](tokenPoolSize.length);
        for (uint256 i = 0; i < depth; i++) {
            uint256 seqIdx = lastAssignedSequence.add(i); // last + 1 is next seqNo, seqIdx is seqNo - 1, then we add i
            poolIndex[i] = getPoolIndex(soldSequence[seqIdx].presale, soldSequence[seqIdx].aType);
            uint256 calcPoolSize = tokenPoolSize[poolIndex[i]].sub(poolSizeReduction[poolIndex[i]]);
            slotIndex[i] = _getSemiRandomSlotIndex(seqIdx, calcPoolSize, _currentBlockHash);
            // Resolve all fitting redirects - this is an O(2) loop!
            for (uint256 fitloop = 0; fitloop < i; fitloop++) {
                for (uint256 j = 0; j < i; j++) {
                    if (poolIndex[i] == poolIndex[j] && slotIndex[i] == slotIndex[j]) {
                        slotIndex[i] = slotRedirect[j];
                    }
                }
            }
            // Instead of actually shuffling the array, do a redirect dance.
            slotRedirect[i] = calcPoolSize.sub(1);
            poolSizeReduction[poolIndex[i]] = poolSizeReduction[poolIndex[i]].add(1);
        }
        return (poolIndex[depth.sub(1)], slotIndex[depth.sub(1)]);
    }

    // Assign _maxCount asset (or less if less are unassigned)
    function assignPurchasedAssets(uint256 _maxCount)
    public
    {
        for (uint256 i = 0; i < _maxCount; i++) {
            if (lastAssignedSequence < soldSequence.length) {
                _assignNextPurchasedAsset(false);
            }
        }
    }

    function assignNextPurchasedAssset()
    public
    {
        _assignNextPurchasedAsset(true);
    }

    function _assignNextPurchasedAsset(bool revertForSameBlock)
    internal
    {
        uint256 nextSequenceNumber = lastAssignedSequence.add(1);
        // Find the stamp to assign and transfer it.
        uint256 seqIdx = nextSequenceNumber.sub(1);
        if (soldSequence[seqIdx].blocknumber < block.number) {
            // Get tokenId in two steps as we need the slot index later.
            (uint256 poolIndex, uint256 slotIndex) = _getNextUnassignedPoolSlot(bytes32(""));
            uint256 tokenId = _getTokenIdForPoolSlot(poolIndex, slotIndex);
            soldSequence[seqIdx].tokenId = tokenId;
            emit AssetAssigned(soldSequence[seqIdx].recipient, tokenId, nextSequenceNumber);
            if (lastRetrievedSequence == lastAssignedSequence && CS2.exists(tokenId)) {
                // If the asset exists and retrieval is caught up, do retrieval right away.
                _retrieveAssignedAsset(seqIdx);
            }
            // Adjust the pool for the transferred asset.
            uint256 lastSlotIndex = tokenPoolSize[poolIndex].sub(1);
            if (slotIndex != lastSlotIndex) {
                // If the removed index is not the last, move the last one to the removed slot.
                uint256 lastValue = tokenIdPools[poolIndex][lastSlotIndex];
                if (lastValue == 0) {
                    // In case we still have a 0 here, set the correct tokenId instead.
                    lastValue = startIds[poolIndex] + lastSlotIndex;
                }
                tokenIdPools[poolIndex][slotIndex] = lastValue;
            }
            tokenPoolSize[poolIndex] = tokenPoolSize[poolIndex].sub(1);
            unassignedInPool[poolIndex] = unassignedInPool[poolIndex].sub(1);
            // Set delivery status for newly sold asset, and update lastAssigned.
            deliveryStatus[tokenId] = ShippingStatus.Sold;
            lastAssignedSequence = nextSequenceNumber;
        }
        else {
            if (revertForSameBlock) {
                revert("Cannot assign assets in the same block.");
            }
        }
    }

    // Retrieve multiple assets with mint proofs, if they match the next ones to retrieve.
    function mintAssetsWithAggregatedProofs(bytes32[] memory tokenData, bytes32[] memory merkleProofsAggregated)
    public
    {
        uint256 count = tokenData.length;
        require(count > 0, "Need actual data and proofs");
        require(merkleProofsAggregated.length % count == 0, "Count of data and proofs need to match");
        uint256 singleProofLength = merkleProofsAggregated.length / count;
        // Try to mint all given proofs.
        for (uint256 i = 0; i < count; i++) {
            uint256 tokenId = uint256(tokenData[i] >> 168); // shift by 20 bytes for address and 1 byte for properties
            if (!CS2.exists(tokenId)) {
                bytes32[] memory merkleProof = new bytes32[](singleProofLength);
                for (uint256 j = 0; j < singleProofLength; j++) {
                    merkleProof[j] = merkleProofsAggregated[singleProofLength.mul(i).add(j)];
                }
                CS2.createWithProof(tokenData[i], merkleProof);
            }
        }
    }

    function retrieveAssignedAssets(uint256 _maxCount)
    public
    {
        for (uint256 i = 0; i < _maxCount; i++) {
            if (lastRetrievedSequence < lastAssignedSequence) {
                uint256 seqIdx = lastRetrievedSequence; // last + 1 is next seqNo, seqIdx is seqNo - 1
                // Only retrieve an asset if the token actually exists.
                if (CS2.exists(soldSequence[seqIdx].tokenId)) {
                    _retrieveAssignedAsset(seqIdx);
                }
            }
        }
    }

    function _retrieveAssignedAsset(uint256 seqIdx)
    internal
    {
        uint256 poolIndex = getPoolIndex(soldSequence[seqIdx].presale, soldSequence[seqIdx].aType);
        require(CS2.ownerOf(soldSequence[seqIdx].tokenId) == tokenPools[poolIndex], "Already transferred out of the pool");
        // NOTE: We know CS2 is no contract that causes re-entrancy as it's our code.
        CS2.safeTransferFrom(tokenPools[poolIndex], soldSequence[seqIdx].recipient, soldSequence[seqIdx].tokenId);
        emit AssignedAssetRetrieved(soldSequence[seqIdx].tokenId, soldSequence[seqIdx].recipient);
        lastRetrievedSequence = seqIdx.add(1); // current SeqNo is SeqIdx + 1
    }

    /*** Handle physical shipping ***/

    // For token owner (after successful purchase): Request shipping.
    // _deliveryInfo is a postal address encrypted with a public key on the client side.
    function shipToMe(string memory _deliveryInfo, uint256[] memory _tokenIds)
    public
    requireOpen
    {
        uint256 count = _tokenIds.length;
        for (uint256 i = 0; i < count; i++) {
            require(CS2.ownerOf(_tokenIds[i]) == msg.sender, "You can only request shipping for your own tokens.");
            require(deliveryStatus[_tokenIds[i]] == ShippingStatus.Sold, "Shipping was already requested for one of these tokens or it was not sold by this shop.");
            deliveryStatus[_tokenIds[i]] = ShippingStatus.ShippingSubmitted;
        }
        emit ShippingSubmitted(msg.sender, _tokenIds, _deliveryInfo);
    }

    // For shipping service: Mark shipping as completed/confirmed.
    function confirmShipping(uint256[] memory _tokenIds)
    public
    onlyShippingControl
    {
        uint256 count = _tokenIds.length;
        for (uint256 i = 0; i < count; i++) {
            deliveryStatus[_tokenIds[i]] = ShippingStatus.ShippingConfirmed;
            emit ShippingConfirmed(CS2.ownerOf(_tokenIds[i]), _tokenIds[i]);
        }
    }

    // For shipping service: Mark shipping as failed/rejected (due to invalid address).
    function rejectShipping(uint256[] memory _tokenIds, string memory _reason)
    public
    onlyShippingControl
    {
        uint256 count = _tokenIds.length;
        for (uint256 i = 0; i < count; i++) {
            deliveryStatus[_tokenIds[i]] = ShippingStatus.Sold;
            emit ShippingFailed(CS2.ownerOf(_tokenIds[i]), _tokenIds[i], _reason);
        }
    }

    /*** Enable reverse ENS registration ***/

    // Call this with the address of the reverse registrar for the respecitve network and the ENS name to register.
    // The reverse registrar can be found as the owner of 'addr.reverse' in the ENS system.
    // For Mainnet, the address needed is 0x9062c0a6dbd6108336bcbe4593a3d1ce05512069
    function registerReverseENS(address _reverseRegistrarAddress, string calldata _name)
    external
    onlyTokenAssignmentControl
    {
        require(_reverseRegistrarAddress != address(0), "need a valid reverse registrar");
        ENSReverseRegistrarI(_reverseRegistrarAddress).setName(_name);
    }

    /*** Make sure currency or NFT doesn't get stranded in this contract ***/

    // If this contract gets a balance in some ERC20 contract after it's finished, then we can rescue it.
    function rescueToken(IERC20 _foreignToken, address _to)
    external
    onlyTokenAssignmentControl
    {
        _foreignToken.transfer(_to, _foreignToken.balanceOf(address(this)));
    }

    // If this contract gets a balance in some ERC721 contract after it's finished, then we can rescue it.
    function approveNFTrescue(IERC721 _foreignNFT, address _to)
    external
    onlyTokenAssignmentControl
    {
        _foreignNFT.setApprovalForAll(_to, true);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract OracleRequest","name":"_oracle","type":"address"},{"internalType":"address","name":"_CS2Address","type":"address"},{"internalType":"address","name":"_CS2PresaleAddress","type":"address"},{"internalType":"uint256","name":"_basePriceEurCent","type":"uint256"},{"internalType":"uint256","name":"_priceTargetTimestamp","type":"uint256"},{"internalType":"uint256","name":"_increaseFactorMicro","type":"uint256"},{"internalType":"address payable","name":"_beneficiary","type":"address"},{"internalType":"address","name":"_shippingControl","type":"address"},{"internalType":"address","name":"_tokenAssignmentControl","type":"address"},{"internalType":"uint256","name":"_tokenPoolSize","type":"uint256"},{"internalType":"address[]","name":"_tokenPools","type":"address[]"},{"internalType":"uint256[]","name":"_startIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sequenceNumber","type":"uint256"}],"name":"AssetAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"bool","name":"presale","type":"bool"},{"indexed":true,"internalType":"enum CS2PropertiesI.AssetType","name":"aType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"sequenceNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceWei","type":"uint256"}],"name":"AssetSold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"AssignedAssetRetrieved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousBasePriceEurCent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBasePriceEurCent","type":"uint256"}],"name":"BasePriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousBeneficiary","type":"address"},{"indexed":true,"internalType":"address","name":"newBeneficiary","type":"address"}],"name":"BeneficiaryTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousIncreaseFactorMicro","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newIncreaseFactorMicro","type":"uint256"}],"name":"IncreaseFactorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOracle","type":"address"},{"indexed":true,"internalType":"address","name":"newOracle","type":"address"}],"name":"OracleChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousPriceTargetTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPriceTargetTimestamp","type":"uint256"}],"name":"PriceTargetTimeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ShippingConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousShippingControl","type":"address"},{"indexed":true,"internalType":"address","name":"newShippingControl","type":"address"}],"name":"ShippingControlTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"ShippingFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":false,"internalType":"string","name":"deliveryInfo","type":"string"}],"name":"ShippingSubmitted","type":"event"},{"anonymous":false,"inputs":[],"name":"ShopClosed","type":"event"},{"anonymous":false,"inputs":[],"name":"ShopOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTokenAssignmentControl","type":"address"},{"indexed":true,"internalType":"address","name":"newTokenAssignmentControl","type":"address"}],"name":"TokenAssignmentControlTransferred","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"inputs":[{"internalType":"contract IERC721","name":"_foreignNFT","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"approveNFTrescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assignNextPurchasedAssset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxCount","type":"uint256"}],"name":"assignPurchasedAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_presale","type":"bool"},{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"availableForSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"basePriceEurCent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_recipient","type":"address"},{"internalType":"bytes32[]","name":"tokenData","type":"bytes32[]"},{"internalType":"bytes32[]","name":"merkleProofsAggregated","type":"bytes32[]"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"closeShop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"confirmShipping","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deliveryStatus","outputs":[{"internalType":"enum CS2OnChainShop.ShippingStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isPresale","type":"bool"},{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"getPoolIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getSoldCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sequenceNumber","type":"uint256"},{"internalType":"bytes32","name":"_currentBlockHash","type":"bytes32"}],"name":"getSoldTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getTimeSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnassignedAssetCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnretrievedAssetCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increaseFactorMicro","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_presale","type":"bool"},{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"isSoldOut","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAssignedSequence","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRetrievedSequence","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastSalePriceEurCent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastSaleTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastSlotPriceEurCent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"tokenData","type":"bytes32[]"},{"internalType":"bytes32[]","name":"merkleProofsAggregated","type":"bytes32[]"}],"name":"mintAssetsWithAggregatedProofs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openShop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"priceEurCent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"freezeSaleSlot","type":"bool"},{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"priceEurCentDynamic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceTargetTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"}],"name":"priceWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum CS2PropertiesI.AssetType","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_recipient","type":"address"},{"internalType":"bytes32[]","name":"tokenData","type":"bytes32[]"},{"internalType":"bytes32[]","name":"merkleProofsAggregated","type":"bytes32[]"}],"name":"redeemVoucher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_reverseRegistrarAddress","type":"address"},{"internalType":"string","name":"_name","type":"string"}],"name":"registerReverseENS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"string","name":"_reason","type":"string"}],"name":"rejectShipping","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_foreignToken","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"rescueToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxCount","type":"uint256"}],"name":"retrieveAssignedAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newBasePriceEurCent","type":"uint256"}],"name":"setBasePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newIncreaseFactorMicro","type":"uint256"}],"name":"setIncreaseFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract OracleRequest","name":"_newOracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPriceTargetTimestamp","type":"uint256"}],"name":"setPriceTargetTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_deliveryInfo","type":"string"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"shipToMe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shippingControl","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"slotSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"soldSequence","outputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"blocknumber","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"presale","type":"bool"},{"internalType":"enum CS2PropertiesI.AssetType","name":"aType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"startIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAssignmentControl","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdPools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenPoolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newBeneficiary","type":"address"}],"name":"transferBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newShippingControl","type":"address"}],"name":"transferShippingControl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTokenAssignmentControl","type":"address"}],"name":"transferTokenAssignmentControl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"unassignedInPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6080604052610258601455614e59805460ff191660011790553480156200002557600080fd5b5060405162004d1e38038062004d1e83398181016040526101808110156200004c57600080fd5b815160208301516040808501516060860151608087015160a088015160c089015160e08a01516101008b01516101208c01516101408d01805199519b9d9a9c989b979a9699959894979396929591948301929184640100000000821115620000b357600080fd5b908301906020820185811115620000c957600080fd5b8251866020820283011164010000000082111715620000e757600080fd5b82525081516020918201928201910280838360005b8381101562000116578181015183820152602001620000fc565b50505050905001604052602001805160405193929190846401000000008211156200014057600080fd5b9083019060208201858111156200015657600080fd5b82518660208202830111640100000000821117156200017457600080fd5b82525081516020918201928201910280838360005b83811015620001a357818101518382015260200162000189565b505050509050016040525050508b600260006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060006001600160a01b0316600260009054906101000a90046001600160a01b03166001600160a01b03161415620002405760405162461bcd60e51b815260040180806020018281038252602e81526020018062004b21602e913960400191505060405180910390fd5b600080546001600160a01b0319166001600160a01b038d81169190911791829055166200029f5760405162461bcd60e51b815260040180806020018281038252603581526020018062004cb76035913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b038c8116919091179182905516620002fe5760405162461bcd60e51b815260040180806020018281038252603d81526020018062004c50603d913960400191505060405180910390fd5b600380546001600160a01b0319166001600160a01b038881169190911791829055166200035d5760405162461bcd60e51b815260040180806020018281038252603281526020018062004cec6032913960400191505060405180910390fd5b600480546001600160a01b0319166001600160a01b03878116919091179182905516620003bc5760405162461bcd60e51b815260040180806020018281038252603681526020018062004b8c6036913960400191505060405180910390fd5b600580546001600160a01b0319166001600160a01b038681169190911791829055166200041b5760405162461bcd60e51b815260040180806020018281038252603d81526020018062004b4f603d913960400191505060405180910390fd5b6006899055886200045e5760405162461bcd60e51b815260040180806020018281038252602a81526020018062004c8d602a913960400191505060405180910390fd5b6007889055428811620004a35760405162461bcd60e51b815260040180806020018281038252603681526020018062004bc26036913960400191505060405180910390fd5b601587905581516008908114620004ec5760405162461bcd60e51b815260040180806020018281038252602c81526020018062004c24602c913960400191505060405180910390fd5b808251146200052d5760405162461bcd60e51b815260040180806020018281038252602c81526020018062004bf8602c913960400191505060405180910390fd5b60005b81811015620005c0578381815181106200054657fe5b6020026020010151601982600881106200055c57fe5b0160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508281815181106200058e57fe5b602002602001015160218260088110620005a457fe5b01558460298260088110620005b557fe5b015560010162000530565b505050505050505050505050505061454380620005de6000396000f3fe6080604052600436106102fe5760003560e01c80637289f98c11610190578063adc34bb2116100dc578063d4f8788d11610095578063de4b32621161006f578063de4b326214610fe5578063f06f44551461100f578063f7de5f7c14611039578063f93ce63a1461117b576102fe565b8063d4f8788d14610dad578063d74b17d514610e5b578063dd48f77414610faa576102fe565b8063adc34bb214610ce1578063b77f9de914610cf6578063ba91966514610d0b578063c13245c114610d35578063c8c2ed5414610d65578063d0763c9514610d7a576102fe565b8063963b079911610149578063a0327ac011610123578063a0327ac014610b42578063a683b7c914610b6c578063a6f5a22b14610b9c578063ac77efb614610bb1576102fe565b8063963b079914610ad9578063979e99c814610b035780639b6dbc8a14610b2d576102fe565b80637289f98c1461095a5780637adbf9731461098457806381b4bd34146109b75780638820e6f5146109e45780638e8fa11f14610a1957806390ffb86414610aa4576102fe565b806338af3eed1161024f5780634f7f15511161020857806363a6344e116101e257806363a6344e146109065780636714494a1461091b5780636738bc6a146109305780636e28f11114610945576102fe565b80634f7f1551146108b257806351cb394c146108dc5780635ed0b0ce146108f1576102fe565b806338af3eed146107ba5780633918021d146107cf57806339c45762146107e45780634707d0001461081957806347535d7b14610854578063477a1a301461087d576102fe565b80631786ba1b116102bc578063322b1cc511610296578063322b1cc51461059557806332ba4cb0146105c25780633317b3191461061057806335f9672314610687576102fe565b80631786ba1b1461040e5780632b11645b146105415780632b85dcc91461056b576102fe565b8062c0f91614610303578063017e97bc1461034957806301ec3d151461035e57806306ff6d5f1461038a57806314946f9c146103b157806314bbe21c146103db575b600080fd5b34801561030f57600080fd5b5061032d6004803603602081101561032657600080fd5b50356111ae565b604080516001600160a01b039092168252519081900360200190f35b34801561035557600080fd5b5061032d6111cb565b34801561036a57600080fd5b506103886004803603602081101561038157600080fd5b50356111da565b005b34801561039657600080fd5b5061039f6112a3565b60408051918252519081900360200190f35b3480156103bd57600080fd5b5061039f600480360360208110156103d457600080fd5b50356112ad565b3480156103e757600080fd5b50610388600480360360208110156103fe57600080fd5b50356001600160a01b03166112c1565b34801561041a57600080fd5b506103886004803603604081101561043157600080fd5b810190602081018135600160201b81111561044b57600080fd5b82018360208201111561045d57600080fd5b803590602001918460018302840111600160201b8311171561047e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104d057600080fd5b8201836020820111156104e257600080fd5b803590602001918460208302840111600160201b8311171561050357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506113ab945050505050565b34801561054d57600080fd5b5061039f6004803603602081101561056457600080fd5b5035611688565b34801561057757600080fd5b5061039f6004803603602081101561058e57600080fd5b5035611695565b3480156105a157600080fd5b5061039f600480360360208110156105b857600080fd5b503560ff166116c3565b3480156105ce57600080fd5b506105ec600480360360208110156105e557600080fd5b503561176e565b604051808260038111156105fc57fe5b60ff16815260200191505060405180910390f35b34801561061c57600080fd5b5061063a6004803603602081101561063357600080fd5b5035611784565b604080516001600160a01b03871681526020810186905290810184905282151560608201526080810182600381111561066f57fe5b60ff1681526020019550505050505060405180910390f35b34801561069357600080fd5b50610388600480360360408110156106aa57600080fd5b810190602081018135600160201b8111156106c457600080fd5b8201836020820111156106d657600080fd5b803590602001918460208302840111600160201b831117156106f757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561074657600080fd5b82018360208201111561075857600080fd5b803590602001918460018302840111600160201b8311171561077957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506117d1945050505050565b3480156107c657600080fd5b5061032d6119cd565b3480156107db57600080fd5b5061039f6119dc565b3480156107f057600080fd5b5061039f6004803603604081101561080757600080fd5b5080351515906020013560ff166119e2565b34801561082557600080fd5b506103886004803603604081101561083c57600080fd5b506001600160a01b0381358116916020013516611a26565b34801561086057600080fd5b50610869611b65565b604080519115158252519081900360200190f35b34801561088957600080fd5b5061039f600480360360408110156108a057600080fd5b5080351515906020013560ff16611b6f565b3480156108be57600080fd5b50610388600480360360208110156108d557600080fd5b5035611c61565b3480156108e857600080fd5b5061039f611cec565b3480156108fd57600080fd5b5061039f611cf2565b34801561091257600080fd5b5061039f611cf8565b34801561092757600080fd5b5061039f611d02565b34801561093c57600080fd5b5061039f611d08565b34801561095157600080fd5b5061039f611d0e565b34801561096657600080fd5b5061039f6004803603602081101561097d57600080fd5b5035611d14565b34801561099057600080fd5b50610388600480360360208110156109a757600080fd5b50356001600160a01b0316611d21565b3480156109c357600080fd5b5061039f600480360360208110156109da57600080fd5b503560ff16611e0b565b3480156109f057600080fd5b5061039f60048036036040811015610a0757600080fd5b5080351515906020013560ff16611e18565b348015610a2557600080fd5b5061038860048036036040811015610a3c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610a6657600080fd5b820183602082011115610a7857600080fd5b803590602001918460018302840111600160201b83111715610a9957600080fd5b509092509050611e40565b348015610ab057600080fd5b5061086960048036036040811015610ac757600080fd5b5080351515906020013560ff16611f89565b348015610ae557600080fd5b5061038860048036036020811015610afc57600080fd5b5035611f9d565b348015610b0f57600080fd5b5061039f60048036036020811015610b2657600080fd5b5035612069565b348015610b3957600080fd5b50610388612076565b348015610b4e57600080fd5b5061039f60048036036020811015610b6557600080fd5b50356120f5565b348015610b7857600080fd5b5061039f60048036036040811015610b8f57600080fd5b5080359060200135612102565b348015610ba857600080fd5b50610388612129565b348015610bbd57600080fd5b5061038860048036036040811015610bd457600080fd5b810190602081018135600160201b811115610bee57600080fd5b820183602082011115610c0057600080fd5b803590602001918460208302840111600160201b83111715610c2157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610c7057600080fd5b820183602082011115610c8257600080fd5b803590602001918460208302840111600160201b83111715610ca357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506121ab945050505050565b348015610ced57600080fd5b5061038861247c565b348015610d0257600080fd5b5061039f612488565b348015610d1757600080fd5b5061038860048036036020811015610d2e57600080fd5b503561248e565b348015610d4157600080fd5b5061039f60048036036040811015610d5857600080fd5b50803590602001356124b7565b348015610d7157600080fd5b5061032d612554565b348015610d8657600080fd5b5061038860048036036020811015610d9d57600080fd5b50356001600160a01b0316612563565b348015610db957600080fd5b5061038860048036036020811015610dd057600080fd5b810190602081018135600160201b811115610dea57600080fd5b820183602082011115610dfc57600080fd5b803590602001918460208302840111600160201b83111715610e1d57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061264d945050505050565b348015610e6757600080fd5b50610388600480360360a0811015610e7e57600080fd5b60ff823516916020810135916001600160a01b036040830135169190810190608081016060820135600160201b811115610eb757600080fd5b820183602082011115610ec957600080fd5b803590602001918460208302840111600160201b83111715610eea57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610f3957600080fd5b820183602082011115610f4b57600080fd5b803590602001918460208302840111600160201b83111715610f6c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506127d9945050505050565b348015610fb657600080fd5b5061038860048036036040811015610fcd57600080fd5b506001600160a01b0381358116916020013516612c78565b348015610ff157600080fd5b506103886004803603602081101561100857600080fd5b5035612d2f565b34801561101b57600080fd5b5061039f6004803603602081101561103257600080fd5b5035612df9565b610388600480360360a081101561104f57600080fd5b60ff823516916020810135916001600160a01b036040830135169190810190608081016060820135600160201b81111561108857600080fd5b82018360208201111561109a57600080fd5b803590602001918460208302840111600160201b831117156110bb57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561110a57600080fd5b82018360208201111561111c57600080fd5b803590602001918460208302840111600160201b8311171561113d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612e06945050505050565b34801561118757600080fd5b506103886004803603602081101561119e57600080fd5b50356001600160a01b0316613283565b601981600881106111bb57fe5b01546001600160a01b0316905081565b6004546001600160a01b031681565b6003546001600160a01b031633146112235760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b4281116112615760405162461bcd60e51b81526004018080602001828103825260368152602001806142926036913960400191505060405180910390fd5b600754604080519182526020820183905280517f18ff519ede7363293f7cd545e18c74b70bce1dc4c144792836b2a29e9c8a1b719281900390910190a1600755565b6018546016540390565b602181600881106112ba57fe5b0154905081565b6003546001600160a01b0316331461130a5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b6001600160a01b03811661134f5760405162461bcd60e51b815260040180806020018281038252602781526020018061415c6027913960400191505060405180910390fd5b6003546040516001600160a01b038084169216907f57005c5083fa0952870a7906715a2f6f9ef2d01b4a423e4b3ce59c6129b1a76390600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6113b3611b65565b15156001146113f35760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b805160005b8181101561159957600054835133916001600160a01b031690636352211e9086908590811061142357fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561145f57600080fd5b505afa158015611473573d6000803e3d6000fd5b505050506040513d602081101561148957600080fd5b50516001600160a01b0316146114d05760405162461bcd60e51b81526004018080602001828103825260328152602001806143296032913960400191505060405180910390fd5b6001614e5a60008584815181106114e357fe5b60209081029190910181015182528101919091526040016000205460ff16600381111561150c57fe5b146115485760405162461bcd60e51b81526004018080602001828103825260578152602001806144b76057913960600191505060405180910390fd5b6002614e5a600085848151811061155b57fe5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083600381111561158c57fe5b02179055506001016113f8565b50336001600160a01b03167fd84b3824b00dc38c63428fb6ae9dc02b61b6ddb8845aaacf34b8950a81e687128385604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561160b5781810151838201526020016115f3565b50505050905001838103825284818151815260200191508051906020019080838360005b8381101561164757818101518382015260200161162f565b50505050905090810190601f1680156116745780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2505050565b600c81600481106112ba57fe5b600060075482106116a8575060006116be565b6014548260075403816116b757fe5b0460010190505b919050565b6000611768606461175c600260009054906101000a90046001600160a01b03166001600160a01b03166354a4adc26040518163ffffffff1660e01b815260040160206040518083038186803b15801561171b57600080fd5b505afa15801561172f573d6000803e3d6000fd5b505050506040513d602081101561174557600080fd5b505161175086611e0b565b9063ffffffff61336d16565b9063ffffffff6133cd16565b92915050565b614e5a6020526000908152604090205460ff1681565b6016818154811061179157fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919060ff8082169161010090041685565b6004546001600160a01b0316331461181a5760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b815160005b818110156119c7576001614e5a600086848151811061183a57fe5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083600381111561186b57fe5b021790555083818151811061187c57fe5b60200260200101516000809054906101000a90046001600160a01b03166001600160a01b0316636352211e8684815181106118b357fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156118ef57600080fd5b505afa158015611903573d6000803e3d6000fd5b505050506040513d602081101561191957600080fd5b505160408051602080825287518282015287516001600160a01b03909416937f15a7ca2825eaeed414d8f3a520cc4db811cd1cc0f67ddfb7c0c5f7a059a7a88f938993928392918301919085019080838360005b8381101561198557818101518382015260200161196d565b50505050905090810190601f1680156119b25780820380516001836020036101000a031916815260200191505b509250505060405180910390a360010161181f565b50505050565b6003546001600160a01b031681565b60065481565b6000806119ef8484611e18565b9050611a1e60318260088110611a0157fe5b015460298360088110611a1057fe5b01549063ffffffff61340f16565b949350505050565b6005546001600160a01b03163314611a6f5760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516001600160a01b0384169163a9059cbb91849184916370a0823191602480820192602092909190829003018186803b158015611ac057600080fd5b505afa158015611ad4573d6000803e3d6000fd5b505050506040513d6020811015611aea57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015611b3b57600080fd5b505af1158015611b4f573d6000803e3d6000fd5b505050506040513d60208110156119c757600080fd5b614e595460ff1690565b600080611b7b42611695565b90506000836003811115611b8b57fe5b905060088160048110611b9a57fe5b01541580611ba6575081155b15611bb75760065492505050611768565b6000611bd060088360048110611bc957fe5b0154611695565b90508515611bf95780831415611bf95760108260048110611bed57fe5b01549350505050611768565b6000620f4240601554600c8560048110611c0f57fe5b01540281611c1957fe5b04905060008285840360065484600c8860048110611c3357fe5b015401030281611c3f57fe5b0490508082600c8660048110611c5157fe5b0154010398975050505050505050565b6003546001600160a01b03163314611caa5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b601554604080519182526020820183905280517fea0df84169e5f51c5c77a255788372ab369a0bb309af4cf5d0e0d16dc6adeb949281900390910190a1601555565b60165490565b60075481565b6017546016540390565b60185481565b60145481565b60155481565b600881600481106112ba57fe5b6003546001600160a01b03163314611d6a5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b6001600160a01b038116611daf5760405162461bcd60e51b815260040180806020018281038252602e81526020018061412e602e913960400191505060405180910390fd5b6002546040516001600160a01b038084169216907f05cd89403c6bdeac21c2ff33de395121a31fa1bc2bf3adf4825f1f86e79969dd90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611768600183611b6f565b6000816003811115611e2657fe5b83611e32576000611e35565b60045b60ff16019392505050565b6005546001600160a01b03163314611e895760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6001600160a01b038316611ee4576040805162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c69642072657665727365207265676973747261720000604482015290519081900360640190fd5b60405163c47f002760e01b8152602060048201908152602482018390526001600160a01b0385169163c47f00279185918591908190604401848480828437600081840152601f19601f8201169050808301925050509350505050602060405180830381600087803b158015611f5857600080fd5b505af1158015611f6c573d6000803e3d6000fd5b505050506040513d6020811015611f8257600080fd5b5050505050565b6000611f9583836119e2565b159392505050565b60005b8181101561206557601754601854101561205d57601854600054601680546001600160a01b0390921691634f558e79919084908110611fdb57fe5b9060005260206000209060040201600201546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561202157600080fd5b505afa158015612035573d6000803e3d6000fd5b505050506040513d602081101561204b57600080fd5b50511561205b5761205b81613451565b505b600101611fa0565b5050565b603181600881106112ba57fe5b6003546001600160a01b031633146120bf5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b614e59805460ff191690556040517f589bfff7e7b59e33b97fa923dbc99256a6d2fdf9a631b431fa2dc06f4eea0ded90600090a1565b601081600481106112ba57fe5b6039826008811061210f57fe5b6109c40201816109c4811061212057fe5b01549150829050565b6003546001600160a01b031633146121725760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b614e59805460ff191660011790556040517f60630afaadc252b436ca4fb961ec5837f6a34e3aebf89df68f3e0745d8c50a8690600090a1565b8151806121ff576040805162461bcd60e51b815260206004820152601b60248201527f4e6565642061637475616c206461746120616e642070726f6f66730000000000604482015290519081900360640190fd5b8082518161220957fe5b06156122465760405162461bcd60e51b815260040180806020018281038252602681526020018061426c6026913960400191505060405180910390fd5b60008183518161225257fe5b04905060005b82811015611f8257600060a886838151811061227057fe5b60209081029190910181015160005460408051634f558e7960e01b81529290941c6004830181905293519394506001600160a01b031692634f558e7992602480840193919291829003018186803b1580156122ca57600080fd5b505afa1580156122de573d6000803e3d6000fd5b505050506040513d60208110156122f457600080fd5b50516124735760608367ffffffffffffffff8111801561231357600080fd5b5060405190808252806020026020018201604052801561233d578160200160208202803683370190505b50905060005b8481101561239d578661236c82612360888863ffffffff61336d16565b9063ffffffff61372516565b8151811061237657fe5b602002602001015182828151811061238a57fe5b6020908102919091010152600101612343565b5060005487516001600160a01b039091169063411b054f908990869081106123c157fe5b6020026020010151836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561241f578181015183820152602001612407565b505050509050019350505050602060405180830381600087803b15801561244557600080fd5b505af1158015612459573d6000803e3d6000fd5b505050506040513d602081101561246f57600080fd5b5050505b50600101612258565b612486600161377f565b565b60175481565b60005b818110156120655760165460175410156124af576124af600061377f565b600101612491565b600060175483116124fe5760006124d584600163ffffffff61340f16565b9050601681815481106124e457fe5b906000526020600020906004020160020154915050611768565b600080612517600160175461372590919063ffffffff16565b8514156125315761252784613a2b565b9092509050612541565b61253b8585613a71565b90925090505b61254b8282613ec1565b95945050505050565b6005546001600160a01b031681565b6005546001600160a01b031633146125ac5760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6001600160a01b0381166125f15760405162461bcd60e51b81526004018080602001828103825260328152602001806142f76032913960400191505060405180910390fd5b6005546040516001600160a01b038084169216907fe74ad8e35ae0d7f4389ff1318666007250321a66dd644dca021b5e2e30fa2a5c90600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146126965760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b805160005b818110156127d4576003614e5a60008584815181106126b657fe5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908360038111156126e757fe5b02179055508281815181106126f857fe5b60200260200101516000809054906101000a90046001600160a01b03166001600160a01b0316636352211e85848151811061272f57fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b50516040516001600160a01b03909116907ff43e8f40a332d86c5b783dafb3a81d6bb1f9a48a5ba2fb3a9bcb8379b29ffadf90600090a360010161269b565b505050565b6127e1611b65565b15156001146128215760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b8151156128325761283282826121ab565b600161283e81876119e2565b85111561287c5760405162461bcd60e51b815260040180806020018281038252602f8152602001806141f5602f913960400191505060405180910390fd5b600086600381111561288a57fe5b60015460408051627eeac760e11b815233600482015260248101849052905192935088926001600160a01b039092169162fdd58e91604480820192602092909190829003018186803b1580156128df57600080fd5b505afa1580156128f3573d6000803e3d6000fd5b505050506040513d602081101561290957600080fd5b505110156129485760405162461bcd60e51b81526004018080602001828103825260478152602001806144046047913960600191505060405180910390fd5b60408051600180825281830190925260609160208083019080368337505060408051600180825281830190925292935060609291506020808301908036833701905050905082600381111561299957fe5b826000815181106129a657fe5b602002602001019060038111156129b957fe5b908160038111156129c657fe5b8152505087816000815181106129d857fe5b6020908102919091018101919091526001546040516383b2a9c560e01b815233600482018181526060602484019081528751606485015287516001600160a01b03909516956383b2a9c5959394899489949392604483019260840191878201910280838360005b83811015612a57578181015183820152602001612a3f565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a96578181015183820152602001612a7e565b5050505090500195505050505050600060405180830381600087803b158015612abe57600080fd5b505af1158015612ad2573d6000803e3d6000fd5b506000925050505b88811015612c175760166040518060a001604052808a6001600160a01b031681526020014381526020016000815260200187151581526020018c6003811115612b1f57fe5b90528154600180820184556000938452602093849020835160049093020180546001600160a01b0319166001600160a01b0390931692909217825592820151928101929092556040810151600283015560608101516003808401805460ff1916921515929092178083556080840151939493929161ff001990911690610100908490811115612baa57fe5b02179055505050896003811115612bbd57fe5b601654604080516001600160a01b038c1681526020810192909252600082820152518715159133917f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9181900360600190a4600101612ada565b506000612c24858b611e18565b9050612c458960318360088110612c3757fe5b01549063ffffffff61372516565b60318260088110612c5257fe5b0155612c6060018a0161248e565b612c6c89600101611f9d565b50505050505050505050565b6005546001600160a01b03163314612cc15760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6040805163a22cb46560e01b81526001600160a01b0383811660048301526001602483015291519184169163a22cb4659160448082019260009290919082900301818387803b158015612d1357600080fd5b505af1158015612d27573d6000803e3d6000fd5b505050505050565b6003546001600160a01b03163314612d785760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b60008111612db75760405162461bcd60e51b81526004018080602001828103825260258152602001806142476025913960400191505060405180910390fd5b600654604080519182526020820183905280517fa698b61af4bc9de0b1fcf8f6620fc0369760a15fd45516b70731063d6a5204639281900390910190a1600655565b602981600881106112ba57fe5b612e0e611b65565b1515600114612e4e5760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b815115612e5f57612e5f82826121ab565b6000612e6b81876119e2565b851115612ea95760405162461bcd60e51b815260040180806020018281038252602f8152602001806141f5602f913960400191505060405180910390fd5b6000612eb4876116c3565b90506000612ec8878363ffffffff61336d16565b905080341015612f095760405162461bcd60e51b815260040180806020018281038252603d815260200180614183603d913960400191505060405180910390fd5b6000886003811115612f1757fe5b905060088160048110612f2657fe5b01541580612f4b5750612f3f60088260048110611bc957fe5b612f4842611695565b14155b15612f6957612f5989611e0b565b60108260048110612f6657fe5b01555b6003546040516000916001600160a01b03169084908381818185875af1925050503d8060008114612fb6576040519150601f19603f3d011682016040523d82523d6000602084013e612fbb565b606091505b5050905080613011576040805162461bcd60e51b815260206004820152601960248201527f4572726f7220696e2073656e64696e67207061796d656e742100000000000000604482015290519081900360640190fd5b60005b8981101561317b5760166040518060a001604052808b6001600160a01b031681526020014381526020016000815260200188151581526020018d600381111561305957fe5b90528154600180820184556000938452602093849020835160049093020180546001600160a01b0319166001600160a01b0390931692909217825592820151928101929092556040810151600283015560608101516003808401805460ff1916921515929092178083556080840151939493929161ff0019909116906101009084908111156130e457fe5b021790555050508a60038111156130f757fe5b601654604080516001600160a01b038d1681526020810192909252818101889052518815159133917f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9181900360600190a461315460008c611b6f565b600c846004811061316157fe5b0155426008846004811061317157fe5b0155600101613014565b506000613188868c611e18565b905061319b8a60318360088110612c3757fe5b603182600881106131a857fe5b01556131b660018b0161248e565b6131c28a600101611f9d565b83341115613276576000336131dd348763ffffffff61340f16565b604051600081818185875af1925050503d8060008114613219576040519150601f19603f3d011682016040523d82523d6000602084013e61321e565b606091505b5050905080613274576040805162461bcd60e51b815260206004820152601a60248201527f4572726f7220696e2072657475726e696e67206368616e676521000000000000604482015290519081900360640190fd5b505b5050505050505050505050565b6004546001600160a01b031633146132cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b6001600160a01b0381166133115760405162461bcd60e51b815260040180806020018281038252602b81526020018061444b602b913960400191505060405180910390fd5b6004546040516001600160a01b038084169216907fce25c0b3947fab39d425994edb341c50f20faf7987f0211bd06db98f98d4fdca90600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008261337c57506000611768565b8282028284828161338957fe5b04146133c65760405162461bcd60e51b81526004018080602001828103825260218152602001806143866021913960400191505060405180910390fd5b9392505050565b60006133c683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613efc565b60006133c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613f9e565b60006134b36016838154811061346357fe5b906000526020600020906004020160030160009054906101000a900460ff166016848154811061348f57fe5b906000526020600020906004020160030160019054906101000a900460ff16611e18565b9050601981600881106134c257fe5b0154600054601680546001600160a01b039384169390921691636352211e9190869081106134ec57fe5b9060005260206000209060040201600201546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561353257600080fd5b505afa158015613546573d6000803e3d6000fd5b505050506040513d602081101561355c57600080fd5b50516001600160a01b0316146135a35760405162461bcd60e51b81526004018080602001828103825260238152602001806142246023913960400191505060405180910390fd5b6000546001600160a01b03166342842e0e601983600881106135c157fe5b0154601680546001600160a01b0390921691869081106135dd57fe5b6000918252602090912060049091020154601680546001600160a01b03909216918790811061360857fe5b9060005260206000209060040201600201546040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561368257600080fd5b505af1158015613696573d6000803e3d6000fd5b50505050601682815481106136a757fe5b6000918252602090912060049091020154601680546001600160a01b0390921691849081106136d257fe5b6000918252602082206002600490920201015460405190917febe35dcb010498636222c9a95b0cca7ea2c23054f52e9ab190bceddd7fda851991a361371e82600163ffffffff61372516565b6018555050565b6000828201838110156133c6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60175460009061379690600163ffffffff61372516565b905060006137ab82600163ffffffff61340f16565b905043601682815481106137bb57fe5b90600052602060002090600402016001015410156139ee576000806137e06000613a2b565b9150915060006137f08383613ec1565b9050806016858154811061380057fe5b906000526020600020906004020160020181905550806016858154811061382357fe5b6000918252602091829020600490910201546040805189815290516001600160a01b03909216927f0ba3f15236668315a95f6121fb9777981d4f84b89cb5647eefbc9c4fd8d377f492918290030190a36017546018541480156138fa575060005460408051634f558e7960e01b81526004810184905290516001600160a01b0390921691634f558e7991602480820192602092909190829003018186803b1580156138cd57600080fd5b505afa1580156138e1573d6000803e3d6000fd5b505050506040513d60208110156138f757600080fd5b50515b156139085761390884613451565b600061391c600160298660088110611a1057fe5b90508083146139855760006039856008811061393457fe5b6109c40201826109c4811061394557fe5b015490508061396257816021866008811061395c57fe5b01540190505b806039866008811061397057fe5b6109c40201856109c4811061398157fe5b0155505b613997600160298660088110611a1057fe5b602985600881106139a457fe5b01556139b8600160318660088110611a1057fe5b603185600881106139c557fe5b0155506000908152614e5a60205260409020805460ff19166001179055505060178290556127d4565b82156127d45760405162461bcd60e51b81526004018080602001828103825260278152602001806143a76027913960400191505060405180910390fd5b600080600060175490506000613a476016838154811061346357fe5b90506000613a648360298460088110613a5c57fe5b015488613ff8565b9194509092505050915091565b6000806017548411613aca576040805162461bcd60e51b815260206004820152601f60248201527f546865206173736574207761732061737369676e656420616c72656164792e00604482015290519081900360640190fd5b601654841115613b21576040805162461bcd60e51b815260206004820181905260248201527f45786365656473206d6178696d756d2073657175656e6365206e756d6265722e604482015290519081900360640190fd5b6000613b386017548661340f90919063ffffffff16565b905060608167ffffffffffffffff81118015613b5357600080fd5b50604051908082528060200260200182016040528015613b7d578160200160208202803683370190505b50905060608267ffffffffffffffff81118015613b9957600080fd5b50604051908082528060200260200182016040528015613bc3578160200160208202803683370190505b50905060608367ffffffffffffffff81118015613bdf57600080fd5b50604051908082528060200260200182016040528015613c09578160200160208202803683370190505b50604080516008808252610120820190925291925060609190602082016101008036833701905050905060005b85811015613e6557601754600090613c54908363ffffffff61372516565b9050613c9260168281548110613c6657fe5b906000526020600020906004020160030160009054906101000a900460ff166016838154811061348f57fe5b868381518110613c9e57fe5b6020026020010181815250506000613cf684888581518110613cbc57fe5b602002602001015181518110613cce57fe5b60200260200101516029898681518110613ce457fe5b602002602001015160088110611a1057fe5b9050613d0382828d613ff8565b868481518110613d0f57fe5b602090810291909101015260005b83811015613dcd5760005b84811015613dc457888181518110613d3c57fe5b6020026020010151898681518110613d5057fe5b6020026020010151148015613d8a5750878181518110613d6c57fe5b6020026020010151888681518110613d8057fe5b6020026020010151145b15613dbc57868181518110613d9b57fe5b6020026020010151888681518110613daf57fe5b6020026020010181815250505b600101613d28565b50600101613d1d565b50613ddf81600163ffffffff61340f16565b858481518110613deb57fe5b602002602001018181525050613e31600185898681518110613e0957fe5b602002602001015181518110613e1b57fe5b602002602001015161372590919063ffffffff16565b84888581518110613e3e57fe5b602002602001015181518110613e5057fe5b60209081029190910101525050600101613c36565b5083613e7886600163ffffffff61340f16565b81518110613e8257fe5b602002602001015183613e9f60018861340f90919063ffffffff16565b81518110613ea957fe5b60200260200101519650965050505050509250929050565b60008060398460088110613ed157fe5b6109c40201836109c48110613ee257fe5b01549050806133c657611a1e8360218660088110612c3757fe5b60008183613f885760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f4d578181015183820152602001613f35565b50505050905090810190601f168015613f7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613f9457fe5b0495945050505050565b60008184841115613ff05760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613f4d578181015183820152602001613f35565b505050900390565b600080436016868154811061400957fe5b9060005260206000209060040201600101541415614064578261405d5760405162461bcd60e51b81526004018080602001828103825260418152602001806144766041913960600191505060405180910390fd5b50816140f2565b6101004310806140a357506140814361010063ffffffff61340f16565b6016868154811061408e57fe5b90600052602060002090600402016001015410155b156140cf57601685815481106140b557fe5b9060005260206000209060040201600101544090506140f2565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4705b6040805160208082018890528183018490528251808303840181526060909201909252805191012084908161412357fe5b069594505050505056fe596f75206e65656420746f2070726f7669646520616e2061637475616c204f7261636c6520636f6e74726163742e62656e65666963696172792063616e6e6f7420626520746865207a65726f20616464726573732e596f75206e65656420746f2073656e6420656e6f7567682063757272656e637920746f20627579207468652073706563696669656420616d6f756e742e4f6e6c79207468652063757272656e742062656e6566696e69636172792063616e2063616c6c20746869732066756e6374696f6e2e4e6f7420656e6f7567682061737365747320617661696c61626c6520746f20627579207468617420616d6f756e742e416c7265616479207472616e73666572726564206f7574206f662074686520706f6f6c596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f2070726963652e436f756e74206f66206461746120616e642070726f6f6673206e65656420746f206d61746368596f75206e65656420746f2070726f766964652061207072696365207461726765742074696d6520696e20746865206675747572652e7368697070696e67436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e746f6b656e41737369676e6d656e74436f6e74726f6c2063616e6e6f7420626520746865207a65726f20616464726573732e596f752063616e206f6e6c792072657175657374207368697070696e6720666f7220796f7572206f776e20746f6b656e732e546869732063616c6c206f6e6c7920776f726b73207768656e207468652073686f70206973206f70656e2e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f742061737369676e2061737365747320696e207468652073616d6520626c6f636b2e746f6b656e41737369676e6d656e74436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e596f75206e65656420746f206f776e20656e6f7567682070726573616c6520766f75636865727320746f2072656465656d207468652073706563696669656420616d6f756e742e7368697070696e67436f6e74726f6c2063616e6e6f7420626520746865207a65726f20616464726573732e466f722061737365747320736f6c6420696e207468652063757272656e7420626c6f636b2c2070726f7669646520612076616c696420626c6f636b20686173682e5368697070696e672077617320616c72656164792072657175657374656420666f72206f6e65206f6620746865736520746f6b656e73206f7220697420776173206e6f7420736f6c6420627920746869732073686f702ea2646970667358221220675293a428cc64fcef06eb856578527f12f5baf480f751a59c24ff72a712cac064736f6c634300060a0033596f75206e65656420746f2070726f7669646520616e2061637475616c204f7261636c6520636f6e74726163742e596f75206e65656420746f2070726f7669646520616e2061637475616c20746f6b656e41737369676e6d656e74436f6e74726f6c20616464726573732e596f75206e65656420746f2070726f7669646520616e2061637475616c207368697070696e67436f6e74726f6c20616464726573732e596f75206e65656420746f2070726f766964652061207072696365207461726765742074696d6520696e20746865206675747572652e4e65656420636f727265637420616d6f756e74206f6620746f6b656e20706f6f6c207374617274204944732e4e65656420636f727265637420616d6f756e74206f6620746f6b656e20706f6f6c206164647265737365732e596f75206e65656420746f2070726f7669646520616e2061637475616c2043727970746f7374616d7020322050726573616c6520636f6e74726163742e596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f20626173652070726963652e596f75206e65656420746f2070726f7669646520616e2061637475616c2043727970746f7374616d70203220636f6e74726163742e596f75206e65656420746f2070726f7669646520616e2061637475616c2062656e656669636961727920616464726573732e0000000000000000000000001863d1351fc3003f1ad361939248e3a3a114958e000000000000000000000000a7f87e8d193e29bf1ed050fdd511b79fe0264d8b000000000000000000000000818737eec8a5350756da40d5ddafda8a84ade10700000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000005f7a620000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000cebb9ae52a3d61c4ed1528fba93e5beaaa40e9e20000000000000000000000009a5be4f89d483e445716dc1abb7668e56deaa909000000000000000000000000596e620e175c2c37a5f35a41d9f2305a991ffc8900000000000000000000000000000000000000000000000000000000000009c4000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000075b09e4ac76b2a9fc104014b1f73ce2dc134472600000000000000000000000023ba98addef64e1fdbdacee2293cbfd5f3d5e7ab000000000000000000000000d8a2264ba34fecb10e0001b5ffed50bfa7f2c0a90000000000000000000000002b15bdea3e1f4373607c1e468194e52d7d7c5b3500000000000000000000000094d20a5c9dff08a430e87e60c7ba5918833b72a3000000000000000000000000a9d27dc56c45fb9388ebb27cb0dcce6e4c97eadc0000000000000000000000002c6176e791a07930d86634a9dc191af9fa6251be00000000000000000000000069148554c14e061600109771102d7e329d796df20000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000d6d8000000000000000000000000000000000000000000000000000000000001c138000000000000000000000000000000000000000000000000000000000002ab9800000000000000000000000000000000000000000000000000000000000395f8000000000000000000000000000000000000000000000000000000000000e09c000000000000000000000000000000000000000000000000000000000001cafc000000000000000000000000000000000000000000000000000000000002b55c0000000000000000000000000000000000000000000000000000000000039fbc

Deployed Bytecode

0x6080604052600436106102fe5760003560e01c80637289f98c11610190578063adc34bb2116100dc578063d4f8788d11610095578063de4b32621161006f578063de4b326214610fe5578063f06f44551461100f578063f7de5f7c14611039578063f93ce63a1461117b576102fe565b8063d4f8788d14610dad578063d74b17d514610e5b578063dd48f77414610faa576102fe565b8063adc34bb214610ce1578063b77f9de914610cf6578063ba91966514610d0b578063c13245c114610d35578063c8c2ed5414610d65578063d0763c9514610d7a576102fe565b8063963b079911610149578063a0327ac011610123578063a0327ac014610b42578063a683b7c914610b6c578063a6f5a22b14610b9c578063ac77efb614610bb1576102fe565b8063963b079914610ad9578063979e99c814610b035780639b6dbc8a14610b2d576102fe565b80637289f98c1461095a5780637adbf9731461098457806381b4bd34146109b75780638820e6f5146109e45780638e8fa11f14610a1957806390ffb86414610aa4576102fe565b806338af3eed1161024f5780634f7f15511161020857806363a6344e116101e257806363a6344e146109065780636714494a1461091b5780636738bc6a146109305780636e28f11114610945576102fe565b80634f7f1551146108b257806351cb394c146108dc5780635ed0b0ce146108f1576102fe565b806338af3eed146107ba5780633918021d146107cf57806339c45762146107e45780634707d0001461081957806347535d7b14610854578063477a1a301461087d576102fe565b80631786ba1b116102bc578063322b1cc511610296578063322b1cc51461059557806332ba4cb0146105c25780633317b3191461061057806335f9672314610687576102fe565b80631786ba1b1461040e5780632b11645b146105415780632b85dcc91461056b576102fe565b8062c0f91614610303578063017e97bc1461034957806301ec3d151461035e57806306ff6d5f1461038a57806314946f9c146103b157806314bbe21c146103db575b600080fd5b34801561030f57600080fd5b5061032d6004803603602081101561032657600080fd5b50356111ae565b604080516001600160a01b039092168252519081900360200190f35b34801561035557600080fd5b5061032d6111cb565b34801561036a57600080fd5b506103886004803603602081101561038157600080fd5b50356111da565b005b34801561039657600080fd5b5061039f6112a3565b60408051918252519081900360200190f35b3480156103bd57600080fd5b5061039f600480360360208110156103d457600080fd5b50356112ad565b3480156103e757600080fd5b50610388600480360360208110156103fe57600080fd5b50356001600160a01b03166112c1565b34801561041a57600080fd5b506103886004803603604081101561043157600080fd5b810190602081018135600160201b81111561044b57600080fd5b82018360208201111561045d57600080fd5b803590602001918460018302840111600160201b8311171561047e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104d057600080fd5b8201836020820111156104e257600080fd5b803590602001918460208302840111600160201b8311171561050357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506113ab945050505050565b34801561054d57600080fd5b5061039f6004803603602081101561056457600080fd5b5035611688565b34801561057757600080fd5b5061039f6004803603602081101561058e57600080fd5b5035611695565b3480156105a157600080fd5b5061039f600480360360208110156105b857600080fd5b503560ff166116c3565b3480156105ce57600080fd5b506105ec600480360360208110156105e557600080fd5b503561176e565b604051808260038111156105fc57fe5b60ff16815260200191505060405180910390f35b34801561061c57600080fd5b5061063a6004803603602081101561063357600080fd5b5035611784565b604080516001600160a01b03871681526020810186905290810184905282151560608201526080810182600381111561066f57fe5b60ff1681526020019550505050505060405180910390f35b34801561069357600080fd5b50610388600480360360408110156106aa57600080fd5b810190602081018135600160201b8111156106c457600080fd5b8201836020820111156106d657600080fd5b803590602001918460208302840111600160201b831117156106f757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561074657600080fd5b82018360208201111561075857600080fd5b803590602001918460018302840111600160201b8311171561077957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506117d1945050505050565b3480156107c657600080fd5b5061032d6119cd565b3480156107db57600080fd5b5061039f6119dc565b3480156107f057600080fd5b5061039f6004803603604081101561080757600080fd5b5080351515906020013560ff166119e2565b34801561082557600080fd5b506103886004803603604081101561083c57600080fd5b506001600160a01b0381358116916020013516611a26565b34801561086057600080fd5b50610869611b65565b604080519115158252519081900360200190f35b34801561088957600080fd5b5061039f600480360360408110156108a057600080fd5b5080351515906020013560ff16611b6f565b3480156108be57600080fd5b50610388600480360360208110156108d557600080fd5b5035611c61565b3480156108e857600080fd5b5061039f611cec565b3480156108fd57600080fd5b5061039f611cf2565b34801561091257600080fd5b5061039f611cf8565b34801561092757600080fd5b5061039f611d02565b34801561093c57600080fd5b5061039f611d08565b34801561095157600080fd5b5061039f611d0e565b34801561096657600080fd5b5061039f6004803603602081101561097d57600080fd5b5035611d14565b34801561099057600080fd5b50610388600480360360208110156109a757600080fd5b50356001600160a01b0316611d21565b3480156109c357600080fd5b5061039f600480360360208110156109da57600080fd5b503560ff16611e0b565b3480156109f057600080fd5b5061039f60048036036040811015610a0757600080fd5b5080351515906020013560ff16611e18565b348015610a2557600080fd5b5061038860048036036040811015610a3c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610a6657600080fd5b820183602082011115610a7857600080fd5b803590602001918460018302840111600160201b83111715610a9957600080fd5b509092509050611e40565b348015610ab057600080fd5b5061086960048036036040811015610ac757600080fd5b5080351515906020013560ff16611f89565b348015610ae557600080fd5b5061038860048036036020811015610afc57600080fd5b5035611f9d565b348015610b0f57600080fd5b5061039f60048036036020811015610b2657600080fd5b5035612069565b348015610b3957600080fd5b50610388612076565b348015610b4e57600080fd5b5061039f60048036036020811015610b6557600080fd5b50356120f5565b348015610b7857600080fd5b5061039f60048036036040811015610b8f57600080fd5b5080359060200135612102565b348015610ba857600080fd5b50610388612129565b348015610bbd57600080fd5b5061038860048036036040811015610bd457600080fd5b810190602081018135600160201b811115610bee57600080fd5b820183602082011115610c0057600080fd5b803590602001918460208302840111600160201b83111715610c2157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610c7057600080fd5b820183602082011115610c8257600080fd5b803590602001918460208302840111600160201b83111715610ca357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506121ab945050505050565b348015610ced57600080fd5b5061038861247c565b348015610d0257600080fd5b5061039f612488565b348015610d1757600080fd5b5061038860048036036020811015610d2e57600080fd5b503561248e565b348015610d4157600080fd5b5061039f60048036036040811015610d5857600080fd5b50803590602001356124b7565b348015610d7157600080fd5b5061032d612554565b348015610d8657600080fd5b5061038860048036036020811015610d9d57600080fd5b50356001600160a01b0316612563565b348015610db957600080fd5b5061038860048036036020811015610dd057600080fd5b810190602081018135600160201b811115610dea57600080fd5b820183602082011115610dfc57600080fd5b803590602001918460208302840111600160201b83111715610e1d57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061264d945050505050565b348015610e6757600080fd5b50610388600480360360a0811015610e7e57600080fd5b60ff823516916020810135916001600160a01b036040830135169190810190608081016060820135600160201b811115610eb757600080fd5b820183602082011115610ec957600080fd5b803590602001918460208302840111600160201b83111715610eea57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610f3957600080fd5b820183602082011115610f4b57600080fd5b803590602001918460208302840111600160201b83111715610f6c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506127d9945050505050565b348015610fb657600080fd5b5061038860048036036040811015610fcd57600080fd5b506001600160a01b0381358116916020013516612c78565b348015610ff157600080fd5b506103886004803603602081101561100857600080fd5b5035612d2f565b34801561101b57600080fd5b5061039f6004803603602081101561103257600080fd5b5035612df9565b610388600480360360a081101561104f57600080fd5b60ff823516916020810135916001600160a01b036040830135169190810190608081016060820135600160201b81111561108857600080fd5b82018360208201111561109a57600080fd5b803590602001918460208302840111600160201b831117156110bb57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561110a57600080fd5b82018360208201111561111c57600080fd5b803590602001918460208302840111600160201b8311171561113d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612e06945050505050565b34801561118757600080fd5b506103886004803603602081101561119e57600080fd5b50356001600160a01b0316613283565b601981600881106111bb57fe5b01546001600160a01b0316905081565b6004546001600160a01b031681565b6003546001600160a01b031633146112235760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b4281116112615760405162461bcd60e51b81526004018080602001828103825260368152602001806142926036913960400191505060405180910390fd5b600754604080519182526020820183905280517f18ff519ede7363293f7cd545e18c74b70bce1dc4c144792836b2a29e9c8a1b719281900390910190a1600755565b6018546016540390565b602181600881106112ba57fe5b0154905081565b6003546001600160a01b0316331461130a5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b6001600160a01b03811661134f5760405162461bcd60e51b815260040180806020018281038252602781526020018061415c6027913960400191505060405180910390fd5b6003546040516001600160a01b038084169216907f57005c5083fa0952870a7906715a2f6f9ef2d01b4a423e4b3ce59c6129b1a76390600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6113b3611b65565b15156001146113f35760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b805160005b8181101561159957600054835133916001600160a01b031690636352211e9086908590811061142357fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561145f57600080fd5b505afa158015611473573d6000803e3d6000fd5b505050506040513d602081101561148957600080fd5b50516001600160a01b0316146114d05760405162461bcd60e51b81526004018080602001828103825260328152602001806143296032913960400191505060405180910390fd5b6001614e5a60008584815181106114e357fe5b60209081029190910181015182528101919091526040016000205460ff16600381111561150c57fe5b146115485760405162461bcd60e51b81526004018080602001828103825260578152602001806144b76057913960600191505060405180910390fd5b6002614e5a600085848151811061155b57fe5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083600381111561158c57fe5b02179055506001016113f8565b50336001600160a01b03167fd84b3824b00dc38c63428fb6ae9dc02b61b6ddb8845aaacf34b8950a81e687128385604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561160b5781810151838201526020016115f3565b50505050905001838103825284818151815260200191508051906020019080838360005b8381101561164757818101518382015260200161162f565b50505050905090810190601f1680156116745780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2505050565b600c81600481106112ba57fe5b600060075482106116a8575060006116be565b6014548260075403816116b757fe5b0460010190505b919050565b6000611768606461175c600260009054906101000a90046001600160a01b03166001600160a01b03166354a4adc26040518163ffffffff1660e01b815260040160206040518083038186803b15801561171b57600080fd5b505afa15801561172f573d6000803e3d6000fd5b505050506040513d602081101561174557600080fd5b505161175086611e0b565b9063ffffffff61336d16565b9063ffffffff6133cd16565b92915050565b614e5a6020526000908152604090205460ff1681565b6016818154811061179157fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919060ff8082169161010090041685565b6004546001600160a01b0316331461181a5760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b815160005b818110156119c7576001614e5a600086848151811061183a57fe5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083600381111561186b57fe5b021790555083818151811061187c57fe5b60200260200101516000809054906101000a90046001600160a01b03166001600160a01b0316636352211e8684815181106118b357fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156118ef57600080fd5b505afa158015611903573d6000803e3d6000fd5b505050506040513d602081101561191957600080fd5b505160408051602080825287518282015287516001600160a01b03909416937f15a7ca2825eaeed414d8f3a520cc4db811cd1cc0f67ddfb7c0c5f7a059a7a88f938993928392918301919085019080838360005b8381101561198557818101518382015260200161196d565b50505050905090810190601f1680156119b25780820380516001836020036101000a031916815260200191505b509250505060405180910390a360010161181f565b50505050565b6003546001600160a01b031681565b60065481565b6000806119ef8484611e18565b9050611a1e60318260088110611a0157fe5b015460298360088110611a1057fe5b01549063ffffffff61340f16565b949350505050565b6005546001600160a01b03163314611a6f5760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516001600160a01b0384169163a9059cbb91849184916370a0823191602480820192602092909190829003018186803b158015611ac057600080fd5b505afa158015611ad4573d6000803e3d6000fd5b505050506040513d6020811015611aea57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015611b3b57600080fd5b505af1158015611b4f573d6000803e3d6000fd5b505050506040513d60208110156119c757600080fd5b614e595460ff1690565b600080611b7b42611695565b90506000836003811115611b8b57fe5b905060088160048110611b9a57fe5b01541580611ba6575081155b15611bb75760065492505050611768565b6000611bd060088360048110611bc957fe5b0154611695565b90508515611bf95780831415611bf95760108260048110611bed57fe5b01549350505050611768565b6000620f4240601554600c8560048110611c0f57fe5b01540281611c1957fe5b04905060008285840360065484600c8860048110611c3357fe5b015401030281611c3f57fe5b0490508082600c8660048110611c5157fe5b0154010398975050505050505050565b6003546001600160a01b03163314611caa5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b601554604080519182526020820183905280517fea0df84169e5f51c5c77a255788372ab369a0bb309af4cf5d0e0d16dc6adeb949281900390910190a1601555565b60165490565b60075481565b6017546016540390565b60185481565b60145481565b60155481565b600881600481106112ba57fe5b6003546001600160a01b03163314611d6a5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b6001600160a01b038116611daf5760405162461bcd60e51b815260040180806020018281038252602e81526020018061412e602e913960400191505060405180910390fd5b6002546040516001600160a01b038084169216907f05cd89403c6bdeac21c2ff33de395121a31fa1bc2bf3adf4825f1f86e79969dd90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611768600183611b6f565b6000816003811115611e2657fe5b83611e32576000611e35565b60045b60ff16019392505050565b6005546001600160a01b03163314611e895760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6001600160a01b038316611ee4576040805162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c69642072657665727365207265676973747261720000604482015290519081900360640190fd5b60405163c47f002760e01b8152602060048201908152602482018390526001600160a01b0385169163c47f00279185918591908190604401848480828437600081840152601f19601f8201169050808301925050509350505050602060405180830381600087803b158015611f5857600080fd5b505af1158015611f6c573d6000803e3d6000fd5b505050506040513d6020811015611f8257600080fd5b5050505050565b6000611f9583836119e2565b159392505050565b60005b8181101561206557601754601854101561205d57601854600054601680546001600160a01b0390921691634f558e79919084908110611fdb57fe5b9060005260206000209060040201600201546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561202157600080fd5b505afa158015612035573d6000803e3d6000fd5b505050506040513d602081101561204b57600080fd5b50511561205b5761205b81613451565b505b600101611fa0565b5050565b603181600881106112ba57fe5b6003546001600160a01b031633146120bf5760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b614e59805460ff191690556040517f589bfff7e7b59e33b97fa923dbc99256a6d2fdf9a631b431fa2dc06f4eea0ded90600090a1565b601081600481106112ba57fe5b6039826008811061210f57fe5b6109c40201816109c4811061212057fe5b01549150829050565b6003546001600160a01b031633146121725760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b614e59805460ff191660011790556040517f60630afaadc252b436ca4fb961ec5837f6a34e3aebf89df68f3e0745d8c50a8690600090a1565b8151806121ff576040805162461bcd60e51b815260206004820152601b60248201527f4e6565642061637475616c206461746120616e642070726f6f66730000000000604482015290519081900360640190fd5b8082518161220957fe5b06156122465760405162461bcd60e51b815260040180806020018281038252602681526020018061426c6026913960400191505060405180910390fd5b60008183518161225257fe5b04905060005b82811015611f8257600060a886838151811061227057fe5b60209081029190910181015160005460408051634f558e7960e01b81529290941c6004830181905293519394506001600160a01b031692634f558e7992602480840193919291829003018186803b1580156122ca57600080fd5b505afa1580156122de573d6000803e3d6000fd5b505050506040513d60208110156122f457600080fd5b50516124735760608367ffffffffffffffff8111801561231357600080fd5b5060405190808252806020026020018201604052801561233d578160200160208202803683370190505b50905060005b8481101561239d578661236c82612360888863ffffffff61336d16565b9063ffffffff61372516565b8151811061237657fe5b602002602001015182828151811061238a57fe5b6020908102919091010152600101612343565b5060005487516001600160a01b039091169063411b054f908990869081106123c157fe5b6020026020010151836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561241f578181015183820152602001612407565b505050509050019350505050602060405180830381600087803b15801561244557600080fd5b505af1158015612459573d6000803e3d6000fd5b505050506040513d602081101561246f57600080fd5b5050505b50600101612258565b612486600161377f565b565b60175481565b60005b818110156120655760165460175410156124af576124af600061377f565b600101612491565b600060175483116124fe5760006124d584600163ffffffff61340f16565b9050601681815481106124e457fe5b906000526020600020906004020160020154915050611768565b600080612517600160175461372590919063ffffffff16565b8514156125315761252784613a2b565b9092509050612541565b61253b8585613a71565b90925090505b61254b8282613ec1565b95945050505050565b6005546001600160a01b031681565b6005546001600160a01b031633146125ac5760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6001600160a01b0381166125f15760405162461bcd60e51b81526004018080602001828103825260328152602001806142f76032913960400191505060405180910390fd5b6005546040516001600160a01b038084169216907fe74ad8e35ae0d7f4389ff1318666007250321a66dd644dca021b5e2e30fa2a5c90600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146126965760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b805160005b818110156127d4576003614e5a60008584815181106126b657fe5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908360038111156126e757fe5b02179055508281815181106126f857fe5b60200260200101516000809054906101000a90046001600160a01b03166001600160a01b0316636352211e85848151811061272f57fe5b60200260200101516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b50516040516001600160a01b03909116907ff43e8f40a332d86c5b783dafb3a81d6bb1f9a48a5ba2fb3a9bcb8379b29ffadf90600090a360010161269b565b505050565b6127e1611b65565b15156001146128215760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b8151156128325761283282826121ab565b600161283e81876119e2565b85111561287c5760405162461bcd60e51b815260040180806020018281038252602f8152602001806141f5602f913960400191505060405180910390fd5b600086600381111561288a57fe5b60015460408051627eeac760e11b815233600482015260248101849052905192935088926001600160a01b039092169162fdd58e91604480820192602092909190829003018186803b1580156128df57600080fd5b505afa1580156128f3573d6000803e3d6000fd5b505050506040513d602081101561290957600080fd5b505110156129485760405162461bcd60e51b81526004018080602001828103825260478152602001806144046047913960600191505060405180910390fd5b60408051600180825281830190925260609160208083019080368337505060408051600180825281830190925292935060609291506020808301908036833701905050905082600381111561299957fe5b826000815181106129a657fe5b602002602001019060038111156129b957fe5b908160038111156129c657fe5b8152505087816000815181106129d857fe5b6020908102919091018101919091526001546040516383b2a9c560e01b815233600482018181526060602484019081528751606485015287516001600160a01b03909516956383b2a9c5959394899489949392604483019260840191878201910280838360005b83811015612a57578181015183820152602001612a3f565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a96578181015183820152602001612a7e565b5050505090500195505050505050600060405180830381600087803b158015612abe57600080fd5b505af1158015612ad2573d6000803e3d6000fd5b506000925050505b88811015612c175760166040518060a001604052808a6001600160a01b031681526020014381526020016000815260200187151581526020018c6003811115612b1f57fe5b90528154600180820184556000938452602093849020835160049093020180546001600160a01b0319166001600160a01b0390931692909217825592820151928101929092556040810151600283015560608101516003808401805460ff1916921515929092178083556080840151939493929161ff001990911690610100908490811115612baa57fe5b02179055505050896003811115612bbd57fe5b601654604080516001600160a01b038c1681526020810192909252600082820152518715159133917f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9181900360600190a4600101612ada565b506000612c24858b611e18565b9050612c458960318360088110612c3757fe5b01549063ffffffff61372516565b60318260088110612c5257fe5b0155612c6060018a0161248e565b612c6c89600101611f9d565b50505050505050505050565b6005546001600160a01b03163314612cc15760405162461bcd60e51b81526004018080602001828103825260368152602001806143ce6036913960400191505060405180910390fd5b6040805163a22cb46560e01b81526001600160a01b0383811660048301526001602483015291519184169163a22cb4659160448082019260009290919082900301818387803b158015612d1357600080fd5b505af1158015612d27573d6000803e3d6000fd5b505050505050565b6003546001600160a01b03163314612d785760405162461bcd60e51b81526004018080602001828103825260358152602001806141c06035913960400191505060405180910390fd5b60008111612db75760405162461bcd60e51b81526004018080602001828103825260258152602001806142476025913960400191505060405180910390fd5b600654604080519182526020820183905280517fa698b61af4bc9de0b1fcf8f6620fc0369760a15fd45516b70731063d6a5204639281900390910190a1600655565b602981600881106112ba57fe5b612e0e611b65565b1515600114612e4e5760405162461bcd60e51b815260040180806020018281038252602b81526020018061435b602b913960400191505060405180910390fd5b815115612e5f57612e5f82826121ab565b6000612e6b81876119e2565b851115612ea95760405162461bcd60e51b815260040180806020018281038252602f8152602001806141f5602f913960400191505060405180910390fd5b6000612eb4876116c3565b90506000612ec8878363ffffffff61336d16565b905080341015612f095760405162461bcd60e51b815260040180806020018281038252603d815260200180614183603d913960400191505060405180910390fd5b6000886003811115612f1757fe5b905060088160048110612f2657fe5b01541580612f4b5750612f3f60088260048110611bc957fe5b612f4842611695565b14155b15612f6957612f5989611e0b565b60108260048110612f6657fe5b01555b6003546040516000916001600160a01b03169084908381818185875af1925050503d8060008114612fb6576040519150601f19603f3d011682016040523d82523d6000602084013e612fbb565b606091505b5050905080613011576040805162461bcd60e51b815260206004820152601960248201527f4572726f7220696e2073656e64696e67207061796d656e742100000000000000604482015290519081900360640190fd5b60005b8981101561317b5760166040518060a001604052808b6001600160a01b031681526020014381526020016000815260200188151581526020018d600381111561305957fe5b90528154600180820184556000938452602093849020835160049093020180546001600160a01b0319166001600160a01b0390931692909217825592820151928101929092556040810151600283015560608101516003808401805460ff1916921515929092178083556080840151939493929161ff0019909116906101009084908111156130e457fe5b021790555050508a60038111156130f757fe5b601654604080516001600160a01b038d1681526020810192909252818101889052518815159133917f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9181900360600190a461315460008c611b6f565b600c846004811061316157fe5b0155426008846004811061317157fe5b0155600101613014565b506000613188868c611e18565b905061319b8a60318360088110612c3757fe5b603182600881106131a857fe5b01556131b660018b0161248e565b6131c28a600101611f9d565b83341115613276576000336131dd348763ffffffff61340f16565b604051600081818185875af1925050503d8060008114613219576040519150601f19603f3d011682016040523d82523d6000602084013e61321e565b606091505b5050905080613274576040805162461bcd60e51b815260206004820152601a60248201527f4572726f7220696e2072657475726e696e67206368616e676521000000000000604482015290519081900360640190fd5b505b5050505050505050505050565b6004546001600160a01b031633146132cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806142c8602f913960400191505060405180910390fd5b6001600160a01b0381166133115760405162461bcd60e51b815260040180806020018281038252602b81526020018061444b602b913960400191505060405180910390fd5b6004546040516001600160a01b038084169216907fce25c0b3947fab39d425994edb341c50f20faf7987f0211bd06db98f98d4fdca90600090a3600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008261337c57506000611768565b8282028284828161338957fe5b04146133c65760405162461bcd60e51b81526004018080602001828103825260218152602001806143866021913960400191505060405180910390fd5b9392505050565b60006133c683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613efc565b60006133c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613f9e565b60006134b36016838154811061346357fe5b906000526020600020906004020160030160009054906101000a900460ff166016848154811061348f57fe5b906000526020600020906004020160030160019054906101000a900460ff16611e18565b9050601981600881106134c257fe5b0154600054601680546001600160a01b039384169390921691636352211e9190869081106134ec57fe5b9060005260206000209060040201600201546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561353257600080fd5b505afa158015613546573d6000803e3d6000fd5b505050506040513d602081101561355c57600080fd5b50516001600160a01b0316146135a35760405162461bcd60e51b81526004018080602001828103825260238152602001806142246023913960400191505060405180910390fd5b6000546001600160a01b03166342842e0e601983600881106135c157fe5b0154601680546001600160a01b0390921691869081106135dd57fe5b6000918252602090912060049091020154601680546001600160a01b03909216918790811061360857fe5b9060005260206000209060040201600201546040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561368257600080fd5b505af1158015613696573d6000803e3d6000fd5b50505050601682815481106136a757fe5b6000918252602090912060049091020154601680546001600160a01b0390921691849081106136d257fe5b6000918252602082206002600490920201015460405190917febe35dcb010498636222c9a95b0cca7ea2c23054f52e9ab190bceddd7fda851991a361371e82600163ffffffff61372516565b6018555050565b6000828201838110156133c6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60175460009061379690600163ffffffff61372516565b905060006137ab82600163ffffffff61340f16565b905043601682815481106137bb57fe5b90600052602060002090600402016001015410156139ee576000806137e06000613a2b565b9150915060006137f08383613ec1565b9050806016858154811061380057fe5b906000526020600020906004020160020181905550806016858154811061382357fe5b6000918252602091829020600490910201546040805189815290516001600160a01b03909216927f0ba3f15236668315a95f6121fb9777981d4f84b89cb5647eefbc9c4fd8d377f492918290030190a36017546018541480156138fa575060005460408051634f558e7960e01b81526004810184905290516001600160a01b0390921691634f558e7991602480820192602092909190829003018186803b1580156138cd57600080fd5b505afa1580156138e1573d6000803e3d6000fd5b505050506040513d60208110156138f757600080fd5b50515b156139085761390884613451565b600061391c600160298660088110611a1057fe5b90508083146139855760006039856008811061393457fe5b6109c40201826109c4811061394557fe5b015490508061396257816021866008811061395c57fe5b01540190505b806039866008811061397057fe5b6109c40201856109c4811061398157fe5b0155505b613997600160298660088110611a1057fe5b602985600881106139a457fe5b01556139b8600160318660088110611a1057fe5b603185600881106139c557fe5b0155506000908152614e5a60205260409020805460ff19166001179055505060178290556127d4565b82156127d45760405162461bcd60e51b81526004018080602001828103825260278152602001806143a76027913960400191505060405180910390fd5b600080600060175490506000613a476016838154811061346357fe5b90506000613a648360298460088110613a5c57fe5b015488613ff8565b9194509092505050915091565b6000806017548411613aca576040805162461bcd60e51b815260206004820152601f60248201527f546865206173736574207761732061737369676e656420616c72656164792e00604482015290519081900360640190fd5b601654841115613b21576040805162461bcd60e51b815260206004820181905260248201527f45786365656473206d6178696d756d2073657175656e6365206e756d6265722e604482015290519081900360640190fd5b6000613b386017548661340f90919063ffffffff16565b905060608167ffffffffffffffff81118015613b5357600080fd5b50604051908082528060200260200182016040528015613b7d578160200160208202803683370190505b50905060608267ffffffffffffffff81118015613b9957600080fd5b50604051908082528060200260200182016040528015613bc3578160200160208202803683370190505b50905060608367ffffffffffffffff81118015613bdf57600080fd5b50604051908082528060200260200182016040528015613c09578160200160208202803683370190505b50604080516008808252610120820190925291925060609190602082016101008036833701905050905060005b85811015613e6557601754600090613c54908363ffffffff61372516565b9050613c9260168281548110613c6657fe5b906000526020600020906004020160030160009054906101000a900460ff166016838154811061348f57fe5b868381518110613c9e57fe5b6020026020010181815250506000613cf684888581518110613cbc57fe5b602002602001015181518110613cce57fe5b60200260200101516029898681518110613ce457fe5b602002602001015160088110611a1057fe5b9050613d0382828d613ff8565b868481518110613d0f57fe5b602090810291909101015260005b83811015613dcd5760005b84811015613dc457888181518110613d3c57fe5b6020026020010151898681518110613d5057fe5b6020026020010151148015613d8a5750878181518110613d6c57fe5b6020026020010151888681518110613d8057fe5b6020026020010151145b15613dbc57868181518110613d9b57fe5b6020026020010151888681518110613daf57fe5b6020026020010181815250505b600101613d28565b50600101613d1d565b50613ddf81600163ffffffff61340f16565b858481518110613deb57fe5b602002602001018181525050613e31600185898681518110613e0957fe5b602002602001015181518110613e1b57fe5b602002602001015161372590919063ffffffff16565b84888581518110613e3e57fe5b602002602001015181518110613e5057fe5b60209081029190910101525050600101613c36565b5083613e7886600163ffffffff61340f16565b81518110613e8257fe5b602002602001015183613e9f60018861340f90919063ffffffff16565b81518110613ea957fe5b60200260200101519650965050505050509250929050565b60008060398460088110613ed157fe5b6109c40201836109c48110613ee257fe5b01549050806133c657611a1e8360218660088110612c3757fe5b60008183613f885760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f4d578181015183820152602001613f35565b50505050905090810190601f168015613f7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613f9457fe5b0495945050505050565b60008184841115613ff05760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613f4d578181015183820152602001613f35565b505050900390565b600080436016868154811061400957fe5b9060005260206000209060040201600101541415614064578261405d5760405162461bcd60e51b81526004018080602001828103825260418152602001806144766041913960600191505060405180910390fd5b50816140f2565b6101004310806140a357506140814361010063ffffffff61340f16565b6016868154811061408e57fe5b90600052602060002090600402016001015410155b156140cf57601685815481106140b557fe5b9060005260206000209060040201600101544090506140f2565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4705b6040805160208082018890528183018490528251808303840181526060909201909252805191012084908161412357fe5b069594505050505056fe596f75206e65656420746f2070726f7669646520616e2061637475616c204f7261636c6520636f6e74726163742e62656e65666963696172792063616e6e6f7420626520746865207a65726f20616464726573732e596f75206e65656420746f2073656e6420656e6f7567682063757272656e637920746f20627579207468652073706563696669656420616d6f756e742e4f6e6c79207468652063757272656e742062656e6566696e69636172792063616e2063616c6c20746869732066756e6374696f6e2e4e6f7420656e6f7567682061737365747320617661696c61626c6520746f20627579207468617420616d6f756e742e416c7265616479207472616e73666572726564206f7574206f662074686520706f6f6c596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f2070726963652e436f756e74206f66206461746120616e642070726f6f6673206e65656420746f206d61746368596f75206e65656420746f2070726f766964652061207072696365207461726765742074696d6520696e20746865206675747572652e7368697070696e67436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e746f6b656e41737369676e6d656e74436f6e74726f6c2063616e6e6f7420626520746865207a65726f20616464726573732e596f752063616e206f6e6c792072657175657374207368697070696e6720666f7220796f7572206f776e20746f6b656e732e546869732063616c6c206f6e6c7920776f726b73207768656e207468652073686f70206973206f70656e2e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f742061737369676e2061737365747320696e207468652073616d6520626c6f636b2e746f6b656e41737369676e6d656e74436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e596f75206e65656420746f206f776e20656e6f7567682070726573616c6520766f75636865727320746f2072656465656d207468652073706563696669656420616d6f756e742e7368697070696e67436f6e74726f6c2063616e6e6f7420626520746865207a65726f20616464726573732e466f722061737365747320736f6c6420696e207468652063757272656e7420626c6f636b2c2070726f7669646520612076616c696420626c6f636b20686173682e5368697070696e672077617320616c72656164792072657175657374656420666f72206f6e65206f6620746865736520746f6b656e73206f7220697420776173206e6f7420736f6c6420627920746869732073686f702ea2646970667358221220675293a428cc64fcef06eb856578527f12f5baf480f751a59c24ff72a712cac064736f6c634300060a0033

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

0000000000000000000000001863d1351fc3003f1ad361939248e3a3a114958e000000000000000000000000a7f87e8d193e29bf1ed050fdd511b79fe0264d8b000000000000000000000000818737eec8a5350756da40d5ddafda8a84ade10700000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000005f7a620000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000cebb9ae52a3d61c4ed1528fba93e5beaaa40e9e20000000000000000000000009a5be4f89d483e445716dc1abb7668e56deaa909000000000000000000000000596e620e175c2c37a5f35a41d9f2305a991ffc8900000000000000000000000000000000000000000000000000000000000009c4000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000075b09e4ac76b2a9fc104014b1f73ce2dc134472600000000000000000000000023ba98addef64e1fdbdacee2293cbfd5f3d5e7ab000000000000000000000000d8a2264ba34fecb10e0001b5ffed50bfa7f2c0a90000000000000000000000002b15bdea3e1f4373607c1e468194e52d7d7c5b3500000000000000000000000094d20a5c9dff08a430e87e60c7ba5918833b72a3000000000000000000000000a9d27dc56c45fb9388ebb27cb0dcce6e4c97eadc0000000000000000000000002c6176e791a07930d86634a9dc191af9fa6251be00000000000000000000000069148554c14e061600109771102d7e329d796df20000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000d6d8000000000000000000000000000000000000000000000000000000000001c138000000000000000000000000000000000000000000000000000000000002ab9800000000000000000000000000000000000000000000000000000000000395f8000000000000000000000000000000000000000000000000000000000000e09c000000000000000000000000000000000000000000000000000000000001cafc000000000000000000000000000000000000000000000000000000000002b55c0000000000000000000000000000000000000000000000000000000000039fbc

-----Decoded View---------------
Arg [0] : _oracle (address): 0x1863D1351fc3003F1Ad361939248E3a3a114958e
Arg [1] : _CS2Address (address): 0xa7f87E8D193E29bf1eD050Fdd511B79Fe0264d8B
Arg [2] : _CS2PresaleAddress (address): 0x818737EeC8A5350756DA40D5DDAfda8A84Ade107
Arg [3] : _basePriceEurCent (uint256): 700
Arg [4] : _priceTargetTimestamp (uint256): 1601856000
Arg [5] : _increaseFactorMicro (uint256): 2000
Arg [6] : _beneficiary (address): 0xCebb9aE52A3D61C4ED1528Fba93E5beaaA40e9e2
Arg [7] : _shippingControl (address): 0x9a5Be4f89D483e445716dc1abb7668e56dEAA909
Arg [8] : _tokenAssignmentControl (address): 0x596E620E175C2C37A5f35A41d9F2305A991fFc89
Arg [9] : _tokenPoolSize (uint256): 2500
Arg [10] : _tokenPools (address[]): 0x75B09e4Ac76b2A9Fc104014b1f73CE2DC1344726,0x23Ba98aDdEF64E1fDbDaCEE2293CbFd5F3D5E7ab,0xD8A2264bA34FEcB10E0001B5FFed50BFa7f2c0a9,0x2b15bdEA3E1F4373607C1e468194e52D7d7C5B35,0x94d20A5c9dFF08a430E87E60c7Ba5918833B72a3,0xA9D27dc56C45fb9388ebb27cB0dCCE6E4c97EADC,0x2C6176E791A07930D86634A9DC191aF9FA6251Be,0x69148554c14e061600109771102D7e329d796dF2
Arg [11] : _startIds (uint256[]): 55000,115000,175000,235000,57500,117500,177500,237500

-----Encoded View---------------
30 Constructor Arguments found :
Arg [0] : 0000000000000000000000001863d1351fc3003f1ad361939248e3a3a114958e
Arg [1] : 000000000000000000000000a7f87e8d193e29bf1ed050fdd511b79fe0264d8b
Arg [2] : 000000000000000000000000818737eec8a5350756da40d5ddafda8a84ade107
Arg [3] : 00000000000000000000000000000000000000000000000000000000000002bc
Arg [4] : 000000000000000000000000000000000000000000000000000000005f7a6200
Arg [5] : 00000000000000000000000000000000000000000000000000000000000007d0
Arg [6] : 000000000000000000000000cebb9ae52a3d61c4ed1528fba93e5beaaa40e9e2
Arg [7] : 0000000000000000000000009a5be4f89d483e445716dc1abb7668e56deaa909
Arg [8] : 000000000000000000000000596e620e175c2c37a5f35a41d9f2305a991ffc89
Arg [9] : 00000000000000000000000000000000000000000000000000000000000009c4
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [11] : 00000000000000000000000000000000000000000000000000000000000002a0
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [13] : 00000000000000000000000075b09e4ac76b2a9fc104014b1f73ce2dc1344726
Arg [14] : 00000000000000000000000023ba98addef64e1fdbdacee2293cbfd5f3d5e7ab
Arg [15] : 000000000000000000000000d8a2264ba34fecb10e0001b5ffed50bfa7f2c0a9
Arg [16] : 0000000000000000000000002b15bdea3e1f4373607c1e468194e52d7d7c5b35
Arg [17] : 00000000000000000000000094d20a5c9dff08a430e87e60c7ba5918833b72a3
Arg [18] : 000000000000000000000000a9d27dc56c45fb9388ebb27cb0dcce6e4c97eadc
Arg [19] : 0000000000000000000000002c6176e791a07930d86634a9dc191af9fa6251be
Arg [20] : 00000000000000000000000069148554c14e061600109771102d7e329d796df2
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [22] : 000000000000000000000000000000000000000000000000000000000000d6d8
Arg [23] : 000000000000000000000000000000000000000000000000000000000001c138
Arg [24] : 000000000000000000000000000000000000000000000000000000000002ab98
Arg [25] : 00000000000000000000000000000000000000000000000000000000000395f8
Arg [26] : 000000000000000000000000000000000000000000000000000000000000e09c
Arg [27] : 000000000000000000000000000000000000000000000000000000000001cafc
Arg [28] : 000000000000000000000000000000000000000000000000000000000002b55c
Arg [29] : 0000000000000000000000000000000000000000000000000000000000039fbc


Deployed Bytecode Sourcemap

20809:32088:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21796:28;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21796:28:0;;:::i;:::-;;;;-1:-1:-1;;;;;21796:28:0;;;;;;;;;;;;;;21029:30;;;;;;;;;;;;;:::i;27325:360::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27325:360:0;;:::i;:::-;;39301:150;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;21897:26;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21897:26:0;;:::i;28247:308::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28247:308:0;-1:-1:-1;;;;;28247:308:0;;:::i;49998:650::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;49998:650:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;49998:650:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49998:650:0;;;;;;;;-1:-1:-1;49998:650:0;;-1:-1:-1;;;;;49998:650:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;49998:650:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49998:650:0;;-1:-1:-1;49998:650:0;;-1:-1:-1;;;;;49998:650:0:i;21288:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21288:38:0;;:::i;32230:250::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32230:250:0;;:::i;32604:171::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32604:171:0;;;;:::i;22240:56::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22240:56:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21672:30;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21672:30:0;;:::i;:::-;;;;-1:-1:-1;;;;;21672:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51181:375;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;51181:375:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;51181:375:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51181:375:0;;;;;;;;-1:-1:-1;51181:375:0;;-1:-1:-1;;;;;51181:375:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;51181:375:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51181:375:0;;-1:-1:-1;51181:375:0;;-1:-1:-1;;;;;51181:375:0:i;20988:34::-;;;;;;;;;;;;;:::i;21112:31::-;;;;;;;;;;;;;:::i;33132:261::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33132:261:0;;;;;;;;;;;:::i;52413:193::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;52413:193:0;;;;;;;;;;:::i;29799:93::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;30416:1688;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30416:1688:0;;;;;;;;;;;:::i;27693:245::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27693:245:0;;:::i;39499:114::-;;;;;;;;;;;;;:::i;21150:35::-;;;;;;;;;;;;;:::i;39092:148::-;;;;;;;;;;;;;:::i;21751:36::-;;;;;;;;;;;;;:::i;21378:32::-;;;;;;;;;;;;;:::i;21417:34::-;;;;;;;;;;;;;:::i;21192:35::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21192:35:0;;:::i;27946:293::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27946:293:0;-1:-1:-1;;;;;27946:293:0;;:::i;29951:157::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29951:157:0;;;;:::i;32869:179::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32869:179:0;;;;;;;;;;;:::i;51909:308::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51909:308:0;;;;;;;;;;;;;;;-1:-1:-1;;;51909:308:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;51909:308:0;;;;;;;;;;-1:-1:-1;51909:308:0;;-1:-1:-1;51909:308:0;-1:-1:-1;51909:308:0;:::i;33466:172::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33466:172:0;;;;;;;;;;;:::i;48564:532::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48564:532:0;;:::i;21968:34::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21968:34:0;;:::i;29456:121::-;;;;;;;;;;;;;:::i;21333:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21333:38:0;;:::i;22009:36::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22009:36:0;;;;;;;:::i;29329:119::-;;;;;;;;;;;;;:::i;47535:1021::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;47535:1021:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;47535:1021:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47535:1021:0;;;;;;;;-1:-1:-1;47535:1021:0;;-1:-1:-1;;;;;47535:1021:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;47535:1021:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47535:1021:0;;-1:-1:-1;47535:1021:0;;-1:-1:-1;;;;;47535:1021:0:i;45201:104::-;;;;;;;;;;;;;:::i;21709:35::-;;;;;;;;;;;;;:::i;44927:266::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44927:266:0;;:::i;39891:859::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39891:859:0;;;;;;;:::i;21066:37::-;;;;;;;;;;;;;:::i;28563:410::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28563:410:0;-1:-1:-1;;;;;28563:410:0;;:::i;50724:360::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;50724:360:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;50724:360:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50724:360:0;;-1:-1:-1;50724:360:0;;-1:-1:-1;;;;;50724:360:0:i;37227:1805::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37227:1805:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;37227:1805:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;37227:1805:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37227:1805:0;;;;;;;;-1:-1:-1;37227:1805:0;;-1:-1:-1;;;;;37227:1805:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;37227:1805:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37227:1805:0;;-1:-1:-1;37227:1805:0;;-1:-1:-1;;;;;37227:1805:0:i;52722:170::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;52722:170:0;;;;;;;;;;:::i;27012:305::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27012:305:0;;:::i;21930:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21930:31:0;;:::i;34116:2620::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34116:2620:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;34116:2620:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;34116:2620:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34116:2620:0;;;;;;;;-1:-1:-1;34116:2620:0;;-1:-1:-1;;;;;34116:2620:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;34116:2620:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34116:2620:0;;-1:-1:-1;34116:2620:0;;-1:-1:-1;;;;;34116:2620:0:i;28981:340::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28981:340:0;-1:-1:-1;;;;;28981:340:0;;:::i;21796:28::-;;;;;;;;;;;;-1:-1:-1;;;;;21796:28:0;;-1:-1:-1;21796:28:0;:::o;21029:30::-;;;-1:-1:-1;;;;;21029:30:0;;:::o;27325:360::-;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27471:3:::1;27444:24;:30;27436:97;;;;-1:-1:-1::0;;;27436:97:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27572:20;::::0;27549:70:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;27630:20;:47:::0;27325:360::o;39301:150::-;39422:21;;39400:12;:19;:43;39301:150;:::o;21897:26::-;;;;;;;;;;;;;-1:-1:-1;21897:26:0;:::o;28247:308::-;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28366:29:0;::::1;28358:81;;;;-1:-1:-1::0;;;28358:81:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28478:11;::::0;28455:52:::1;::::0;-1:-1:-1;;;;;28455:52:0;;::::1;::::0;28478:11:::1;::::0;28455:52:::1;::::0;28478:11:::1;::::0;28455:52:::1;28518:11;:29:::0;;-1:-1:-1;;;;;;28518:29:0::1;-1:-1:-1::0;;;;;28518:29:0;;;::::1;::::0;;;::::1;::::0;;28247:308::o;49998:650::-;26859:8;:6;:8::i;:::-;:16;;26871:4;26859:16;26851:72;;;;-1:-1:-1;;;26851:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50134:16;;50118:13:::1;50161:409;50185:5;50181:1;:9;50161:409;;;50220:3;::::0;50232:12;;50249:10:::1;::::0;-1:-1:-1;;;;;50220:3:0::1;::::0;:11:::1;::::0;50232:9;;50242:1;;50232:12;::::1;;;;;;;;;;;50220:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;50220:25:0;-1:-1:-1;;;;;50220:39:0::1;;50212:102;;;;-1:-1:-1::0;;;50212:102:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50369:19;50337:14;:28;50352:9;50362:1;50352:12;;;;;;;;;::::0;;::::1;::::0;;;;;;;50337:28;;;::::1;::::0;;;;;;-1:-1:-1;50337:28:0;;::::1;;:51;::::0;::::1;;;;;;;50329:151;;;;-1:-1:-1::0;;;50329:151:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50526:32;50495:14;:28;50510:9;50520:1;50510:12;;;;;;;;;;;;;;50495:28;;;;;;;;;;;;:63;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;50192:3:0::1;;50161:409;;;;50603:10;-1:-1:-1::0;;;;;50585:55:0::1;;50615:9;50626:13;50585:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26934:1;49998:650:::0;;:::o;21288:38::-;;;;;;;;;32230:250;32302:7;32345:20;;32331:10;:34;32327:75;;-1:-1:-1;32389:1:0;32382:8;;32327:75;32457:11;;32443:10;32420:20;;:33;32419:49;;;;;;32471:1;32419:53;32412:60;;32230:250;;;;:::o;32604:171::-;32685:7;32717:50;32763:3;32717:41;32741:6;;;;;;;;;-1:-1:-1;;;;;32741:6:0;-1:-1:-1;;;;;32741:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32741:16:0;32717:19;32730:5;32717:12;:19::i;:::-;:23;:41;:23;:41;:::i;:::-;:45;:50;:45;:50;:::i;:::-;32710:57;32604:171;-1:-1:-1;;32604:171:0:o;22240:56::-;;;;;;;;;;;;;;;:::o;21672:30::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21672:30:0;;;;-1:-1:-1;21672:30:0;;;;;;;;;;;;:::o;51181:375::-;26542:15;;-1:-1:-1;;;;;26542:15:0;26528:10;:29;26520:89;;;;-1:-1:-1;;;26520:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51325:16;;51309:13:::1;51352:197;51376:5;51372:1;:9;51352:197;;;51434:19;51403:14;:28;51418:9;51428:1;51418:12;;;;;;;;;;;;;;51403:28;;;;;;;;;;;;:50;;;;;;;;;;;;;;;;;;;;;;;;51515:9;51525:1;51515:12;;;;;;;;;;;;;;51488:3;::::0;::::1;;;;;;;-1:-1:-1::0;;;;;51488:3:0::1;-1:-1:-1::0;;;;;51488:11:0::1;;51500:9;51510:1;51500:12;;;;;;;;;;;;;;51488:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;51488:25:0;51473:64:::1;::::0;;51488:25:::1;51473:64:::0;;;;;;;::::1;::::0;;;-1:-1:-1;;;;;51473:64:0;;::::1;::::0;::::1;::::0;51529:7;;51473:64;;;;;;;;;::::1;::::0;;;;;::::1;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51383:3;;51352:197;;;;26620:1;51181:375:::0;;:::o;20988:34::-;;;-1:-1:-1;;;;;20988:34:0;;:::o;21112:31::-;;;;:::o;33132:261::-;33236:7;33261:17;33281:29;33294:8;33304:5;33281:12;:29::i;:::-;33261:49;;33328:57;33357:16;33374:9;33357:27;;;;;;;;;33328:13;33342:9;33328:24;;;;;;;;;;:57;:28;:57;:::i;:::-;33321:64;33132:261;-1:-1:-1;;;;33132:261:0:o;52413:193::-;26708:22;;-1:-1:-1;;;;;26708:22:0;26694:10;:36;26686:103;;;;-1:-1:-1;;;26686:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52559:38:::1;::::0;;-1:-1:-1;;;52559:38:0;;52591:4:::1;52559:38;::::0;::::1;::::0;;;-1:-1:-1;;;;;52531:22:0;::::1;::::0;::::1;::::0;52554:3;;52531:22;;52559:23:::1;::::0;:38;;;;;::::1;::::0;;;;;;;;;52531:22;52559:38;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52559:38:0;52531:67:::1;::::0;;-1:-1:-1;;;;;;52531:67:0::1;::::0;;;;;;-1:-1:-1;;;;;52531:67:0;;::::1;;::::0;::::1;::::0;;;;;;;;;;;;;;52559:38:::1;::::0;52531:67;;;;;;;-1:-1:-1;52531:67:0;;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;29799:93:::0;29877:7;;;;29799:93;:::o;30416:1688::-;30529:7;30554:15;30572:16;30584:3;30572:11;:16::i;:::-;30554:34;;30599:15;30625:5;30617:14;;;;;;;;30599:32;;30646:17;30664:7;30646:26;;;;;;;;;:31;;:47;;-1:-1:-1;30681:12:0;;30646:47;30642:201;;;30815:16;;30808:23;;;;;;30642:201;30853:20;30876:39;30888:17;30906:7;30888:26;;;;;;;;;30876:11;:39::i;:::-;30853:62;;30930:14;30926:236;;;31066:12;31055:7;:23;31051:100;;;31106:20;31127:7;31106:29;;;;;;;;;31099:36;;;;;;;31051:100;31442:21;31520:9;31498:19;;31466:20;31487:7;31466:29;;;;;;;;;:51;:63;;;;;;31442:87;;31885:21;32005:12;31994:7;31979:12;:22;31958:16;;31942:13;31910:20;31931:7;31910:29;;;;;;;;;:45;:64;31909:93;:108;;;;;;31885:132;;32083:13;32067;32035:20;32056:7;32035:29;;;;;;;;;:45;:61;;30416:1688;-1:-1:-1;;;;;;;;30416:1688:0:o;27693:245::-;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27829:19:::1;::::0;27807:67:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;27885:19;:45:::0;27693:245::o;39499:114::-;39586:12;:19;39499:114;:::o;21150:35::-;;;;:::o;39092:148::-;39212:20;;39190:12;:19;:42;39092:148;:::o;21751:36::-;;;;:::o;21378:32::-;;;;:::o;21417:34::-;;;;:::o;21192:35::-;;;;;;;;;27946:293;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28048:35:0;::::1;28040:94;;;;-1:-1:-1::0;;;28040:94:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28172:6;::::0;28150:51:::1;::::0;-1:-1:-1;;;;;28150:51:0;;::::1;::::0;28172:6:::1;::::0;28150:51:::1;::::0;28172:6:::1;::::0;28150:51:::1;28212:6;:19:::0;;-1:-1:-1;;;;;;28212:19:0::1;-1:-1:-1::0;;;;;28212:19:0;;;::::1;::::0;;;::::1;::::0;;27946:293::o;29951:157::-;30036:7;30068:32;30088:4;30094:5;30068:19;:32::i;32869:179::-;32971:7;33034:5;33026:14;;;;;;;;33004:10;:18;;33021:1;33004:18;;;33017:1;33004:18;33003:37;;;;32869:179;-1:-1:-1;;;32869:179:0:o;51909:308::-;26708:22;;-1:-1:-1;;;;;26708:22:0;26694:10;:36;26686:103;;;;-1:-1:-1;;;26686:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52064:38:0;::::1;52056:81;;;::::0;;-1:-1:-1;;;52056:81:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;52148:61;::::0;-1:-1:-1;;;52148:61:0;;::::1;;::::0;::::1;::::0;;;;;;;;;-1:-1:-1;;;;;52148:54:0;::::1;::::0;::::1;::::0;52203:5;;;;52148:61;;;;;52203:5;;;;52148:61;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;;;;;51909:308:0:o;33466:172::-;33563:4;33592:33;33609:8;33619:5;33592:16;:33::i;:::-;:38;;33466:172;-1:-1:-1;;;33466:172:0:o;48564:532::-;48648:9;48643:446;48667:9;48663:1;:13;48643:446;;;48726:20;;48702:21;;:44;48698:380;;;48784:21;;48767:14;48948:3;48959:12;:20;;-1:-1:-1;;;;;48948:3:0;;;;:10;;48959:12;48784:21;;48959:20;;;;;;;;;;;;;;;;:28;;;48948:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48948:40:0;48944:119;;;49013:30;49036:6;49013:22;:30::i;:::-;48698:380;;48678:3;;48643:446;;;;48564:532;:::o;21968:34::-;;;;;;;;;29456:121;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29526:7:::1;:15:::0;;-1:-1:-1;;29526:15:0::1;::::0;;29557:12:::1;::::0;::::1;::::0;29536:5:::1;::::0;29557:12:::1;29456:121::o:0;21333:38::-;;;;;;;;;22009:36;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22009:36:0;;-1:-1:-1;22009:36:0:o;29329:119::-;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29398:7:::1;:14:::0;;-1:-1:-1;;29398:14:0::1;29408:4;29398:14;::::0;;29428:12:::1;::::0;::::1;::::0;29398:7:::1;::::0;29428:12:::1;29329:119::o:0;47535:1021::-;47688:16;;47723:9;47715:49;;;;;-1:-1:-1;;;47715:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47815:5;47783:22;:29;:37;;;;;;:42;47775:93;;;;-1:-1:-1;;;47775:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47879:25;47939:5;47907:22;:29;:37;;;;;;;-1:-1:-1;48002:9:0;47997:552;48021:5;48017:1;:9;47997:552;;;48048:15;48090:3;48074:9;48084:1;48074:12;;;;;;;;;;;;;;;;;;;48066:28;48173:3;:19;;;-1:-1:-1;;;48173:19:0;;48074;;;;48173;;;;;;;;48074;;-1:-1:-1;;;;;;48173:3:0;;:10;;:19;;;;;48074:12;;48173:19;;;;;;:3;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48173:19:0;48168:370;;48213:28;48258:17;48244:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48244:32:0;-1:-1:-1;48213:63:0;-1:-1:-1;48300:9:0;48295:163;48319:17;48315:1;:21;48295:163;;;48383:22;48406:31;48435:1;48406:24;:17;48428:1;48406:24;:21;:24;:::i;:::-;:28;:31;:28;:31;:::i;:::-;48383:55;;;;;;;;;;;;;;48366:11;48378:1;48366:14;;;;;;;;;;;;;;;;;:72;48338:3;;48295:163;;;-1:-1:-1;48476:3:0;;48496:12;;-1:-1:-1;;;;;48476:3:0;;;;:19;;48496:9;;48506:1;;48496:12;;;;;;;;;;;;48510:11;48476:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;48168:370:0;-1:-1:-1;48028:3:0;;47997:552;;45201:104;45266:31;45292:4;45266:25;:31::i;:::-;45201:104::o;21709:35::-;;;;:::o;44927:266::-;45010:9;45005:181;45029:9;45025:1;:13;45005:181;;;45087:12;:19;45064:20;;:42;45060:115;;;45127:32;45153:5;45127:25;:32::i;:::-;45040:3;;45005:181;;39891:859;39998:7;40046:20;;40027:15;:39;40023:230;;40152:14;40169:22;:15;40189:1;40169:22;:19;:22;:::i;:::-;40152:39;;40213:12;40226:6;40213:20;;;;;;;;;;;;;;;;;;:28;;;40206:35;;;;;40023:230;40347:17;40375;40426:27;40451:1;40426:20;;:24;;:27;;;;:::i;:::-;40407:15;:46;40403:278;;;40495:45;40522:17;40495:26;:45::i;:::-;40470:70;;-1:-1:-1;40470:70:0;-1:-1:-1;40403:278:0;;;40607:62;40634:15;40651:17;40607:26;:62::i;:::-;40582:87;;-1:-1:-1;40582:87:0;-1:-1:-1;40403:278:0;40698:44;40721:9;40732;40698:22;:44::i;:::-;40691:51;39891:859;-1:-1:-1;;;;;39891:859:0:o;21066:37::-;;;-1:-1:-1;;;;;21066:37:0;;:::o;28563:410::-;26708:22;;-1:-1:-1;;;;;26708:22:0;26694:10;:36;26686:103;;;;-1:-1:-1;;;26686:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28707:40:0;::::1;28699:103;;;;-1:-1:-1::0;;;28699:103:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28852:22;::::0;28818:85:::1;::::0;-1:-1:-1;;;;;28818:85:0;;::::1;::::0;28852:22:::1;::::0;28818:85:::1;::::0;28852:22:::1;::::0;28818:85:::1;28914:22;:51:::0;;-1:-1:-1;;;;;;28914:51:0::1;-1:-1:-1::0;;;;;28914:51:0;;;::::1;::::0;;;::::1;::::0;;28563:410::o;50724:360::-;26542:15;;-1:-1:-1;;;;;26542:15:0;26528:10;:29;26520:89;;;;-1:-1:-1;;;26520:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50846:16;;50830:13:::1;50873:204;50897:5;50893:1;:9;50873:204;;;50955:32;50924:14;:28;50939:9;50949:1;50939:12;;;;;;;;;;;;;;50924:28;;;;;;;;;;;;:63;;;;;;;;;;;;;;;;;;;;;;;;51052:9;51062:1;51052:12;;;;;;;;;;;;;;51025:3;::::0;::::1;;;;;;;-1:-1:-1::0;;;;;51025:3:0::1;-1:-1:-1::0;;;;;51025:11:0::1;;51037:9;51047:1;51037:12;;;;;;;;;;;;;;51025:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;51025:25:0;51007:58:::1;::::0;-1:-1:-1;;;;;51007:58:0;;::::1;::::0;::::1;::::0;;;::::1;50904:3;;50873:204;;;;26620:1;50724:360:::0;:::o;37227:1805::-;26859:8;:6;:8::i;:::-;:16;;26871:4;26859:16;26851:72;;;;-1:-1:-1;;;26851:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37445:16;;:20;37441:118:::1;;37482:65;37513:9;37524:22;37482:30;:65::i;:::-;37586:4;37620:34;37586:4:::0;37648:5;37620:16:::1;:34::i;:::-;37609:7;:45;;37601:105;;;;-1:-1:-1::0;;;37601:105:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37717:15;37743:5;37735:14;;;;;;;;37768:10;::::0;:41:::1;::::0;;-1:-1:-1;;;37768:41:0;;37789:10:::1;37768:41;::::0;::::1;::::0;;;;;;;;;37717:32;;-1:-1:-1;37813:7:0;;-1:-1:-1;;;;;37768:10:0;;::::1;::::0;:20:::1;::::0;:41;;;;;::::1;::::0;;;;;;;;;:10;:41;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;37768:41:0;:52:::1;;37760:136;;;;-1:-1:-1::0;;;37760:136:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37991:36;::::0;;38025:1:::1;37991:36:::0;;;;;::::1;::::0;;;37940:48:::1;::::0;37991:36:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;38071:16:0::1;::::0;;38085:1:::1;38071:16:::0;;;;;::::1;::::0;;;37940:87;;-1:-1:-1;38038:30:0::1;::::0;38071:16;-1:-1:-1;38071:16:0::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;38071:16:0::1;38038:49;;38143:7;38115:36;;;;;;;;38098:11;38110:1;38098:14;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;;;;::::0;::::1;38181:7;38162:13;38176:1;38162:16;;;;;;;;;::::0;;::::1;::::0;;;;;;:26;;;;38199:10:::1;::::0;:62:::1;::::0;-1:-1:-1;;;38199:62:0;;38222:10:::1;38199:62;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38199:10:0;;::::1;::::0;:22:::1;::::0;38222:10;;38234:11;;38247:13;;38199:62;;;;;;;;;;;::::1;::::0;::::1;::::0;;;:10:::1;:62;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;38344:9:0::1;::::0;-1:-1:-1;;;38339:309:0::1;38363:7;38359:1;:11;38339:309;;;38467:12;38485:55;;;;;;;;38494:10;-1:-1:-1::0;;;;;38485:55:0::1;;;;;38506:12;38485:55;;;;38520:1;38485:55;;;;38523:9;38485:55;;;;;;38534:5;38485:55;;;;;;;;::::0;;38467:74;;::::1;::::0;;::::1;::::0;;-1:-1:-1;38467:74:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;-1:-1:-1;;;;;;38467:74:0::1;-1:-1:-1::0;;;;;38467:74:0;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;-1:-1:-1;;38467:74:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;;38467:74:0;;::::1;::::0;::::1;::::0;;;;::::1;;;;;;;;;;;;;38606:5;38561:75;;;;;;;;38613:12;:19:::0;38561:75:::1;::::0;;-1:-1:-1;;;;;38561:75:0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;38634:1:::1;38561:75:::0;;;;;;::::1;;::::0;38571:10:::1;::::0;38561:75:::1;::::0;;;;;;;::::1;38372:3;;38339:309;;;;38658:17;38678:30;38691:9;38702:5;38678:12;:30::i;:::-;38658:50;;38749:40;38781:7;38749:16;38766:9;38749:27;;;;;;;;::::0;;:40:::1;:31;:40;:::i;:::-;38719:16;38736:9;38719:27;;;;;;;;:70:::0;38868:34:::1;38900:1;38890:11:::0;::::1;38868:21;:34::i;:::-;38989:35;39012:7;39022:1;39012:11;38989:22;:35::i;:::-;26934:1;;;;;37227:1805:::0;;;;;:::o;52722:170::-;26708:22;;-1:-1:-1;;;;;26708:22:0;26694:10;:36;26686:103;;;;-1:-1:-1;;;26686:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52844:40:::1;::::0;;-1:-1:-1;;;52844:40:0;;-1:-1:-1;;;;;52844:40:0;;::::1;;::::0;::::1;::::0;52879:4:::1;52844:40:::0;;;;;;:29;;::::1;::::0;::::1;::::0;:40;;;;;-1:-1:-1;;52844:40:0;;;;;;;;-1:-1:-1;52844:29:0;:40;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;52722:170:::0;;:::o;27012:305::-;26381:11;;-1:-1:-1;;;;;26381:11:0;26367:10;:25;26359:91;;;;-1:-1:-1;;;26359:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27144:1:::1;27121:20;:24;27113:74;;;;-1:-1:-1::0;;;27113:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27220:16;::::0;27203:56:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;27270:16;:39:::0;27012:305::o;21930:31::-;;;;;;;;;34116:2620;26859:8;:6;:8::i;:::-;:16;;26871:4;26859:16;26851:72;;;;-1:-1:-1;;;26851:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34332:16;;:20;34328:118:::1;;34369:65;34400:9;34411:22;34369:30;:65::i;:::-;34456:14;34508:34;34456:14:::0;34536:5;34508:16:::1;:34::i;:::-;34497:7;:45;;34489:105;;;;-1:-1:-1::0;;;34489:105:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34605:19;34627:15;34636:5;34627:8;:15::i;:::-;34605:37:::0;-1:-1:-1;34653:17:0::1;34673:24;:7:::0;34605:37;34673:24:::1;:11;:24;:::i;:::-;34653:44;;34729:9;34716;:22;;34708:96;;;;-1:-1:-1::0;;;34708:96:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34815:15;34841:5;34833:14;;;;;;;;34815:32;;34862:17;34880:7;34862:26;;;;;;;;::::0;:31;;:94:::1;;;34917:39;34929:17;34947:7;34929:26;;;;;;34917:39;34897:16;34909:3;34897:11;:16::i;:::-;:59;;34862:94;34858:297;;;35124:19;35137:5;35124:12;:19::i;:::-;35092:20;35113:7;35092:29;;;;;;;;:51:::0;34858:297:::1;35360:11;::::0;:38:::1;::::0;35317:16:::1;::::0;-1:-1:-1;;;;;35360:11:0::1;::::0;35384:9;;35317:16;35360:38;35317:16;35360:38;35384:9;35360:11;:38:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35316:82;;;35414:11;35409:58;;35429:35;::::0;;-1:-1:-1;;;35429:35:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;35409:58;35482:9;35477:550;35501:7;35497:1;:11;35477:550;;;35605:12;35623:55;;;;;;;;35632:10;-1:-1:-1::0;;;;;35623:55:0::1;;;;;35644:12;35623:55;;;;35658:1;35623:55;;;;35661:9;35623:55;;;;;;35672:5;35623:55;;;;;;;;::::0;;35605:74;;::::1;::::0;;::::1;::::0;;-1:-1:-1;35605:74:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;-1:-1:-1;;;;;;35605:74:0::1;-1:-1:-1::0;;;;;35605:74:0;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;-1:-1:-1;;35605:74:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;;35605:74:0;;::::1;::::0;::::1;::::0;;;;::::1;;;;;;;;;;;;;35744:5;35699:85;;;;;;;;35751:12;:19:::0;35699:85:::1;::::0;;-1:-1:-1;;;;;35699:85:0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;;;::::1;;::::0;35709:10:::1;::::0;35699:85:::1;::::0;;;;;;;::::1;35935:33;35955:5;35962;35935:19;:33::i;:::-;35903:20;35924:7;35903:29;;;;;;;;:65:::0;36012:3:::1;35983:17;36001:7:::0;35983:26:::1;::::0;::::1;;;;;;:32:::0;35510:3:::1;;35477:550;;;;36037:17;36057:30;36070:9;36081:5;36057:12;:30::i;:::-;36037:50;;36128:40;36160:7;36128:16;36145:9;36128:27;;;;;;:40;36098:16;36115:9;36098:27;;;;;;;;:70:::0;36247:34:::1;36279:1;36269:11:::0;::::1;36247:21;:34::i;:::-;36368:35;36391:7;36401:1;36391:11;36368:22;:35::i;:::-;36518:9;36506;:21;36502:227;;;36545:18;36590:10;36613:24;:9;36627::::0;36613:24:::1;:13;:24;:::i;:::-;36590:52;::::0;::::1;::::0;;;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36544:98;;;36662:13;36657:61;;36679:36;::::0;;-1:-1:-1;;;36679:36:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;36657:61;36502:227;;26934:1;;;;;;34116:2620:::0;;;;;:::o;28981:340::-;26542:15;;-1:-1:-1;;;;;26542:15:0;26528:10;:29;26520:89;;;;-1:-1:-1;;;26520:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;29104:33:0;::::1;29096:89;;;;-1:-1:-1::0;;;29096:89:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29228:15;::::0;29201:64:::1;::::0;-1:-1:-1;;;;;29201:64:0;;::::1;::::0;29228:15:::1;::::0;29201:64:::1;::::0;29228:15:::1;::::0;29201:64:::1;29276:15;:37:::0;;-1:-1:-1;;;;;;29276:37:0::1;-1:-1:-1::0;;;;;29276:37:0;;;::::1;::::0;;;::::1;::::0;;28981:340::o;2555:471::-;2613:7;2858:6;2854:47;;-1:-1:-1;2888:1:0;2881:8;;2854:47;2925:5;;;2929:1;2925;:5;:1;2949:5;;;;;:10;2941:56;;;;-1:-1:-1;;;2941:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3017:1;2555:471;-1:-1:-1;;;2555:471:0:o;3494:132::-;3552:7;3579:39;3583:1;3586;3579:39;;;;;;;;;;;;;;;;;:3;:39::i;1681:136::-;1739:7;1766:43;1770:1;1773;1766:43;;;;;;;;;;;;;;;;;:3;:43::i;49104:683::-;49182:17;49202:70;49215:12;49228:6;49215:20;;;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;49245:12;49258:6;49245:20;;;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;49202:12;:70::i;:::-;49182:90;;49336:10;49347:9;49336:21;;;;;;;;;;49291:3;49303:12;:20;;-1:-1:-1;;;;;49336:21:0;;;;49291:3;;;;:11;;49303:12;49316:6;;49303:20;;;;;;;;;;;;;;;;:28;;;49291:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49291:41:0;-1:-1:-1;;;;;49291:66:0;;49283:114;;;;-1:-1:-1;;;49283:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49495:3;;-1:-1:-1;;;;;49495:3:0;:20;49516:10;49527:9;49516:21;;;;;;;;;49539:12;:20;;-1:-1:-1;;;;;49516:21:0;;;;49552:6;;49539:20;;;;;;;;;;;;;;;;;;;:30;49571:12;:20;;-1:-1:-1;;;;;49539:30:0;;;;49584:6;;49571:20;;;;;;;;;;;;;;;;:28;;;49495:105;;;;;;;;;;;;;-1:-1:-1;;;;;49495:105:0;-1:-1:-1;;;;;49495:105:0;;;;;;-1:-1:-1;;;;;49495:105:0;-1:-1:-1;;;;;49495:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49669:12;49682:6;49669:20;;;;;;;;;;;;;;;;;;;;;:30;49639:12;:20;;-1:-1:-1;;;;;49669:30:0;;;;49652:6;;49639:20;;;;;;;;;;;;;:28;:20;;;;;:28;;49616:84;;49639:28;;49616:84;;;49735:13;:6;49746:1;49735:13;:10;:13;:::i;:::-;49711:21;:37;-1:-1:-1;;49104:683:0:o;1225:181::-;1283:7;1315:5;;;1339:6;;;;1331:46;;;;;-1:-1:-1;;;1331:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;45313:2122;45432:20;;45403:26;;45432:27;;45457:1;45432:27;:24;:27;:::i;:::-;45403:56;-1:-1:-1;45524:14:0;45541:25;45403:56;45564:1;45541:25;:22;:25;:::i;:::-;45524:42;;45616:12;45581;45594:6;45581:20;;;;;;;;;;;;;;;;;;:32;;;:47;45577:1851;;;45720:17;45739;45760:39;45787:11;45760:26;:39::i;:::-;45719:80;;;;45814:15;45832:44;45855:9;45866;45832:22;:44::i;:::-;45814:62;;45922:7;45891:12;45904:6;45891:20;;;;;;;;;;;;;;;;;;:28;;:38;;;;45995:7;45963:12;45976:6;45963:20;;;;;;;;;;;;;;;;;;;;;;:30;45949:74;;;;;;;;-1:-1:-1;;;;;45963:30:0;;;;45949:74;;;;;;;;;46067:20;;46042:21;;:45;:68;;;;-1:-1:-1;46091:3:0;;:19;;;-1:-1:-1;;;46091:19:0;;;;;;;;;;-1:-1:-1;;;;;46091:3:0;;;;:10;;:19;;;;;;;;;;;;;;;:3;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46091:19:0;46042:68;46038:232;;;46224:30;46247:6;46224:22;:30::i;:::-;46343:21;46367:31;46396:1;46367:13;46381:9;46367:24;;;;;;:31;46343:55;;46430:13;46417:9;:26;46413:504;;46561:17;46581:12;46594:9;46581:23;;;;;;;;;;46605:13;46581:38;;;;;;;;;;-1:-1:-1;46642:14:0;46638:199;;46804:13;46782:8;46791:9;46782:19;;;;;;;;;:35;46770:47;;46638:199;46892:9;46855:12;46868:9;46855:23;;;;;;;;;;46879:9;46855:34;;;;;;;;:46;-1:-1:-1;46413:504:0;46958:31;46987:1;46958:13;46972:9;46958:24;;;;;;:31;46931:13;46945:9;46931:24;;;;;;;;:58;47034:34;47066:1;47034:16;47051:9;47034:27;;;;;;:34;47004:16;47021:9;47004:27;;;;;;;;:64;-1:-1:-1;47166:23:0;;;;:14;:23;;;;;:45;;-1:-1:-1;;47166:45:0;47192:19;47166:45;;;-1:-1:-1;;47226:20:0;:41;;;45577:1851;;;47313:18;47309:108;;;47352:49;;-1:-1:-1;;;47352:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42349:470;42445:7;42454;42479:14;42496:20;;42479:37;;42574:17;42594:70;42607:12;42620:6;42607:20;;;;;;;42594:70;42574:90;;42675:17;42695:76;42719:6;42727:13;42741:9;42727:24;;;;;;;;;42753:17;42695:23;:76::i;:::-;42790:9;;-1:-1:-1;42675:96:0;;-1:-1:-1;;;42349:470:0;;;:::o;43033:1822::-;43154:7;43163;43214:20;;43196:15;:38;43188:82;;;;;-1:-1:-1;;;43188:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43308:12;:19;43289:38;;;43281:83;;;;;-1:-1:-1;;;43281:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43375:13;43391:41;43411:20;;43391:15;:19;;:41;;;;:::i;:::-;43375:57;;43443:26;43486:5;43472:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43472:20:0;;43443:49;;43503:26;43546:5;43532:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43532:20:0;;43503:49;;43563:29;43609:5;43595:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43595:20:0;-1:-1:-1;43663:35:0;;;43677:20;43663:35;;;;;;;;;43563:52;;-1:-1:-1;43626:34:0;;43663:35;;;;;;;;;;;-1:-1:-1;;43626:72:0;-1:-1:-1;43714:9:0;43709:1071;43733:5;43729:1;:9;43709:1071;;;43777:20;;43760:14;;43777:27;;43802:1;43777:27;:24;:27;:::i;:::-;43760:44;;43896:70;43909:12;43922:6;43909:20;;;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;43939:12;43952:6;43939:20;;;;;;;43896:70;43881:9;43891:1;43881:12;;;;;;;;;;;;;:85;;;;;43981:20;44004:64;44036:17;44054:9;44064:1;44054:12;;;;;;;;;;;;;;44036:31;;;;;;;;;;;;;;44004:13;44018:9;44028:1;44018:12;;;;;;;;;;;;;;44004:27;;;;;;:64;43981:87;;44098:64;44122:6;44130:12;44144:17;44098:23;:64::i;:::-;44083:9;44093:1;44083:12;;;;;;;;;;;;;;;;;:79;44252:15;44247:305;44283:1;44273:7;:11;44247:305;;;44321:9;44316:221;44340:1;44336;:5;44316:221;;;44391:9;44401:1;44391:12;;;;;;;;;;;;;;44375:9;44385:1;44375:12;;;;;;;;;;;;;;:28;:60;;;;;44423:9;44433:1;44423:12;;;;;;;;;;;;;;44407:9;44417:1;44407:12;;;;;;;;;;;;;;:28;44375:60;44371:147;;;44479:12;44492:1;44479:15;;;;;;;;;;;;;;44464:9;44474:1;44464:12;;;;;;;;;;;;;:30;;;;;44371:147;44343:3;;44316:221;;;-1:-1:-1;44286:9:0;;44247:305;;;-1:-1:-1;44662:19:0;:12;44679:1;44662:19;:16;:19;:::i;:::-;44644:12;44657:1;44644:15;;;;;;;;;;;;;:37;;;;;44730:38;44766:1;44730:17;44748:9;44758:1;44748:12;;;;;;;;;;;;;;44730:31;;;;;;;;;;;;;;:35;;:38;;;;:::i;:::-;44696:17;44714:9;44724:1;44714:12;;;;;;;;;;;;;;44696:31;;;;;;;;;;;;;;;;;:72;-1:-1:-1;;43740:3:0;;43709:1071;;;-1:-1:-1;44798:9:0;44808:12;:5;44818:1;44808:12;:9;:12;:::i;:::-;44798:23;;;;;;;;;;;;;;44823:9;44833:12;44843:1;44833:5;:9;;:12;;;;:::i;:::-;44823:23;;;;;;;;;;;;;;44790:57;;;;;;;;;43033:1822;;;;;:::o;40849:414::-;40954:7;40979:15;40997:12;41010:10;40997:24;;;;;;;;;;41022:10;40997:36;;;;;;;;;;-1:-1:-1;41048:12:0;41044:187;;41183:36;41208:10;41183:8;41192:10;41183:20;;;;;;4114:345;4200:7;4302:12;4295:5;4287:28;;;;-1:-1:-1;;;4287:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4326:9;4342:1;4338;:5;;;;;;;4114:345;-1:-1:-1;;;;;4114:345:0:o;2112:192::-;2198:7;2234:12;2226:6;;;;2218:29;;;;-1:-1:-1;;;2218:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2270:5:0;;;2112:192::o;41363:869::-;41490:7;41657:13;41721:12;41685;41698:6;41685:20;;;;;;;;;;;;;;;;;;:32;;;:48;41681:464;;;41756:32;41748:110;;;;-1:-1:-1;;;41748:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41879:17:0;41681:464;;;41942:3;41927:12;:18;:79;;;-1:-1:-1;41985:21:0;:12;42002:3;41985:21;:16;:21;:::i;:::-;41949:12;41962:6;41949:20;;;;;;;;;;;;;;;;;;:32;;;:57;;41927:79;41923:222;;;42039:12;42052:6;42039:20;;;;;;;;;;;;;;;;;;:32;;;42029:43;42021:51;;41923:222;;;-1:-1:-1;42120:13:0;41923:222;42180:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42170:42;;;;;42216:8;;;42162:62;;;;;;41363:869;-1:-1:-1;;;;;41363:869:0:o

Swarm Source

ipfs://675293a428cc64fcef06eb856578527f12f5baf480f751a59c24ff72a712cac0

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.