ETH Price: $2,629.49 (-0.88%)

 

Overview

TokenID

1390073197418994709285271386017172281782...

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
ZeroXTrade

Compiler Version
v0.5.15+commit.6a57276f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 2 : ZeroXTrade.sol
pragma experimental ABIEncoderV2;
pragma solidity 0.5.15;

contract IAugur {
    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function isKnownUniverse(IUniverse _universe) public view returns (bool);
    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool);
    function isTrustedSender(address _address) public returns (bool);
    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool);
    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool);
    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool);
    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool);
    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool);
    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool);
    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool);
    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool);
    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool);
    function logUniverseForked(IMarket _forkingMarket) public returns (bool);
    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool);
    function logParticipationTokensRedeemed(IUniverse universe, address _sender, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool);
    function logTimestampSet(uint256 _newTimestamp) public returns (bool);
    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool);
    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool);
    function isKnownFeeSender(address _feeSender) public view returns (bool);
    function lookup(bytes32 _key) public view returns (address);
    function getTimestamp() public view returns (uint256);
    function getMaximumMarketEndDate() public returns (uint256);
    function isKnownMarket(IMarket _market) public view returns (bool);
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 numOutcomes) public view returns (bytes32);
    function logValidityBondChanged(uint256 _validityBond) public returns (bool);
    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool);
    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool);
    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool);
    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256);
}

contract IAugurCreationDataGetter {
    struct MarketCreationData {
        string extraInfo;
        address marketCreator;
        bytes32[] outcomes;
        int256[] displayPrices;
        IMarket.MarketType marketType;
        uint256 recommendedTradeInterval;
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory);
}

contract IAugurMarketDataGetter {
    function getMarketType(IMarket _market) public view returns (IMarket.MarketType _marketType);
    function getMarketOutcomes(IMarket _market) public view returns (bytes32[] memory _outcomes);
    function getMarketRecommendedTradeInterval(IMarket _market) public view returns (uint256);
}

contract IExchange {

    struct FillResults {
        uint256 makerAssetFilledAmount;  // Total amount of makerAsset(s) filled.
        uint256 takerAssetFilledAmount;  // Total amount of takerAsset(s) filled.
        uint256 makerFeePaid;            // Total amount of fees paid by maker(s) to feeRecipient(s).
        uint256 takerFeePaid;            // Total amount of fees paid by taker to feeRecipients(s).
        uint256 protocolFeePaid;         // Total amount of fees paid by taker to the staking contract.
    }

    struct OrderInfo {
        uint8 orderStatus;                    // Status that describes order's validity and fillability.
        bytes32 orderHash;                    // EIP712 hash of the order (see LibOrder.getOrderHash).
        uint256 orderTakerAssetFilledAmount;  // Amount of order that has already been filled.
    }

    // solhint-disable max-line-length
    struct Order {
        address makerAddress;           // Address that created the order.
        address takerAddress;           // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.
        address feeRecipientAddress;    // Address that will recieve fees when order is filled.
        address senderAddress;          // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.
        uint256 makerAssetAmount;       // Amount of makerAsset being offered by maker. Must be greater than 0.
        uint256 takerAssetAmount;       // Amount of takerAsset being bid on by maker. Must be greater than 0.
        uint256 makerFee;               // Fee paid to feeRecipient by maker when order is filled.
        uint256 takerFee;               // Fee paid to feeRecipient by taker when order is filled.
        uint256 expirationTimeSeconds;  // Timestamp in seconds at which order expires.
        uint256 salt;                   // Arbitrary number to facilitate uniqueness of the order's hash.
        bytes makerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The leading bytes4 references the id of the asset proxy.
        bytes takerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The leading bytes4 references the id of the asset proxy.
        bytes makerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring makerFeeAsset. The leading bytes4 references the id of the asset proxy.
        bytes takerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring takerFeeAsset. The leading bytes4 references the id of the asset proxy.
    }
    // solhint-enable max-line-length

    function protocolFeeMultiplier() external view returns (uint256);

    /// @dev Gets information about an order: status, hash, and amount filled.
    /// @param order Order to gather information on.
    /// @return OrderInfo Information about the order and its state.
    ///         See LibOrder.OrderInfo for a complete description.
    function getOrderInfo(Order memory order) public view returns (OrderInfo memory orderInfo);

    /// @dev Fills the input order.
    /// @param order Order struct containing order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signature Proof that order has been created by maker.
    /// @return Amounts filled and fees paid by maker and taker.
    function fillOrder(Order memory order, uint256 takerAssetFillAmount, bytes memory signature) public payable returns (FillResults memory fillResults);
}

library ContractExists {
    function exists(address _address) internal view returns (bool) {
        uint256 size;
        assembly { size := extcodesize(_address) }
        return size > 0;
    }
}

contract IOwnable {
    function getOwner() public view returns (address);
    function transferOwnership(address _newOwner) public returns (bool);
}

contract ITyped {
    function getTypeName() public view returns (bytes32);
}

contract Initializable {
    bool private initialized = false;

    modifier beforeInitialized {
        require(!initialized);
        _;
    }

    function endInitialization() internal beforeInitialized {
        initialized = true;
    }

    function getInitialized() public view returns (bool) {
        return initialized;
    }
}

library LibBytes {

    using LibBytes for bytes;

    /// @dev Tests equality of two byte arrays.
    /// @param lhs First byte array to compare.
    /// @param rhs Second byte array to compare.
    /// @return True if arrays are the same. False otherwise.
    function equals(
        bytes memory lhs,
        bytes memory rhs
    )
        internal
        pure
        returns (bool equal)
    {
        // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.
        // We early exit on unequal lengths, but keccak would also correctly
        // handle this.
        return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);
    }

    /// @dev Gets the memory address for the contents of a byte array.
    /// @param input Byte array to lookup.
    /// @return memoryAddress Memory address of the contents of the byte array.
    function contentAddress(bytes memory input)
        internal
        pure
        returns (uint256 memoryAddress)
    {
        assembly {
            memoryAddress := add(input, 32)
        }
        return memoryAddress;
    }

    /// @dev Copies `length` bytes from memory location `source` to `dest`.
    /// @param dest memory address to copy bytes to.
    /// @param source memory address to copy bytes from.
    /// @param length number of bytes to copy.
    function memCopy(
        uint256 dest,
        uint256 source,
        uint256 length
    )
        internal
        pure
    {
        if (length < 32) {
            // Handle a partial word by reading destination and masking
            // off the bits we are interested in.
            // This correctly handles overlap, zero lengths and source == dest
            assembly {
                let mask := sub(exp(256, sub(32, length)), 1)
                let s := and(mload(source), not(mask))
                let d := and(mload(dest), mask)
                mstore(dest, or(s, d))
            }
        } else {
            // Skip the O(length) loop when source == dest.
            if (source == dest) {
                return;
            }

            // For large copies we copy whole words at a time. The final
            // word is aligned to the end of the range (instead of after the
            // previous) to handle partial words. So a copy will look like this:
            //
            //  ####
            //      ####
            //          ####
            //            ####
            //
            // We handle overlap in the source and destination range by
            // changing the copying direction. This prevents us from
            // overwriting parts of source that we still need to copy.
            //
            // This correctly handles source == dest
            //
            if (source > dest) {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because it
                    // is easier to compare with in the loop, and these
                    // are also the addresses we need for copying the
                    // last bytes.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the last 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the last bytes in
                    // source already due to overlap.
                    let last := mload(sEnd)

                    // Copy whole words front to back
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} lt(source, sEnd) {} {
                        mstore(dest, mload(source))
                        source := add(source, 32)
                        dest := add(dest, 32)
                    }

                    // Write the last 32 bytes
                    mstore(dEnd, last)
                }
            } else {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because those
                    // are the starting points when copying a word at the end.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the first 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the first bytes in
                    // source already due to overlap.
                    let first := mload(source)

                    // Copy whole words back to front
                    // We use a signed comparisson here to allow dEnd to become
                    // negative (happens when source and dest < 32). Valid
                    // addresses in local memory will never be larger than
                    // 2**255, so they can be safely re-interpreted as signed.
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} slt(dest, dEnd) {} {
                        mstore(dEnd, mload(sEnd))
                        sEnd := sub(sEnd, 32)
                        dEnd := sub(dEnd, 32)
                    }

                    // Write the first 32 bytes
                    mstore(dest, first)
                }
            }
        }
    }

    /// @dev Returns a slices from a byte array.
    /// @param b The byte array to take a slice from.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    function slice(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            revert();
        }
        if (to > b.length) {
            revert();
        }

        // Create a new bytes structure and copy contents
        result = new bytes(to - from);
        memCopy(
            result.contentAddress(),
            b.contentAddress() + from,
            result.length
        );
        return result;
    }

    /// @dev Returns a slice from a byte array without preserving the input.
    /// @param b The byte array to take a slice from. Will be destroyed in the process.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.
    function sliceDestructive(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            revert();
        }
        if (to > b.length) {
            revert();
        }

        // Create a new bytes structure around [from, to) in-place.
        assembly {
            result := add(b, from)
            mstore(result, sub(to, from))
        }
        return result;
    }

    /// @dev Pops the last byte off of a byte array by modifying its length.
    /// @param b Byte array that will be modified.
    /// @return The byte that was popped off.
    function popLastByte(bytes memory b)
        internal
        pure
        returns (bytes1 result)
    {
        if (b.length == 0) {
            revert();
        }

        // Store last byte.
        result = b[b.length - 1];

        assembly {
            // Decrement length of byte array.
            let newLen := sub(mload(b), 1)
            mstore(b, newLen)
        }
        return result;
    }
}

library SafeMathUint256 {
    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-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a <= b) {
            return a;
        } else {
            return b;
        }
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a >= b) {
            return a;
        } else {
            return b;
        }
    }

    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            uint256 x = (y + 1) / 2;
            z = y;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    function getUint256Min() internal pure returns (uint256) {
        return 0;
    }

    function getUint256Max() internal pure returns (uint256) {
        // 2 ** 256 - 1
        return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
    }

    function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
        return a % b == 0;
    }

    // Float [fixed point] Operations
    function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, b), base);
    }

    function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, base), b);
    }
}

interface IERC1155 {

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    /// Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    ///Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /// @dev MUST emit when an approval is updated.
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    /// @dev MUST emit when the URI is updated for a token ID.
    /// URIs are defined in RFC 3986.
    /// The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema".
    event URI(
        string value,
        uint256 indexed id
    );

    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external;

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if length of `_ids` is not the same as length of `_values`.
    ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external;

    /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
    /// @dev MUST emit the ApprovalForAll event on success.
    /// @param operator  Address to add to the set of authorized operators
    /// @param approved  True if the operator is approved, false to revoke approval
    function setApprovalForAll(address operator, bool approved) external;

    /// @notice Queries the approval status of an operator for a given owner.
    /// @param owner     The owner of the Tokens
    /// @param operator  Address of authorized operator
    /// @return           True if the operator is approved, false if not
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return        The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256);

    /// @notice Get the total supply of a Token.
    /// @param id     ID of the Token
    /// @return        The total supply of the Token type requested
    function totalSupply(uint256 id) external view returns (uint256);

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(
        address[] calldata owners,
        uint256[] calldata ids
    )
        external
        view
        returns (uint256[] memory balances_);
}

contract IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) public view returns (uint256);
    function transfer(address to, uint256 amount) public returns (bool);
    function transferFrom(address from, address to, uint256 amount) public returns (bool);
    function approve(address spender, uint256 amount) public returns (bool);
    function allowance(address owner, address spender) public view returns (uint256);

    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ICash is IERC20 {
}

contract IAffiliateValidator {
    function validateReference(address _account, address _referrer) external view returns (bool);
}

contract IDisputeWindow is ITyped, IERC20 {
    function invalidMarketsTotal() external view returns (uint256);
    function validityBondTotal() external view returns (uint256);

    function incorrectDesignatedReportTotal() external view returns (uint256);
    function initialReportBondTotal() external view returns (uint256);

    function designatedReportNoShowsTotal() external view returns (uint256);
    function designatedReporterNoShowBondTotal() external view returns (uint256);

    function initialize(IAugur _augur, IUniverse _universe, uint256 _disputeWindowId, bool _participationTokensEnabled, uint256 _duration, uint256 _startTime) public;
    function trustedBuy(address _buyer, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getReputationToken() public view returns (IReputationToken);
    function getStartTime() public view returns (uint256);
    function getEndTime() public view returns (uint256);
    function getWindowId() public view returns (uint256);
    function isActive() public view returns (bool);
    function isOver() public view returns (bool);
    function onMarketFinalized() public;
    function redeem(address _account) public returns (bool);
}

contract IMarket is IOwnable {
    enum MarketType {
        YES_NO,
        CATEGORICAL,
        SCALAR
    }

    function initialize(IAugur _augur, IUniverse _universe, uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public;
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators) public view returns (bytes32);
    function doInitialReport(uint256[] memory _payoutNumerators, string memory _description, uint256 _additionalStake) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getDisputeWindow() public view returns (IDisputeWindow);
    function getNumberOfOutcomes() public view returns (uint256);
    function getNumTicks() public view returns (uint256);
    function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
    function getForkingMarket() public view returns (IMarket _market);
    function getEndTime() public view returns (uint256);
    function getWinningPayoutDistributionHash() public view returns (bytes32);
    function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningReportingParticipant() public view returns (IReportingParticipant);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getFinalizationTime() public view returns (uint256);
    function getInitialReporter() public view returns (IInitialReporter);
    function getDesignatedReportingEndTime() public view returns (uint256);
    function getValidityBondAttoCash() public view returns (uint256);
    function affiliateFeeDivisor() external view returns (uint256);
    function getNumParticipants() public view returns (uint256);
    function getDisputePacingOn() public view returns (bool);
    function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
    function recordMarketCreatorFees(uint256 _marketCreatorFees, address _sourceAccount, bytes32 _fingerprint) public returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function isFinalizedAsInvalid() public view returns (bool);
    function finalize() public returns (bool);
    function isFinalized() public view returns (bool);
    function getOpenInterest() public view returns (uint256);
}

contract IReportingParticipant {
    function getStake() public view returns (uint256);
    function getPayoutDistributionHash() public view returns (bytes32);
    function liquidateLosing() public;
    function redeem(address _redeemer) public returns (bool);
    function isDisavowed() public view returns (bool);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getMarket() public view returns (IMarket);
    function getSize() public view returns (uint256);
}

contract IInitialReporter is IReportingParticipant, IOwnable {
    function initialize(IAugur _augur, IMarket _market, address _designatedReporter) public;
    function report(address _reporter, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _initialReportStake) public;
    function designatedReporterShowed() public view returns (bool);
    function initialReporterWasCorrect() public view returns (bool);
    function getDesignatedReporter() public view returns (address);
    function getReportTimestamp() public view returns (uint256);
    function migrateToNewUniverse(address _designatedReporter) public;
    function returnRepFromDisavow() public;
}

contract IReputationToken is IERC20 {
    function migrateOutByPayout(uint256[] memory _payoutNumerators, uint256 _attotokens) public returns (bool);
    function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
    function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedDisputeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getTotalMigrated() public view returns (uint256);
    function getTotalTheoreticalSupply() public view returns (uint256);
    function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
}

contract IShareToken is ITyped, IERC1155 {
    function initialize(IAugur _augur) external;
    function initializeMarket(IMarket _market, uint256 _numOutcomes, uint256 _numTicks) public;
    function unsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value) public;
    function unsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) public;
    function claimTradingProceeds(IMarket _market, address _shareHolder, bytes32 _fingerprint) external returns (uint256[] memory _outcomeFees);
    function getMarket(uint256 _tokenId) external view returns (IMarket);
    function getOutcome(uint256 _tokenId) external view returns (uint256);
    function getTokenId(IMarket _market, uint256 _outcome) public pure returns (uint256 _tokenId);
    function getTokenIds(IMarket _market, uint256[] memory _outcomes) public pure returns (uint256[] memory _tokenIds);
    function buyCompleteSets(IMarket _market, address _account, uint256 _amount) external returns (bool);
    function buyCompleteSetsForTrade(IMarket _market, uint256 _amount, uint256 _longOutcome, address _longRecipient, address _shortRecipient) external returns (bool);
    function sellCompleteSets(IMarket _market, address _holder, address _recipient, uint256 _amount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function sellCompleteSetsForTrade(IMarket _market, uint256 _outcome, uint256 _amount, address _shortParticipant, address _longParticipant, address _shortRecipient, address _longRecipient, uint256 _price, address _sourceAccount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function totalSupplyForMarketOutcome(IMarket _market, uint256 _outcome) public view returns (uint256);
    function balanceOfMarketOutcome(IMarket _market, uint256 _outcome, address _account) public view returns (uint256);
    function lowestBalanceOfMarketOutcomes(IMarket _market, uint256[] memory _outcomes, address _account) public view returns (uint256);
}

contract IUniverse {
    function creationTime() external view returns (uint256);
    function marketBalance(address) external view returns (uint256);

    function fork() public returns (bool);
    function updateForkValues() public returns (bool);
    function getParentUniverse() public view returns (IUniverse);
    function createChildUniverse(uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getForkingMarket() public view returns (IMarket);
    function getForkEndTime() public view returns (uint256);
    function getForkReputationGoal() public view returns (uint256);
    function getParentPayoutDistributionHash() public view returns (bytes32);
    function getDisputeRoundDurationInSeconds(bool _initial) public view returns (uint256);
    function getOrCreateDisputeWindowByTimestamp(uint256 _timestamp, bool _initial) public returns (IDisputeWindow);
    function getOrCreateCurrentDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreateNextDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreatePreviousDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOpenInterestInAttoCash() public view returns (uint256);
    function getTargetRepMarketCapInAttoCash() public view returns (uint256);
    function getOrCacheValidityBond() public returns (uint256);
    function getOrCacheDesignatedReportStake() public returns (uint256);
    function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
    function getOrCacheMarketRepBond() public returns (uint256);
    function getOrCacheReportingFeeDivisor() public returns (uint256);
    function getDisputeThresholdForFork() public view returns (uint256);
    function getDisputeThresholdForDisputePacing() public view returns (uint256);
    function getInitialReportMinValue() public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getReportingFeeDivisor() public view returns (uint256);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningChildPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function isOpenInterestCash(address) public view returns (bool);
    function isForkingMarket() public view returns (bool);
    function getCurrentDisputeWindow(bool _initial) public view returns (IDisputeWindow);
    function getDisputeWindowStartTimeAndDuration(uint256 _timestamp, bool _initial) public view returns (uint256, uint256);
    function isParentOf(IUniverse _shadyChild) public view returns (bool);
    function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
    function isContainerForDisputeWindow(IDisputeWindow _shadyTarget) public view returns (bool);
    function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function migrateMarketOut(IUniverse _destinationUniverse) public returns (bool);
    function migrateMarketIn(IMarket _market, uint256 _cashBalance, uint256 _marketOI) public returns (bool);
    function decrementOpenInterest(uint256 _amount) public returns (bool);
    function decrementOpenInterestFromMarket(IMarket _market) public returns (bool);
    function incrementOpenInterest(uint256 _amount) public returns (bool);
    function getWinningChildUniverse() public view returns (IUniverse);
    function isForking() public view returns (bool);
    function deposit(address _sender, uint256 _amount, address _market) public returns (bool);
    function withdraw(address _recipient, uint256 _amount, address _market) public returns (bool);
    function createScalarMarket(uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, int256[] memory _prices, uint256 _numTicks, string memory _extraInfo) public returns (IMarket _newMarket);
}

contract IV2ReputationToken is IReputationToken {
    function parentUniverse() external returns (IUniverse);
    function burnForMarket(uint256 _amountToBurn) public returns (bool);
    function mintForWarpSync(uint256 _amountToMint, address _target) public returns (bool);
}

contract IAugurTrading {
    function lookup(bytes32 _key) public view returns (address);
    function logProfitLossChanged(IMarket _market, address _account, uint256 _outcome, int256 _netPosition, uint256 _avgPrice, int256 _realizedProfit, int256 _frozenFunds, int256 _realizedCost) public returns (bool);
    function logOrderCreated(IUniverse _universe, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logOrderCanceled(IUniverse _universe, IMarket _market, address _creator, uint256 _tokenRefund, uint256 _sharesRefund, bytes32 _orderId) public returns (bool);
    function logOrderFilled(IUniverse _universe, address _creator, address _filler, uint256 _price, uint256 _fees, uint256 _amountFilled, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logMarketVolumeChanged(IUniverse _universe, address _market, uint256 _volume, uint256[] memory _outcomeVolumes, uint256 _totalTrades) public returns (bool);
    function logZeroXOrderFilled(IUniverse _universe, IMarket _market, bytes32 _orderHash, bytes32 _tradeGroupId, uint8 _orderType, address[] memory _addressData, uint256[] memory _uint256Data) public returns (bool);
    function logZeroXOrderCanceled(address _universe, address _market, address _account, uint256 _outcome, uint256 _price, uint256 _amount, uint8 _type, bytes32 _orderHash) public;
}

contract IFillOrder {
    function publicFillOrder(bytes32 _orderId, uint256 _amountFillerWants, bytes32 _tradeGroupId, bytes32 _fingerprint) external returns (uint256);
    function fillOrder(address _filler, bytes32 _orderId, uint256 _amountFillerWants, bytes32 tradeGroupId, bytes32 _fingerprint) external returns (uint256);
    function fillZeroXOrder(IMarket _market, uint256 _outcome, uint256 _price, Order.Types _orderType, address _creator, uint256 _amount, bytes32 _fingerprint, bytes32 _tradeGroupId, address _filler) external returns (uint256, uint256);
    function getMarketOutcomeValues(IMarket _market) public view returns (uint256[] memory);
    function getMarketVolume(IMarket _market) public view returns (uint256);
}

contract IOrders {
    function saveOrder(uint256[] calldata _uints, bytes32[] calldata _bytes32s, Order.Types _type, IMarket _market, address _sender) external returns (bytes32 _orderId);
    function removeOrder(bytes32 _orderId) external returns (bool);
    function getMarket(bytes32 _orderId) public view returns (IMarket);
    function getOrderType(bytes32 _orderId) public view returns (Order.Types);
    function getOutcome(bytes32 _orderId) public view returns (uint256);
    function getAmount(bytes32 _orderId) public view returns (uint256);
    function getPrice(bytes32 _orderId) public view returns (uint256);
    function getOrderCreator(bytes32 _orderId) public view returns (address);
    function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderDataForCancel(bytes32 _orderId) public view returns (uint256, uint256, Order.Types, IMarket, uint256, address);
    function getOrderDataForLogs(bytes32 _orderId) public view returns (Order.Types, address[] memory _addressData, uint256[] memory _uint256Data);
    function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
    function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
    function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
    function getOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
    function getTotalEscrowed(IMarket _market) public view returns (uint256);
    function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
    function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
    function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled, uint256 _fill) external returns (bool);
    function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
}

contract IZeroXTrade {

    struct AugurOrderData {
        address marketAddress;                  // Market Address
        uint256 price;                          // Price
        uint8 outcome;                          // Outcome
        uint8 orderType;                        // Order Type
    }

    function parseOrderData(IExchange.Order memory _order) public view returns (AugurOrderData memory _data);
    function unpackTokenId(uint256 _tokenId) public pure returns (address _market, uint256 _price, uint8 _outcome, uint8 _type);
}

library Order {
    using SafeMathUint256 for uint256;

    enum Types {
        Bid, Ask
    }

    enum TradeDirections {
        Long, Short
    }

    struct Data {
        // Contracts
        IMarket market;
        IAugur augur;
        IAugurTrading augurTrading;
        IShareToken shareToken;
        ICash cash;

        // Order
        bytes32 id;
        address creator;
        uint256 outcome;
        Order.Types orderType;
        uint256 amount;
        uint256 price;
        uint256 sharesEscrowed;
        uint256 moneyEscrowed;
        bytes32 betterOrderId;
        bytes32 worseOrderId;
    }

    function create(IAugur _augur, IAugurTrading _augurTrading, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data memory) {
        require(_outcome < _market.getNumberOfOutcomes(), "Order.create: Outcome is not within market range");
        require(_price != 0, "Order.create: Price may not be 0");
        require(_price < _market.getNumTicks(), "Order.create: Price is outside of market range");
        require(_attoshares > 0, "Order.create: Cannot use amount of 0");
        require(_creator != address(0), "Order.create: Creator is 0x0");

        IShareToken _shareToken = IShareToken(_augur.lookup("ShareToken"));

        return Data({
            market: _market,
            augur: _augur,
            augurTrading: _augurTrading,
            shareToken: _shareToken,
            cash: ICash(_augur.lookup("Cash")),
            id: 0,
            creator: _creator,
            outcome: _outcome,
            orderType: _type,
            amount: _attoshares,
            price: _price,
            sharesEscrowed: 0,
            moneyEscrowed: 0,
            betterOrderId: _betterOrderId,
            worseOrderId: _worseOrderId
        });
    }

    //
    // "public" functions
    //

    function getOrderId(Order.Data memory _orderData, IOrders _orders) internal view returns (bytes32) {
        if (_orderData.id == bytes32(0)) {
            bytes32 _orderId = calculateOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
            require(_orders.getAmount(_orderId) == 0, "Order.getOrderId: New order had amount. This should not be possible");
            _orderData.id = _orderId;
        }
        return _orderData.id;
    }

    function calculateOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) internal pure returns (bytes32) {
        return sha256(abi.encodePacked(_type, _market, _amount, _price, _sender, _blockNumber, _outcome, _moneyEscrowed, _sharesEscrowed));
    }

    function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
        return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
    }

    function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
        return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
    }

    function saveOrder(Order.Data memory _orderData, bytes32 _tradeGroupId, IOrders _orders) internal returns (bytes32) {
        getOrderId(_orderData, _orders);
        uint256[] memory _uints = new uint256[](5);
        _uints[0] = _orderData.amount;
        _uints[1] = _orderData.price;
        _uints[2] = _orderData.outcome;
        _uints[3] = _orderData.moneyEscrowed;
        _uints[4] = _orderData.sharesEscrowed;
        bytes32[] memory _bytes32s = new bytes32[](4);
        _bytes32s[0] = _orderData.betterOrderId;
        _bytes32s[1] = _orderData.worseOrderId;
        _bytes32s[2] = _tradeGroupId;
        _bytes32s[3] = _orderData.id;
        return _orders.saveOrder(_uints, _bytes32s, _orderData.orderType, _orderData.market, _orderData.creator);
    }
}

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

interface IWETH {
    function deposit() external payable;
    function balanceOf(address owner) external view returns (uint);
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

contract ZeroXTrade is Initializable, IZeroXTrade, IERC1155 {
    using SafeMathUint256 for uint256;
    using LibBytes for bytes;

    bool transferFromAllowed = false;

    // ERC20Token(address)
    bytes4 constant private ERC20_PROXY_ID = 0xf47261b0;

    // ERC1155Assets(address,uint256[],uint256[],bytes)
    bytes4 constant private MULTI_ASSET_PROXY_ID = 0x94cfcdd7;

    // ERC1155Assets(address,uint256[],uint256[],bytes)
    bytes4 constant private ERC1155_PROXY_ID = 0xa7cb5fb7;

    // EIP191 header for EIP712 prefix
    string constant internal EIP191_HEADER = "\x19\x01";

    // EIP712 Domain Name value
    string constant internal EIP712_DOMAIN_NAME = "0x Protocol";

    // EIP712 Domain Version value
    string constant internal EIP712_DOMAIN_VERSION = "2";

    // EIP1271 Order With Hash Selector
    bytes4 constant public EIP1271_ORDER_WITH_HASH_SELECTOR = 0x3efe50c8;

    // Hash of the EIP712 Domain Separator Schema
    bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(
        abi.encodePacked(
        "EIP712Domain(",
        "string name,",
        "string version,",
        "address verifyingContract",
        ")"
    ));

    bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(
        abi.encodePacked(
        "Order(",
        "address makerAddress,",
        "address takerAddress,",
        "address feeRecipientAddress,",
        "address senderAddress,",
        "uint256 makerAssetAmount,",
        "uint256 takerAssetAmount,",
        "uint256 makerFee,",
        "uint256 takerFee,",
        "uint256 expirationTimeSeconds,",
        "uint256 salt,",
        "bytes makerAssetData,",
        "bytes takerAssetData",
        "bytes makerFeeAssetData,",
        "bytes takerFeeAssetData",
        ")"
    ));

    // Hash of the EIP712 Domain Separator data
    // solhint-disable-next-line var-name-mixedcase
    bytes32 public EIP712_DOMAIN_HASH;

    IAugur public augur;
    IAugurTrading public augurTrading;
    IFillOrder public fillOrder;
    ICash public cash;
    IShareToken public shareToken;
    IExchange public exchange;
    IUniswapV2Pair public ethExchange;
    IWETH public WETH;
    bool public token0IsCash;

    function initialize(IAugur _augur, IAugurTrading _augurTrading) public beforeInitialized {
        endInitialization();
        augur = _augur;
        augurTrading = _augurTrading;
        cash = ICash(_augur.lookup("Cash"));
        require(cash != ICash(0));
        shareToken = IShareToken(_augur.lookup("ShareToken"));
        require(shareToken != IShareToken(0));
        exchange = IExchange(_augurTrading.lookup("ZeroXExchange"));
        require(exchange != IExchange(0));
        fillOrder = IFillOrder(_augurTrading.lookup("FillOrder"));
        require(fillOrder != IFillOrder(0));
        WETH = IWETH(_augurTrading.lookup("WETH9"));
        IUniswapV2Factory _uniswapFactory = IUniswapV2Factory(_augur.lookup("UniswapV2Factory"));
        address _ethExchangeAddress = _uniswapFactory.getPair(address(WETH), address(cash));
        if (_ethExchangeAddress == address(0)) {
            _ethExchangeAddress = _uniswapFactory.createPair(address(WETH), address(cash));
        }
        ethExchange = IUniswapV2Pair(_ethExchangeAddress);
        token0IsCash = ethExchange.token0() == address(cash);

        EIP712_DOMAIN_HASH = keccak256(
            abi.encodePacked(
                EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
                keccak256(bytes(EIP712_DOMAIN_NAME)),
                keccak256(bytes(EIP712_DOMAIN_VERSION)),
                uint256(address(this))
            )
        );
    }

    // ERC1155 Implementation
    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external {
        require(transferFromAllowed);
        emit TransferSingle(msg.sender, from, to, id, value);
    }

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external {
        require(transferFromAllowed);
        emit TransferBatch(msg.sender, from, to, ids, values);
    }

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return       The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256) {
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(id);
        // NOTE: An invalid order type will cause a failure here. That is malformed input so we don't mind reverting in such a case
        Order.Types _orderType = Order.Types(_type);
        if (_orderType == Order.Types.Ask) {
            return askBalance(owner, IMarket(_market), _outcome, _price);
        } else if (_orderType == Order.Types.Bid) {
            return bidBalance(owner, IMarket(_market), _outcome, _price);
        }
    }

    function totalSupply(uint256 id) external view returns (uint256) {
        return 0;
    }

    function bidBalance(address _owner, IMarket _market, uint8 _outcome, uint256 _price) public view returns (uint256) {
        uint256 _numberOfOutcomes = _market.getNumberOfOutcomes();
        // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
        uint256[] memory _shortOutcomes = new uint256[](_numberOfOutcomes - 1);
        uint256 _indexOutcome = 0;
        for (uint256 _i = 0; _i < _numberOfOutcomes - 1; _i++) {
            if (_i == _outcome) {
                _indexOutcome++;
            }
            _shortOutcomes[_i] = _indexOutcome;
            _indexOutcome++;
        }

        uint256 _attoSharesOwned = shareToken.lowestBalanceOfMarketOutcomes(_market, _shortOutcomes, _owner);

        uint256 _availableCash = cashAvailableForTransferFrom(_owner, address(fillOrder));
        uint256 _attoSharesPurchasable = _availableCash.div(_price);

        return _attoSharesOwned.add(_attoSharesPurchasable);
    }

    function askBalance(address _owner, IMarket _market, uint8 _outcome, uint256 _price) public view returns (uint256) {
        uint256 _attoSharesOwned = shareToken.balanceOfMarketOutcome(_market, _outcome, _owner);
        uint256 _availableCash = cashAvailableForTransferFrom(_owner, address(fillOrder));
        uint256 _attoSharesPurchasable = _availableCash.div(_market.getNumTicks().sub(_price));

        return _attoSharesOwned.add(_attoSharesPurchasable);
    }

    function cashAvailableForTransferFrom(address _owner, address _sender) public view returns (uint256) {
        uint256 _balance = cash.balanceOf(_owner);
        uint256 _allowance = cash.allowance(_owner, _sender);
        return _balance.min(_allowance);
    }

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external view returns (uint256[] memory balances_) {
        balances_ = new uint256[](owners.length);
        for (uint256 _i = 0; _i < owners.length; _i++) {
            balances_[_i] = this.balanceOf(owners[_i], ids[_i]);
        }
    }

    function setApprovalForAll(address operator, bool approved) external {
        revert("Not supported");
    }

    function isApprovedForAll(address owner, address operator) external view returns (bool) {
        return true;
    }

    // Trade functions

    /**
     * Perform Augur Trades using 0x signed orders
     *
     * @param  _requestedFillAmount  Share amount to fill
     * @param  _fingerprint          Fingerprint of the user to restrict affiliate fees
     * @param  _tradeGroupId         Random id to correlate these fills as one trade action
     * @param  _maxProtocolFeeDai    The maximum amount of DAI to spend on covering the 0x protocol fee
     * @param  _maxTrades            The maximum number of trades to actually take from the provided 0x orders
     * @param  _orders               Array of encoded Order struct data
     * @param  _signatures           Array of signature data
     * @return                       The amount the taker still wants
     */
    function trade(
        uint256 _requestedFillAmount,
        bytes32 _fingerprint,
        bytes32 _tradeGroupId,
        uint256 _maxProtocolFeeDai,
        uint256 _maxTrades,
        IExchange.Order[] memory _orders,
        bytes[] memory _signatures
    )
        public
        payable
        returns (uint256)
    {
        require(_orders.length > 0);
        uint256 _fillAmountRemaining = _requestedFillAmount;

        transferFromAllowed = true;

        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(tx.gasprice);
        coverProtocolFee(_protocolFee.mul(_maxTrades), _maxProtocolFeeDai);

        // Do the actual asset exchanges
        for (uint256 i = 0; i < _orders.length && _fillAmountRemaining != 0; i++) {
            IExchange.Order memory _order = _orders[i];
            validateOrder(_order, _fillAmountRemaining);

            // Update 0x and pay protocol fee. This will also validate signatures and order state for us.
            IExchange.FillResults memory totalFillResults = fillOrderNoThrow(
                _order,
                _fillAmountRemaining,
                _signatures[i],
                _protocolFee
            );

            if (totalFillResults.takerAssetFilledAmount == 0) {
                continue;
            }

            uint256 _amountTraded = doTrade(_order, totalFillResults.takerAssetFilledAmount, _fingerprint, _tradeGroupId, msg.sender);

            _fillAmountRemaining = _fillAmountRemaining.sub(_amountTraded);
            _maxTrades -= 1;
            if (_maxTrades == 0) {
                break;
            }
        }

        transferFromAllowed = false;

        if (address(this).balance > 0) {
            (bool _success,) = msg.sender.call.value(address(this).balance)("");
            require(_success);
        }

        return _fillAmountRemaining;
    }

    function fillOrderNoThrow(IExchange.Order memory _order, uint256 _takerAssetFillAmount, bytes memory _signature, uint256 _protocolFee) internal returns (IExchange.FillResults memory fillResults) {
        bytes memory fillOrderCalldata = abi.encodeWithSelector(
            IExchange(address(0)).fillOrder.selector,
            _order,
            _takerAssetFillAmount,
            _signature
        );

        (bool _didSucceed, bytes memory _returnData) = address(exchange).call.value(_protocolFee)(fillOrderCalldata);
        if (_didSucceed) {
            assert(_returnData.length == 160);
            fillResults = abi.decode(_returnData, (IExchange.FillResults));
        }
        return fillResults;
    }

    function coverProtocolFee(uint256 _amountEthRequired, uint256 _maxProtocolFeeDai) internal {
        if (address(this).balance < _amountEthRequired) {
            uint256 _ethDeficit = _amountEthRequired - address(this).balance;
            uint256 _cost = getTokenPurchaseCost(_ethDeficit);
            require(_cost <= _maxProtocolFeeDai, "Cost of purchasing ETH to cover protocol Fee on the exchange was too high");
            require(cash.transferFrom(msg.sender, address(ethExchange), _cost));
            ethExchange.swap(token0IsCash ? 0 : _ethDeficit, token0IsCash ? _ethDeficit : 0, address(this), "");
            WETH.withdraw(_ethDeficit);
        }
    }

    function estimateProtocolFeeCostInCash(uint256 _numOrders, uint256 _gasPrice) public view returns (uint256) {
        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(_gasPrice);
        uint256 _amountEthRequired = _protocolFee.mul(_numOrders);
        return getTokenPurchaseCost(_amountEthRequired);
    }

    function getTokenPurchaseCost(uint256 _ethAmount) private view returns (uint256) {
        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = ethExchange.getReserves();
        return getAmountIn(_ethAmount, token0IsCash ? _reserve0 : _reserve1, token0IsCash ? _reserve1 : _reserve0);
    }

    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure returns (uint amountIn) {
        require(amountOut > 0);
        require(reserveIn > 0 && reserveOut > 0);
        uint numerator = reserveIn.mul(amountOut).mul(1000);
        uint denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);
    }

    function validateOrder(IExchange.Order memory _order, uint256 _fillAmountRemaining) internal view {
        require(_order.takerAssetData.equals(encodeTakerAssetData()));
        require(_order.takerAssetAmount == _order.makerAssetAmount);
        (IERC1155 _zeroXTradeTokenMaker, uint256 _tokenIdMaker) = getZeroXTradeTokenData(_order.makerAssetData);
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(_tokenIdMaker);
        uint256 _numTicks = IMarket(_market).getNumTicks();
        require(isOrderAmountValid(IMarket(_market), _fillAmountRemaining), "Order must be a multiple of the market trade increment");
        require(_zeroXTradeTokenMaker == this);
    }

    function isOrderAmountValid(IMarket _market, uint256 _orderAmount) public view returns (bool) {
        uint256 _tradeInterval = IAugurMarketDataGetter(address(augur)).getMarketRecommendedTradeInterval(_market);
        return _orderAmount.isMultipleOf(_tradeInterval);
    }

    function cancelOrders(IExchange.Order[] memory _orders, bytes[] memory _signatures, uint256 _maxProtocolFeeDai) public returns (bool) {
        require(_orders.length == _signatures.length);
        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(tx.gasprice);
        coverProtocolFee(_protocolFee.mul(_orders.length), _maxProtocolFeeDai);
        transferFromAllowed = true;
        for (uint256 i = 0; i < _orders.length; i++) {
            IExchange.Order memory _order = _orders[i];
            bytes memory _signature = _signatures[i];
            require(msg.sender == _order.makerAddress);
            IExchange.OrderInfo memory _orderInfo = exchange.getOrderInfo(_order);
            uint256 _amountRemaining = _order.takerAssetAmount.sub(_orderInfo.orderTakerAssetFilledAmount);
            exchange.fillOrder.value(_protocolFee)(_order, _amountRemaining, _signature);
            AugurOrderData memory _orderData = parseOrderData(_order);
            IUniverse _universe = IMarket(_orderData.marketAddress).getUniverse();
            augurTrading.logZeroXOrderCanceled(address(_universe), _orderData.marketAddress, _order.makerAddress, _orderData.outcome, _orderData.price, _amountRemaining, uint8(_orderData.orderType), _orderInfo.orderHash);
        }
        transferFromAllowed = false;
        if (address(this).balance > 0) {
            (bool _success,) = msg.sender.call.value(address(this).balance)("");
            require(_success);
        }
        return true;
    }

    function doTrade(IExchange.Order memory _order, uint256 _amount, bytes32 _fingerprint, bytes32 _tradeGroupId, address _taker) private returns (uint256 _amountFilled) {
        // parseOrderData will validate that the token being traded is the leigitmate one for the market
        AugurOrderData memory _augurOrderData = parseOrderData(_order);
        // If the signed order creator doesnt have enough funds we still want to continue and take their order out of the list
        // If the filler doesn't have funds this will just fail, which is fine
        if (!creatorHasFundsForTrade(_order, _amount)) {
            return 0;
        }
        // If the maker is also the taker we also just skip the trade but treat it as filled for amount remaining purposes
        if (_order.makerAddress == _taker) {
            return _amount;
        }
        (uint256 _amountRemaining, uint256 _fees) = fillOrder.fillZeroXOrder(IMarket(_augurOrderData.marketAddress), _augurOrderData.outcome, _augurOrderData.price, Order.Types(_augurOrderData.orderType), _order.makerAddress, _amount, _fingerprint, _tradeGroupId, _taker);
        _amountFilled = _amount.sub(_amountRemaining);
        logOrderFilled(_order, _augurOrderData, _taker, _tradeGroupId, _amountFilled, _fees);
        return _amountFilled;
    }

    function logOrderFilled(IExchange.Order memory _order, AugurOrderData memory _augurOrderData, address _taker, bytes32 _tradeGroupId, uint256 _amountFilled, uint256 _fees) private {
        bytes32 _orderHash = exchange.getOrderInfo(_order).orderHash;
        address[] memory _addressData = new address[](2);
        uint256[] memory _uint256Data = new uint256[](10);
        Order.Types _orderType = Order.Types(_augurOrderData.orderType);
        _addressData[0] = _order.makerAddress;
        _addressData[1] = _taker;
        _uint256Data[0] = _augurOrderData.price;
        _uint256Data[1] = 0;
        _uint256Data[2] = _augurOrderData.outcome;
        _uint256Data[5] = _fees;
        _uint256Data[6] = _amountFilled;
        _uint256Data[8] = 0;
        _uint256Data[9] = 0;
        augurTrading.logZeroXOrderFilled(IMarket(_augurOrderData.marketAddress).getUniverse(), IMarket(_augurOrderData.marketAddress), _orderHash, _tradeGroupId, uint8(_orderType), _addressData, _uint256Data);
    }

    function creatorHasFundsForTrade(IExchange.Order memory _order, uint256 _amount) public view returns (bool) {
        uint256 _tokenId = getTokenIdFromOrder(_order);
        return _amount <= this.balanceOf(_order.makerAddress, _tokenId);
    }

    function getTransferFromAllowed() public view returns (bool) {
        return transferFromAllowed;
    }

    /// @dev Encode MultiAsset proxy asset data into the format described in the AssetProxy contract specification.
    /// @param _market The address of the market to trade on
    /// @param _price The price used to trade
    /// @param _outcome The outcome to trade on
    /// @param _type Either BID == 0 or ASK == 1
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeAssetData(
        IMarket _market,
        uint256 _price,
        uint8 _outcome,
        uint8 _type
    )
        public
        view
        returns (bytes memory _assetData)
    {
        bytes[] memory _nestedAssetData = new bytes[](3);
        uint256[] memory _multiAssetValues = new uint256[](3);
        _nestedAssetData[0] = encodeTradeAssetData(_market, _price, _outcome, _type);
        _nestedAssetData[1] = encodeCashAssetData();
        _nestedAssetData[2] = encodeShareAssetData();
        _multiAssetValues[0] = 1;
        _multiAssetValues[1] = 0;
        _multiAssetValues[2] = 0;
        bytes memory _data = abi.encodeWithSelector(
            MULTI_ASSET_PROXY_ID,
            _multiAssetValues,
            _nestedAssetData
        );
        return _data;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @param _market The address of the market to trade on
    /// @param _price The price used to trade
    /// @param _outcome The outcome to trade on
    /// @param _type Either BID == 0 or ASK == 1
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeTradeAssetData(
        IMarket _market,
        uint256 _price,
        uint8 _outcome,
        uint8 _type
    )
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](1);
        uint256[] memory _tokenValues = new uint256[](1);

        uint256 _tokenId = getTokenId(address(_market), _price, _outcome, _type);
        _tokenIds[0] = _tokenId;
        _tokenValues[0] = 1;
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(this),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    /// @dev Encode ERC-20 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeCashAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        _assetData = abi.encodeWithSelector(
            ERC20_PROXY_ID,
            address(cash)
        );

        return _assetData;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeShareAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](0);
        uint256[] memory _tokenValues = new uint256[](0);
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(shareToken),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeTakerAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](0);
        uint256[] memory _tokenValues = new uint256[](0);
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(this),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    function getTokenId(address _market, uint256 _price, uint8 _outcome, uint8 _type) public pure returns (uint256 _tokenId) {
        // NOTE: we're assuming no one needs a full uint256 for the price value here and cutting to uint80 so we can pack this in a uint256.
        bytes memory _tokenIdBytes = abi.encodePacked(_market, uint80(_price), _outcome, _type);
        assembly {
            _tokenId := mload(add(_tokenIdBytes, add(0x20, 0)))
        }
    }

    function unpackTokenId(uint256 _tokenId) public pure returns (address _market, uint256 _price, uint8 _outcome, uint8 _type) {
        assembly {
            _market := shr(96, and(_tokenId, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000))
            _price := shr(16,  and(_tokenId, 0x0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF0000))
            _outcome := shr(8, and(_tokenId, 0x000000000000000000000000000000000000000000000000000000000000FF00))
            _type :=           and(_tokenId, 0x00000000000000000000000000000000000000000000000000000000000000FF)
        }
    }

    /// @dev Decode MultiAsset asset data from the format described in the AssetProxy contract specification.
    /// @param _assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets.
    /// @return The ERC-1155 AssetProxy identifier, the address of this ERC-1155
    /// contract hosting the assets, an array of the identifiers of the
    /// assets to be traded, an array of asset amounts to be traded, and
    /// callback data.  Each element of the arrays corresponds to the
    /// same-indexed element of the other array.  Return values specified as
    /// `memory` are returned as pointers to locations within the memory of
    /// the input parameter `assetData`.
    function decodeAssetData(bytes memory _assetData)
        public
        view
        returns (
            bytes4 _assetProxyId,
            address _tokenAddress,
            uint256[] memory _tokenIds,
            uint256[] memory _tokenValues,
            bytes memory _callbackData
        )
    {
         // Read the bytes4 from array memory
        assembly {
            _assetProxyId := mload(add(_assetData, 32))
            // Solidity does not require us to clean the trailing bytes. We do it anyway
            _assetProxyId := and(_assetProxyId, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }

        require(_assetProxyId == MULTI_ASSET_PROXY_ID, "WRONG_PROXY_ID");

        uint256[] memory _amounts;
        bytes[] memory _nestedAssetData;

        // Slice the selector off the asset data
        bytes memory _noSelectorAssetData = _assetData.slice(4, _assetData.length);

        (_amounts, _nestedAssetData) = abi.decode(_noSelectorAssetData, (uint256[], bytes[]));
        
        // Validate storage refs against the decoded values.
        {
            require(_amounts.length == 3);
            require(_amounts[0] == 1);
            require(_amounts[1] == 0);
            require(_amounts[2] == 0);
            require(_nestedAssetData[1].equals(encodeCashAssetData()));
            require(_nestedAssetData[2].equals(encodeShareAssetData()));
        }

        return decodeTradeAssetData(_nestedAssetData[0]);
    }

    /// @dev Decode ERC-1155 asset data from the format described in the AssetProxy contract specification.
    /// @param _assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets.
    /// @return The ERC-1155 AssetProxy identifier, the address of this ERC-1155
    /// contract hosting the assets, an array of the identifiers of the
    /// assets to be traded, an array of asset amounts to be traded, and
    /// callback data.  Each element of the arrays corresponds to the
    /// same-indexed element of the other array.  Return values specified as
    /// `memory` are returned as pointers to locations within the memory of
    /// the input parameter `assetData`.
    function decodeTradeAssetData(bytes memory _assetData)
        public
        pure
        returns (
            bytes4 _assetProxyId,
            address _tokenAddress,
            uint256[] memory _tokenIds,
            uint256[] memory _tokenValues,
            bytes memory _callbackData
        )
    {
         // Read the bytes4 from array memory
        assembly {
            _assetProxyId := mload(add(_assetData, 32))
            // Solidity does not require us to clean the trailing bytes. We do it anyway
            _assetProxyId := and(_assetProxyId, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }

        require(_assetProxyId == ERC1155_PROXY_ID, "WRONG_PROXY_ID");

        assembly {
            let _length := mload(_assetData)
            // Skip the length (of bytes variable) and the selector to get to the first parameter.
            _assetData := add(_assetData, 36)
            // Read the value of the first parameter:
            _tokenAddress := mload(_assetData)
            _tokenIds := add(_assetData, mload(add(_assetData, 32)))
            _tokenValues := add(_assetData, mload(add(_assetData, 64)))
            _callbackData := add(_assetData, mload(add(_assetData, 96)))
        }

        return (
            _assetProxyId,
            _tokenAddress,
            _tokenIds,
            _tokenValues,
            _callbackData
        );
    }

    function parseOrderData(IExchange.Order memory _order) public view returns (AugurOrderData memory _data) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_order.makerAssetData);
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(_tokenIds[0]);
        _data.marketAddress = _market;
        _data.price = _price;
        _data.orderType = _type;
        _data.outcome = _outcome;
    }

    function getZeroXTradeTokenData(bytes memory _assetData) public view returns (IERC1155 _token, uint256 _tokenId) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_assetData);
        _tokenId = _tokenIds[0];
        _token = IERC1155(_tokenAddress);
    }

    function getTokenIdFromOrder(IExchange.Order memory _order) public view returns (uint256 _tokenId) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_order.makerAssetData);
        _tokenId = _tokenIds[0];
    }

    function createZeroXOrder(uint8 _type, uint256 _attoshares, uint256 _price, address _market, uint8 _outcome, uint256 _expirationTimeSeconds, uint256 _salt) public view returns (IExchange.Order memory _zeroXOrder, bytes32 _orderHash) {
        return createZeroXOrderFor(msg.sender, _type, _attoshares, _price, _market, _outcome, _expirationTimeSeconds, _salt);
    }

    function createZeroXOrderFor(address _maker, uint8 _type, uint256 _attoshares, uint256 _price, address _market, uint8 _outcome, uint256 _expirationTimeSeconds, uint256 _salt) public view returns (IExchange.Order memory _zeroXOrder, bytes32 _orderHash) {
        bytes memory _assetData = encodeAssetData(IMarket(_market), _price, _outcome, _type);
        require(isOrderAmountValid(IMarket(_market), _attoshares), "Order must be a multiple of the market trade increment");
        _zeroXOrder.makerAddress = _maker;
        _zeroXOrder.makerAssetAmount = _attoshares;
        _zeroXOrder.takerAssetAmount = _attoshares;
        _zeroXOrder.expirationTimeSeconds = _expirationTimeSeconds;
        _zeroXOrder.salt = _salt;
        _zeroXOrder.makerAssetData = _assetData;
        _zeroXOrder.takerAssetData = encodeTakerAssetData();
        _orderHash = exchange.getOrderInfo(_zeroXOrder).orderHash;
    }

    function encodeEIP1271OrderWithHash(
        IExchange.Order memory _zeroXOrder,
        bytes32 _orderHash
    )
        public
        pure
        returns (bytes memory encoded)
    {
        return abi.encodeWithSelector(
            EIP1271_ORDER_WITH_HASH_SELECTOR,
            _zeroXOrder,
            _orderHash
        );
    }

    function () external payable {}
}

File 2 of 2 : Augur.sol
pragma experimental ABIEncoderV2;
pragma solidity 0.5.15;

contract IAugur {
    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function isKnownUniverse(IUniverse _universe) public view returns (bool);
    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool);
    function isTrustedSender(address _address) public returns (bool);
    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool);
    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool);
    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool);
    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool);
    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool);
    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool);
    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool);
    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool);
    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool);
    function logUniverseForked(IMarket _forkingMarket) public returns (bool);
    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool);
    function logParticipationTokensRedeemed(IUniverse universe, address _sender, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool);
    function logTimestampSet(uint256 _newTimestamp) public returns (bool);
    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool);
    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool);
    function isKnownFeeSender(address _feeSender) public view returns (bool);
    function lookup(bytes32 _key) public view returns (address);
    function getTimestamp() public view returns (uint256);
    function getMaximumMarketEndDate() public returns (uint256);
    function isKnownMarket(IMarket _market) public view returns (bool);
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 numOutcomes) public view returns (bytes32);
    function logValidityBondChanged(uint256 _validityBond) public returns (bool);
    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool);
    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool);
    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool);
    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256);
}

contract IAugurCreationDataGetter {
    struct MarketCreationData {
        string extraInfo;
        address marketCreator;
        bytes32[] outcomes;
        int256[] displayPrices;
        IMarket.MarketType marketType;
        uint256 recommendedTradeInterval;
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory);
}

contract IUniverseFactory {
    function createUniverse(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash, uint256[] memory _payoutNumerators) public returns (IUniverse);
}

library ContractExists {
    function exists(address _address) internal view returns (bool) {
        uint256 size;
        assembly { size := extcodesize(_address) }
        return size > 0;
    }
}

contract IOwnable {
    function getOwner() public view returns (address);
    function transferOwnership(address _newOwner) public returns (bool);
}

contract ITyped {
    function getTypeName() public view returns (bytes32);
}

contract ITime is ITyped {
    function getTimestamp() external view returns (uint256);
}

library SafeMathUint256 {
    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-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a <= b) {
            return a;
        } else {
            return b;
        }
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a >= b) {
            return a;
        } else {
            return b;
        }
    }

    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            uint256 x = (y + 1) / 2;
            z = y;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    function getUint256Min() internal pure returns (uint256) {
        return 0;
    }

    function getUint256Max() internal pure returns (uint256) {
        // 2 ** 256 - 1
        return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
    }

    function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
        return a % b == 0;
    }

    // Float [fixed point] Operations
    function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, b), base);
    }

    function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, base), b);
    }
}

interface IERC1155 {

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    /// Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    ///Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /// @dev MUST emit when an approval is updated.
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    /// @dev MUST emit when the URI is updated for a token ID.
    /// URIs are defined in RFC 3986.
    /// The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema".
    event URI(
        string value,
        uint256 indexed id
    );

    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external;

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if length of `_ids` is not the same as length of `_values`.
    ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external;

    /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
    /// @dev MUST emit the ApprovalForAll event on success.
    /// @param operator  Address to add to the set of authorized operators
    /// @param approved  True if the operator is approved, false to revoke approval
    function setApprovalForAll(address operator, bool approved) external;

    /// @notice Queries the approval status of an operator for a given owner.
    /// @param owner     The owner of the Tokens
    /// @param operator  Address of authorized operator
    /// @return           True if the operator is approved, false if not
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return        The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256);

    /// @notice Get the total supply of a Token.
    /// @param id     ID of the Token
    /// @return        The total supply of the Token type requested
    function totalSupply(uint256 id) external view returns (uint256);

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(
        address[] calldata owners,
        uint256[] calldata ids
    )
        external
        view
        returns (uint256[] memory balances_);
}

contract IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) public view returns (uint256);
    function transfer(address to, uint256 amount) public returns (bool);
    function transferFrom(address from, address to, uint256 amount) public returns (bool);
    function approve(address spender, uint256 amount) public returns (bool);
    function allowance(address owner, address spender) public view returns (uint256);

    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ICash is IERC20 {
}

contract IAffiliateValidator {
    function validateReference(address _account, address _referrer) external view returns (bool);
}

contract IAffiliates {
    function setFingerprint(bytes32 _fingerprint) external;
    function setReferrer(address _referrer) external;
    function getAccountFingerprint(address _account) external returns (bytes32);
    function getReferrer(address _account) external returns (address);
    function getAndValidateReferrer(address _account, IAffiliateValidator affiliateValidator) external returns (address);
    function affiliateValidators(address _affiliateValidator) external returns (bool);
}

contract IDisputeWindow is ITyped, IERC20 {
    function invalidMarketsTotal() external view returns (uint256);
    function validityBondTotal() external view returns (uint256);

    function incorrectDesignatedReportTotal() external view returns (uint256);
    function initialReportBondTotal() external view returns (uint256);

    function designatedReportNoShowsTotal() external view returns (uint256);
    function designatedReporterNoShowBondTotal() external view returns (uint256);

    function initialize(IAugur _augur, IUniverse _universe, uint256 _disputeWindowId, bool _participationTokensEnabled, uint256 _duration, uint256 _startTime) public;
    function trustedBuy(address _buyer, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getReputationToken() public view returns (IReputationToken);
    function getStartTime() public view returns (uint256);
    function getEndTime() public view returns (uint256);
    function getWindowId() public view returns (uint256);
    function isActive() public view returns (bool);
    function isOver() public view returns (bool);
    function onMarketFinalized() public;
    function redeem(address _account) public returns (bool);
}

contract IMarket is IOwnable {
    enum MarketType {
        YES_NO,
        CATEGORICAL,
        SCALAR
    }

    function initialize(IAugur _augur, IUniverse _universe, uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public;
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators) public view returns (bytes32);
    function doInitialReport(uint256[] memory _payoutNumerators, string memory _description, uint256 _additionalStake) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getDisputeWindow() public view returns (IDisputeWindow);
    function getNumberOfOutcomes() public view returns (uint256);
    function getNumTicks() public view returns (uint256);
    function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
    function getForkingMarket() public view returns (IMarket _market);
    function getEndTime() public view returns (uint256);
    function getWinningPayoutDistributionHash() public view returns (bytes32);
    function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningReportingParticipant() public view returns (IReportingParticipant);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getFinalizationTime() public view returns (uint256);
    function getInitialReporter() public view returns (IInitialReporter);
    function getDesignatedReportingEndTime() public view returns (uint256);
    function getValidityBondAttoCash() public view returns (uint256);
    function affiliateFeeDivisor() external view returns (uint256);
    function getNumParticipants() public view returns (uint256);
    function getDisputePacingOn() public view returns (bool);
    function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
    function recordMarketCreatorFees(uint256 _marketCreatorFees, address _sourceAccount, bytes32 _fingerprint) public returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function isFinalizedAsInvalid() public view returns (bool);
    function finalize() public returns (bool);
    function isFinalized() public view returns (bool);
    function getOpenInterest() public view returns (uint256);
}

contract IReportingParticipant {
    function getStake() public view returns (uint256);
    function getPayoutDistributionHash() public view returns (bytes32);
    function liquidateLosing() public;
    function redeem(address _redeemer) public returns (bool);
    function isDisavowed() public view returns (bool);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getMarket() public view returns (IMarket);
    function getSize() public view returns (uint256);
}

contract IDisputeCrowdsourcer is IReportingParticipant, IERC20 {
    function initialize(IAugur _augur, IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _crowdsourcerGeneration) public;
    function contribute(address _participant, uint256 _amount, bool _overload) public returns (uint256);
    function setSize(uint256 _size) public;
    function getRemainingToFill() public view returns (uint256);
    function correctSize() public returns (bool);
    function getCrowdsourcerGeneration() public view returns (uint256);
}

contract IInitialReporter is IReportingParticipant, IOwnable {
    function initialize(IAugur _augur, IMarket _market, address _designatedReporter) public;
    function report(address _reporter, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _initialReportStake) public;
    function designatedReporterShowed() public view returns (bool);
    function initialReporterWasCorrect() public view returns (bool);
    function getDesignatedReporter() public view returns (address);
    function getReportTimestamp() public view returns (uint256);
    function migrateToNewUniverse(address _designatedReporter) public;
    function returnRepFromDisavow() public;
}

contract IReputationToken is IERC20 {
    function migrateOutByPayout(uint256[] memory _payoutNumerators, uint256 _attotokens) public returns (bool);
    function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
    function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedDisputeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getTotalMigrated() public view returns (uint256);
    function getTotalTheoreticalSupply() public view returns (uint256);
    function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
}

contract IShareToken is ITyped, IERC1155 {
    function initialize(IAugur _augur) external;
    function initializeMarket(IMarket _market, uint256 _numOutcomes, uint256 _numTicks) public;
    function unsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value) public;
    function unsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) public;
    function claimTradingProceeds(IMarket _market, address _shareHolder, bytes32 _fingerprint) external returns (uint256[] memory _outcomeFees);
    function getMarket(uint256 _tokenId) external view returns (IMarket);
    function getOutcome(uint256 _tokenId) external view returns (uint256);
    function getTokenId(IMarket _market, uint256 _outcome) public pure returns (uint256 _tokenId);
    function getTokenIds(IMarket _market, uint256[] memory _outcomes) public pure returns (uint256[] memory _tokenIds);
    function buyCompleteSets(IMarket _market, address _account, uint256 _amount) external returns (bool);
    function buyCompleteSetsForTrade(IMarket _market, uint256 _amount, uint256 _longOutcome, address _longRecipient, address _shortRecipient) external returns (bool);
    function sellCompleteSets(IMarket _market, address _holder, address _recipient, uint256 _amount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function sellCompleteSetsForTrade(IMarket _market, uint256 _outcome, uint256 _amount, address _shortParticipant, address _longParticipant, address _shortRecipient, address _longRecipient, uint256 _price, address _sourceAccount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function totalSupplyForMarketOutcome(IMarket _market, uint256 _outcome) public view returns (uint256);
    function balanceOfMarketOutcome(IMarket _market, uint256 _outcome, address _account) public view returns (uint256);
    function lowestBalanceOfMarketOutcomes(IMarket _market, uint256[] memory _outcomes, address _account) public view returns (uint256);
}

contract IUniverse {
    function creationTime() external view returns (uint256);
    function marketBalance(address) external view returns (uint256);

    function fork() public returns (bool);
    function updateForkValues() public returns (bool);
    function getParentUniverse() public view returns (IUniverse);
    function createChildUniverse(uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getForkingMarket() public view returns (IMarket);
    function getForkEndTime() public view returns (uint256);
    function getForkReputationGoal() public view returns (uint256);
    function getParentPayoutDistributionHash() public view returns (bytes32);
    function getDisputeRoundDurationInSeconds(bool _initial) public view returns (uint256);
    function getOrCreateDisputeWindowByTimestamp(uint256 _timestamp, bool _initial) public returns (IDisputeWindow);
    function getOrCreateCurrentDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreateNextDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreatePreviousDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOpenInterestInAttoCash() public view returns (uint256);
    function getTargetRepMarketCapInAttoCash() public view returns (uint256);
    function getOrCacheValidityBond() public returns (uint256);
    function getOrCacheDesignatedReportStake() public returns (uint256);
    function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
    function getOrCacheMarketRepBond() public returns (uint256);
    function getOrCacheReportingFeeDivisor() public returns (uint256);
    function getDisputeThresholdForFork() public view returns (uint256);
    function getDisputeThresholdForDisputePacing() public view returns (uint256);
    function getInitialReportMinValue() public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getReportingFeeDivisor() public view returns (uint256);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningChildPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function isOpenInterestCash(address) public view returns (bool);
    function isForkingMarket() public view returns (bool);
    function getCurrentDisputeWindow(bool _initial) public view returns (IDisputeWindow);
    function getDisputeWindowStartTimeAndDuration(uint256 _timestamp, bool _initial) public view returns (uint256, uint256);
    function isParentOf(IUniverse _shadyChild) public view returns (bool);
    function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
    function isContainerForDisputeWindow(IDisputeWindow _shadyTarget) public view returns (bool);
    function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function migrateMarketOut(IUniverse _destinationUniverse) public returns (bool);
    function migrateMarketIn(IMarket _market, uint256 _cashBalance, uint256 _marketOI) public returns (bool);
    function decrementOpenInterest(uint256 _amount) public returns (bool);
    function decrementOpenInterestFromMarket(IMarket _market) public returns (bool);
    function incrementOpenInterest(uint256 _amount) public returns (bool);
    function getWinningChildUniverse() public view returns (IUniverse);
    function isForking() public view returns (bool);
    function deposit(address _sender, uint256 _amount, address _market) public returns (bool);
    function withdraw(address _recipient, uint256 _amount, address _market) public returns (bool);
    function createScalarMarket(uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, int256[] memory _prices, uint256 _numTicks, string memory _extraInfo) public returns (IMarket _newMarket);
}

contract IV2ReputationToken is IReputationToken {
    function parentUniverse() external returns (IUniverse);
    function burnForMarket(uint256 _amountToBurn) public returns (bool);
    function mintForWarpSync(uint256 _amountToMint, address _target) public returns (bool);
}

library Reporting {
    uint256 private constant DESIGNATED_REPORTING_DURATION_SECONDS = 1 days;
    uint256 private constant DISPUTE_ROUND_DURATION_SECONDS = 7 days;
    uint256 private constant INITIAL_DISPUTE_ROUND_DURATION_SECONDS = 1 days;
    uint256 private constant DISPUTE_WINDOW_BUFFER_SECONDS = 1 hours;
    uint256 private constant FORK_DURATION_SECONDS = 60 days;

    uint256 private constant BASE_MARKET_DURATION_MAXIMUM = 30 days; // A market of 30 day length can always be created
    uint256 private constant UPGRADE_CADENCE = 365 days;
    uint256 private constant INITIAL_UPGRADE_TIMESTAMP = 1627776000; // Aug 1st 2021

    uint256 private constant INITIAL_REP_SUPPLY = 11 * 10 ** 6 * 10 ** 18; // 11 Million REP

    uint256 private constant AFFILIATE_SOURCE_CUT_DIVISOR = 5; // The trader gets 20% of the affiliate fee when an affiliate fee is taken

    uint256 private constant DEFAULT_VALIDITY_BOND = 10 ether; // 10 Cash (Dai)
    uint256 private constant VALIDITY_BOND_FLOOR = 10 ether; // 10 Cash (Dai)
    uint256 private constant DEFAULT_REPORTING_FEE_DIVISOR = 10000; // .01% fees
    uint256 private constant MAXIMUM_REPORTING_FEE_DIVISOR = 10000; // Minimum .01% fees
    uint256 private constant MINIMUM_REPORTING_FEE_DIVISOR = 3; // Maximum 33.3~% fees. Note than anything less than a value of 2 here will likely result in bugs such as divide by 0 cases.

    uint256 private constant TARGET_INVALID_MARKETS_DIVISOR = 100; // 1% of markets are expected to be invalid
    uint256 private constant TARGET_INCORRECT_DESIGNATED_REPORT_MARKETS_DIVISOR = 100; // 1% of markets are expected to have an incorrect designate report
    uint256 private constant TARGET_DESIGNATED_REPORT_NO_SHOWS_DIVISOR = 20; // 5% of markets are expected to have a no show
    uint256 private constant TARGET_REP_MARKET_CAP_MULTIPLIER = 5; // We multiply and divide by constants since we may want to multiply by a fractional amount

    uint256 private constant FORK_THRESHOLD_DIVISOR = 40; // 2.5% of the total REP supply being filled in a single dispute bond will trigger a fork
    uint256 private constant MAXIMUM_DISPUTE_ROUNDS = 20; // We ensure that after 20 rounds of disputes a fork will occur
    uint256 private constant MINIMUM_SLOW_ROUNDS = 8; // We ensure that at least 8 dispute rounds take DISPUTE_ROUND_DURATION_SECONDS+ seconds to complete until the next round begins

    function getDesignatedReportingDurationSeconds() internal pure returns (uint256) { return DESIGNATED_REPORTING_DURATION_SECONDS; }
    function getInitialDisputeRoundDurationSeconds() internal pure returns (uint256) { return INITIAL_DISPUTE_ROUND_DURATION_SECONDS; }
    function getDisputeWindowBufferSeconds() internal pure returns (uint256) { return DISPUTE_WINDOW_BUFFER_SECONDS; }
    function getDisputeRoundDurationSeconds() internal pure returns (uint256) { return DISPUTE_ROUND_DURATION_SECONDS; }
    function getForkDurationSeconds() internal pure returns (uint256) { return FORK_DURATION_SECONDS; }
    function getBaseMarketDurationMaximum() internal pure returns (uint256) { return BASE_MARKET_DURATION_MAXIMUM; }
    function getUpgradeCadence() internal pure returns (uint256) { return UPGRADE_CADENCE; }
    function getInitialUpgradeTimestamp() internal pure returns (uint256) { return INITIAL_UPGRADE_TIMESTAMP; }
    function getDefaultValidityBond() internal pure returns (uint256) { return DEFAULT_VALIDITY_BOND; }
    function getValidityBondFloor() internal pure returns (uint256) { return VALIDITY_BOND_FLOOR; }
    function getTargetInvalidMarketsDivisor() internal pure returns (uint256) { return TARGET_INVALID_MARKETS_DIVISOR; }
    function getTargetIncorrectDesignatedReportMarketsDivisor() internal pure returns (uint256) { return TARGET_INCORRECT_DESIGNATED_REPORT_MARKETS_DIVISOR; }
    function getTargetDesignatedReportNoShowsDivisor() internal pure returns (uint256) { return TARGET_DESIGNATED_REPORT_NO_SHOWS_DIVISOR; }
    function getTargetRepMarketCapMultiplier() internal pure returns (uint256) { return TARGET_REP_MARKET_CAP_MULTIPLIER; }
    function getMaximumReportingFeeDivisor() internal pure returns (uint256) { return MAXIMUM_REPORTING_FEE_DIVISOR; }
    function getMinimumReportingFeeDivisor() internal pure returns (uint256) { return MINIMUM_REPORTING_FEE_DIVISOR; }
    function getDefaultReportingFeeDivisor() internal pure returns (uint256) { return DEFAULT_REPORTING_FEE_DIVISOR; }
    function getInitialREPSupply() internal pure returns (uint256) { return INITIAL_REP_SUPPLY; }
    function getAffiliateSourceCutDivisor() internal pure returns (uint256) { return AFFILIATE_SOURCE_CUT_DIVISOR; }
    function getForkThresholdDivisor() internal pure returns (uint256) { return FORK_THRESHOLD_DIVISOR; }
    function getMaximumDisputeRounds() internal pure returns (uint256) { return MAXIMUM_DISPUTE_ROUNDS; }
    function getMinimumSlowRounds() internal pure returns (uint256) { return MINIMUM_SLOW_ROUNDS; }
}

contract IAugurTrading {
    function lookup(bytes32 _key) public view returns (address);
    function logProfitLossChanged(IMarket _market, address _account, uint256 _outcome, int256 _netPosition, uint256 _avgPrice, int256 _realizedProfit, int256 _frozenFunds, int256 _realizedCost) public returns (bool);
    function logOrderCreated(IUniverse _universe, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logOrderCanceled(IUniverse _universe, IMarket _market, address _creator, uint256 _tokenRefund, uint256 _sharesRefund, bytes32 _orderId) public returns (bool);
    function logOrderFilled(IUniverse _universe, address _creator, address _filler, uint256 _price, uint256 _fees, uint256 _amountFilled, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logMarketVolumeChanged(IUniverse _universe, address _market, uint256 _volume, uint256[] memory _outcomeVolumes, uint256 _totalTrades) public returns (bool);
    function logZeroXOrderFilled(IUniverse _universe, IMarket _market, bytes32 _orderHash, bytes32 _tradeGroupId, uint8 _orderType, address[] memory _addressData, uint256[] memory _uint256Data) public returns (bool);
    function logZeroXOrderCanceled(address _universe, address _market, address _account, uint256 _outcome, uint256 _price, uint256 _amount, uint8 _type, bytes32 _orderHash) public;
}

contract IOrders {
    function saveOrder(uint256[] calldata _uints, bytes32[] calldata _bytes32s, Order.Types _type, IMarket _market, address _sender) external returns (bytes32 _orderId);
    function removeOrder(bytes32 _orderId) external returns (bool);
    function getMarket(bytes32 _orderId) public view returns (IMarket);
    function getOrderType(bytes32 _orderId) public view returns (Order.Types);
    function getOutcome(bytes32 _orderId) public view returns (uint256);
    function getAmount(bytes32 _orderId) public view returns (uint256);
    function getPrice(bytes32 _orderId) public view returns (uint256);
    function getOrderCreator(bytes32 _orderId) public view returns (address);
    function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderDataForCancel(bytes32 _orderId) public view returns (uint256, uint256, Order.Types, IMarket, uint256, address);
    function getOrderDataForLogs(bytes32 _orderId) public view returns (Order.Types, address[] memory _addressData, uint256[] memory _uint256Data);
    function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
    function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
    function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
    function getOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
    function getTotalEscrowed(IMarket _market) public view returns (uint256);
    function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
    function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
    function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled, uint256 _fill) external returns (bool);
    function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
}

library Order {
    using SafeMathUint256 for uint256;

    enum Types {
        Bid, Ask
    }

    enum TradeDirections {
        Long, Short
    }

    struct Data {
        // Contracts
        IMarket market;
        IAugur augur;
        IAugurTrading augurTrading;
        IShareToken shareToken;
        ICash cash;

        // Order
        bytes32 id;
        address creator;
        uint256 outcome;
        Order.Types orderType;
        uint256 amount;
        uint256 price;
        uint256 sharesEscrowed;
        uint256 moneyEscrowed;
        bytes32 betterOrderId;
        bytes32 worseOrderId;
    }

    function create(IAugur _augur, IAugurTrading _augurTrading, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data memory) {
        require(_outcome < _market.getNumberOfOutcomes(), "Order.create: Outcome is not within market range");
        require(_price != 0, "Order.create: Price may not be 0");
        require(_price < _market.getNumTicks(), "Order.create: Price is outside of market range");
        require(_attoshares > 0, "Order.create: Cannot use amount of 0");
        require(_creator != address(0), "Order.create: Creator is 0x0");

        IShareToken _shareToken = IShareToken(_augur.lookup("ShareToken"));

        return Data({
            market: _market,
            augur: _augur,
            augurTrading: _augurTrading,
            shareToken: _shareToken,
            cash: ICash(_augur.lookup("Cash")),
            id: 0,
            creator: _creator,
            outcome: _outcome,
            orderType: _type,
            amount: _attoshares,
            price: _price,
            sharesEscrowed: 0,
            moneyEscrowed: 0,
            betterOrderId: _betterOrderId,
            worseOrderId: _worseOrderId
        });
    }

    //
    // "public" functions
    //

    function getOrderId(Order.Data memory _orderData, IOrders _orders) internal view returns (bytes32) {
        if (_orderData.id == bytes32(0)) {
            bytes32 _orderId = calculateOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
            require(_orders.getAmount(_orderId) == 0, "Order.getOrderId: New order had amount. This should not be possible");
            _orderData.id = _orderId;
        }
        return _orderData.id;
    }

    function calculateOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) internal pure returns (bytes32) {
        return sha256(abi.encodePacked(_type, _market, _amount, _price, _sender, _blockNumber, _outcome, _moneyEscrowed, _sharesEscrowed));
    }

    function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
        return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
    }

    function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
        return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
    }

    function saveOrder(Order.Data memory _orderData, bytes32 _tradeGroupId, IOrders _orders) internal returns (bytes32) {
        getOrderId(_orderData, _orders);
        uint256[] memory _uints = new uint256[](5);
        _uints[0] = _orderData.amount;
        _uints[1] = _orderData.price;
        _uints[2] = _orderData.outcome;
        _uints[3] = _orderData.moneyEscrowed;
        _uints[4] = _orderData.sharesEscrowed;
        bytes32[] memory _bytes32s = new bytes32[](4);
        _bytes32s[0] = _orderData.betterOrderId;
        _bytes32s[1] = _orderData.worseOrderId;
        _bytes32s[2] = _tradeGroupId;
        _bytes32s[3] = _orderData.id;
        return _orders.saveOrder(_uints, _bytes32s, _orderData.orderType, _orderData.market, _orderData.creator);
    }
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

contract Augur is IAugur, IAugurCreationDataGetter {
    using SafeMathUint256 for uint256;
    using ContractExists for address;

    enum TokenType {
        ReputationToken,
        DisputeCrowdsourcer,
        ParticipationToken
    }

    event MarketCreated(IUniverse indexed universe, uint256 endTime, string extraInfo, IMarket market, address indexed marketCreator, address designatedReporter, uint256 feePerCashInAttoCash, int256[] prices, IMarket.MarketType marketType, uint256 numTicks, bytes32[] outcomes, uint256 noShowBond, uint256 timestamp);
    event InitialReportSubmitted(address indexed universe, address indexed reporter, address indexed market, address initialReporter, uint256 amountStaked, bool isDesignatedReporter, uint256[] payoutNumerators, string description, uint256 nextWindowStartTime, uint256 nextWindowEndTime, uint256 timestamp);
    event DisputeCrowdsourcerCreated(address indexed universe, address indexed market, address disputeCrowdsourcer, uint256[] payoutNumerators, uint256 size, uint256 disputeRound);
    event DisputeCrowdsourcerContribution(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountStaked, string description, uint256[] payoutNumerators, uint256 currentStake, uint256 stakeRemaining, uint256 disputeRound, uint256 timestamp);
    event DisputeCrowdsourcerCompleted(address indexed universe, address indexed market, address disputeCrowdsourcer, uint256[] payoutNumerators, uint256 nextWindowStartTime, uint256 nextWindowEndTime, bool pacingOn, uint256 totalRepStakedInPayout, uint256 totalRepStakedInMarket, uint256 disputeRound, uint256 timestamp);
    event InitialReporterRedeemed(address indexed universe, address indexed reporter, address indexed market, address initialReporter, uint256 amountRedeemed, uint256 repReceived, uint256[] payoutNumerators, uint256 timestamp);
    event DisputeCrowdsourcerRedeemed(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountRedeemed, uint256 repReceived, uint256[] payoutNumerators, uint256 timestamp);
    event ReportingParticipantDisavowed(address indexed universe, address indexed market, address reportingParticipant);
    event MarketParticipantsDisavowed(address indexed universe, address indexed market);
    event MarketFinalized(address indexed universe, address indexed market, uint256 timestamp, uint256[] winningPayoutNumerators);
    event MarketMigrated(address indexed market, address indexed originalUniverse, address indexed newUniverse);
    event UniverseForked(address indexed universe, IMarket forkingMarket);
    event UniverseCreated(address indexed parentUniverse, address indexed childUniverse, uint256[] payoutNumerators, uint256 creationTimestamp);
    event CompleteSetsPurchased(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets, uint256 timestamp);
    event CompleteSetsSold(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets, uint256 fees, uint256 timestamp);
    event TradingProceedsClaimed(address indexed universe, address indexed sender, address market, uint256 outcome, uint256 numShares, uint256 numPayoutTokens, uint256 fees, uint256 timestamp);
    event TokensTransferred(address indexed universe, address token, address indexed from, address indexed to, uint256 value, TokenType tokenType, address market);
    event TokensMinted(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market, uint256 totalSupply);
    event TokensBurned(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market, uint256 totalSupply);
    event TokenBalanceChanged(address indexed universe, address indexed owner, address token, TokenType tokenType, address market, uint256 balance, uint256 outcome);
    event DisputeWindowCreated(address indexed universe, address disputeWindow, uint256 startTime, uint256 endTime, uint256 id, bool initial);
    event InitialReporterTransferred(address indexed universe, address indexed market, address from, address to);
    event MarketTransferred(address indexed universe, address indexed market, address from, address to);
    event MarketOIChanged(address indexed universe, address indexed market, uint256 marketOI);
    event ParticipationTokensRedeemed(address indexed universe, address indexed disputeWindow, address indexed account, uint256 attoParticipationTokens, uint256 feePayoutShare, uint256 timestamp);
    event TimestampSet(uint256 newTimestamp);
    event ValidityBondChanged(address indexed universe, uint256 validityBond);
    event DesignatedReportStakeChanged(address indexed universe, uint256 designatedReportStake);
    event NoShowBondChanged(address indexed universe, uint256 noShowBond);
    event ReportingFeeChanged(address indexed universe, uint256 reportingFee);
    event ShareTokenBalanceChanged(address indexed universe, address indexed account, address indexed market, uint256 outcome, uint256 balance);
    event MarketRepBondTransferred(address indexed universe, address market, address from, address to);
    event WarpSyncDataUpdated(address indexed universe, uint256 warpSyncHash, uint256 marketEndTime);

    event RegisterContract(address contractAddress, bytes32 key);
    event FinishDeployment();

    mapping(address => bool) private markets;
    mapping(address => bool) private universes;
    mapping(address => bool) private crowdsourcers;
    mapping(address => bool) private trustedSender;

    mapping(address => MarketCreationData) private marketCreationData;

    address public uploader;
    mapping(bytes32 => address) private registry;

    ITime public time;
    IUniverse public genesisUniverse;

    uint256 public forkCounter;
    mapping (address => uint256) universeForkIndex;

    uint256 public upgradeTimestamp = Reporting.getInitialUpgradeTimestamp();

    int256 private constant DEFAULT_MIN_PRICE = 0;
    int256 private constant DEFAULT_MAX_PRICE = 1 ether;

    uint256 constant public TRADE_INTERVAL_VALUE = 10 ** 19; // Trade value of 10 DAI
    uint256 constant public MIN_TRADE_INTERVAL = 10**14; // We ignore "dust" portions of the min interval and for huge scalars have a larger min value
    uint256 constant public DEFAULT_RECOMMENDED_TRADE_INTERVAL = 10**17;
    uint256 private constant MAX_NUM_TICKS = 2 ** 256 - 2;

    ICash public cash;

    modifier onlyUploader() {
        require(msg.sender == uploader);
        _;
    }

    constructor() public {
        uploader = msg.sender;
    }

    //
    // Registry
    //

    function registerContract(bytes32 _key, address _address) public onlyUploader returns (bool) {
        require(registry[_key] == address(0), "Augur.registerContract: key has already been used in registry");
        require(_address.exists());
        registry[_key] = _address;
        if (_key == "ShareToken" || _key == "MarketFactory" || _key == "EthExchange") {
            trustedSender[_address] = true;
        } else if (_key == "Time") {
            time = ITime(_address);
        } else if (_key == "Cash") {
            cash = ICash(_address);
        }
        emit RegisterContract(_address, _key);
        return true;
    }

    /**
     * @notice Find the contract address for a particular key
     * @param _key The key to lookup
     * @return the address of the registered contract if one exists for the given key
     */
    function lookup(bytes32 _key) public view returns (address) {
        return registry[_key];
    }

    function finishDeployment() public onlyUploader returns (bool) {
        uploader = address(1);
        emit FinishDeployment();
        return true;
    }

    //
    // Universe
    //

    function createGenesisUniverse() public onlyUploader returns (IUniverse) {
        require(genesisUniverse == IUniverse(0));
        genesisUniverse = createUniverse(IUniverse(0), bytes32(0), new uint256[](0));
        return genesisUniverse;
    }

    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse) {
        IUniverse _parentUniverse = getAndValidateUniverse(msg.sender);
        return createUniverse(_parentUniverse, _parentPayoutDistributionHash, _parentPayoutNumerators);
    }

    function createUniverse(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) private returns (IUniverse) {
        IUniverseFactory _universeFactory = IUniverseFactory(registry["UniverseFactory"]);
        IUniverse _newUniverse = _universeFactory.createUniverse(_parentUniverse, _parentPayoutDistributionHash, _parentPayoutNumerators);
        universes[address(_newUniverse)] = true;
        trustedSender[address(_newUniverse)] = true;
        emit UniverseCreated(address(_parentUniverse), address(_newUniverse), _parentPayoutNumerators, getTimestamp());
        return _newUniverse;
    }

    function isKnownUniverse(IUniverse _universe) public view returns (bool) {
        return universes[address(_universe)];
    }

    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256) {
        return universeForkIndex[address(_universe)];
    }

    //
    // Crowdsourcers
    //

    function isKnownCrowdsourcer(IDisputeCrowdsourcer _crowdsourcer) public view returns (bool) {
        return crowdsourcers[address(_crowdsourcer)];
    }

    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        crowdsourcers[_disputeCrowdsourcer] = true;
        emit DisputeCrowdsourcerCreated(address(_universe), _market, _disputeCrowdsourcer, _payoutNumerators, _size, _disputeRound);
        return true;
    }

    function isKnownFeeSender(address _feeSender) public view returns (bool) {
        return _feeSender == registry["ShareToken"] || markets[_feeSender];
    }

    //
    // Transfer
    //

    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool) {
        require(trustedSender[msg.sender]);
        require(cash.transferFrom(_from, _to, _amount));
        return true;
    }

    function isTrustedSender(address _address) public returns (bool) {
        return trustedSender[_address];
    }

    //
    // Time
    //

    /// @notice Returns Augur’s internal Unix timestamp.
    /// @return (uint256) Augur’s internal Unix timestamp
    function getTimestamp() public view returns (uint256) {
        return time.getTimestamp();
    }

    //
    // Markets
    //

    function isKnownMarket(IMarket _market) public view returns (bool) {
        return markets[address(_market)];
    }

    function getMaximumMarketEndDate() public returns (uint256) {
        uint256 _now = getTimestamp();
        while (_now > upgradeTimestamp) {
            upgradeTimestamp = upgradeTimestamp.add(Reporting.getUpgradeCadence());
        }
        uint256 _upgradeCadenceDurationEndTime = upgradeTimestamp;
        uint256 _baseDurationEndTime = _now + Reporting.getBaseMarketDurationMaximum();
        return _baseDurationEndTime.max(_upgradeCadenceDurationEndTime);
    }

    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 _numOutcomes) public view returns (bytes32) {
        uint256 _sum = 0;
        // This is to force an Invalid report to be entirely payed out to Invalid
        require(_payoutNumerators[0] == 0 || _payoutNumerators[0] == _numTicks);
        require(_payoutNumerators.length == _numOutcomes, "Augur.derivePayoutDistributionHash: Malformed payout length");
        for (uint256 i = 0; i < _payoutNumerators.length; i++) {
            uint256 _value = _payoutNumerators[i];
            _sum = _sum.add(_value);
        }
        require(_sum == _numTicks, "Augur.derivePayoutDistributionHash: Malformed payout sum");
        return keccak256(abi.encodePacked(_payoutNumerators));
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory) {
        return marketCreationData[address(_market)];
    }

    function getMarketType(IMarket _market) public view returns (IMarket.MarketType _marketType) {
        return marketCreationData[address(_market)].marketType;
    }

    function getMarketOutcomes(IMarket _market) public view returns (bytes32[] memory _outcomes) {
        return marketCreationData[address(_market)].outcomes;
    }

    function getMarketRecommendedTradeInterval(IMarket _market) public view returns (uint256) {
        return marketCreationData[address(_market)].recommendedTradeInterval;
    }

    //
    // Logging
    //

    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        markets[address(_market)] = true;
        int256[] memory _prices = new int256[](2);
        _prices[0] = DEFAULT_MIN_PRICE;
        _prices[1] = DEFAULT_MAX_PRICE;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].outcomes = _outcomes;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.CATEGORICAL;
        marketCreationData[address(_market)].recommendedTradeInterval = DEFAULT_RECOMMENDED_TRADE_INTERVAL;
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.CATEGORICAL, 100, _outcomes, _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        markets[address(_market)] = true;
        int256[] memory _prices = new int256[](2);
        _prices[0] = DEFAULT_MIN_PRICE;
        _prices[1] = DEFAULT_MAX_PRICE;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.YES_NO;
        marketCreationData[address(_market)].recommendedTradeInterval = DEFAULT_RECOMMENDED_TRADE_INTERVAL;
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.YES_NO, 100, new bytes32[](0), _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        require(_prices.length == 2);
        require(_prices[0] < _prices[1]);
        uint256 _priceRange = uint256(_prices[1] - _prices[0]);
        require(_priceRange > _numTicks);
        markets[address(_market)] = true;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].displayPrices = _prices;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.SCALAR;
        marketCreationData[address(_market)].recommendedTradeInterval = getTradeInterval(_priceRange, _numTicks);
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.SCALAR, _numTicks, new bytes32[](0), _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function getTradeInterval(uint256 _displayRange, uint256 _numTicks) public pure returns (uint256) {
        // Handle Warp Sync Market
        if (_numTicks == MAX_NUM_TICKS) {
            return MIN_TRADE_INTERVAL;
        }
        uint256 _displayAmount = TRADE_INTERVAL_VALUE.mul(10**18).div(_displayRange);
        uint256 _displayInterval = MIN_TRADE_INTERVAL;
        while (_displayInterval < _displayAmount) {
            _displayInterval = _displayInterval.mul(10);
        }
        _displayAmount = _displayInterval;
        return _displayInterval.mul(_displayRange).div(_numTicks).div(10**18);
    }

    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit InitialReportSubmitted(address(_universe), _reporter, _market, _initialReporter, _amountStaked, _isDesignatedReporter, _payoutNumerators, _description, _nextWindowStartTime, _nextWindowEndTime, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory _description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit DisputeCrowdsourcerContribution(address(_universe), _reporter, _market, _disputeCrowdsourcer, _amountStaked, _description, _payoutNumerators, _currentStake, _stakeRemaining, _disputeRound, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit DisputeCrowdsourcerCompleted(address(_universe), _market, _disputeCrowdsourcer, _payoutNumerators, _nextWindowStartTime, _nextWindowEndTime, _pacingOn, _totalRepStakedInPayout, _totalRepStakedInMarket, _disputeRound, getTimestamp());
        return true;
    }

    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
        emit InitialReporterRedeemed(address(_universe), _reporter, _market, msg.sender, _amountRedeemed, _repReceived, _payoutNumerators, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        emit DisputeCrowdsourcerRedeemed(address(_universe), _reporter, _market, address(_disputeCrowdsourcer), _amountRedeemed, _repReceived, _payoutNumerators, getTimestamp());
        return true;
    }

    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
        emit ReportingParticipantDisavowed(address(_universe), address(_market), msg.sender);
        return true;
    }

    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketParticipantsDisavowed(address(_universe), address(_market));
        return true;
    }

    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketFinalized(address(_universe), address(_market), getTimestamp(), _winningPayoutNumerators);
        return true;
    }

    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool) {
        IUniverse _newUniverse = IUniverse(msg.sender);
        require(isKnownUniverse(_newUniverse));
        emit MarketMigrated(address(_market), address(_originalUniverse), address(_newUniverse));
        return true;
    }

    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool) {
        require(msg.sender == registry["ShareToken"] || (isKnownUniverse(_universe) && _universe.isOpenInterestCash(msg.sender)));
        emit CompleteSetsPurchased(address(_universe), address(_market), _account, _numCompleteSets, getTimestamp());
        return true;
    }

    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit CompleteSetsSold(address(_universe), address(_market), _account, _numCompleteSets, _fees, getTimestamp());
        return true;
    }

    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit MarketOIChanged(address(_universe), address(_market), _market.getOpenInterest());
        return true;
    }

    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit TradingProceedsClaimed(address(_universe), _sender, _market, _outcome, _numShares, _numPayoutTokens, _fees, getTimestamp());
        return true;
    }

    function logUniverseForked(IMarket _forkingMarket) public returns (bool) {
        require(isKnownUniverse(IUniverse(msg.sender)));
        forkCounter += 1;
        universeForkIndex[msg.sender] = forkCounter;
        emit UniverseForked(msg.sender, _forkingMarket);
        return true;
    }

    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.ReputationToken, address(0), _fromBalance, _toBalance, 0);
        return true;
    }

    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _fromBalance, _toBalance, 0);
        return true;
    }

    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.ReputationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.ReputationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit ShareTokenBalanceChanged(address(_market.getUniverse()), _account, address(_market), _outcome, _balance);
        return true;
    }

    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _totalSupply, _balance, 0);
        return true;
    }

    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _totalSupply, _balance, 0);
        return true;
    }

    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool) {
        require(isKnownUniverse(IUniverse(msg.sender)));
        emit DisputeWindowCreated(msg.sender, address(_disputeWindow), _disputeWindow.getStartTime(), _disputeWindow.getEndTime(), _id, _initial);
        return true;
    }

    function logParticipationTokensRedeemed(IUniverse _universe, address _account, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        emit ParticipationTokensRedeemed(address(_universe), msg.sender, _account, _attoParticipationTokens, _feePayoutShare, getTimestamp());
        return true;
    }

    function logTimestampSet(uint256 _newTimestamp) public returns (bool) {
        require(msg.sender == registry["Time"]);
        emit TimestampSet(_newTimestamp);
        return true;
    }

    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(_market));
        require(msg.sender == address(_market.getInitialReporter()));
        emit InitialReporterTransferred(address(_universe), address(_market), _from, _to);
        return true;
    }

    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketTransferred(address(_universe), address(_market), _from, _to);
        return true;
    }

    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.ParticipationToken, address(0), _fromBalance, _toBalance, 0);
        return true;
    }

    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.ParticipationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.ParticipationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logTokensTransferred(address _universe, address _token, address _from, address _to, uint256 _amount, TokenType _tokenType, address _market, uint256 _fromBalance, uint256 _toBalance, uint256 _outcome) private returns (bool) {
        emit TokensTransferred(_universe, _token, _from, _to, _amount, _tokenType, _market);
        emit TokenBalanceChanged(_universe, _from, _token, _tokenType, _market, _fromBalance, _outcome);
        emit TokenBalanceChanged(_universe, _to, _token, _tokenType, _market, _toBalance, _outcome);
        return true;
    }

    function logTokensBurned(address _universe, address _token, address _target, uint256 _amount, TokenType _tokenType, address _market, uint256 _totalSupply, uint256 _balance, uint256 _outcome) private returns (bool) {
        emit TokensBurned(_universe, _token, _target, _amount, _tokenType, _market, _totalSupply);
        emit TokenBalanceChanged(_universe, _target, _token, _tokenType, _market, _balance, _outcome);
        return true;
    }

    function logTokensMinted(address _universe, address _token, address _target, uint256 _amount, TokenType _tokenType, address _market, uint256 _totalSupply, uint256 _balance, uint256 _outcome) private returns (bool) {
        emit TokensMinted(_universe, _token, _target, _amount, _tokenType, _market, _totalSupply);
        emit TokenBalanceChanged(_universe, _target, _token, _tokenType, _market, _balance, _outcome);
        return true;
    }

    function logValidityBondChanged(uint256 _validityBond) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit ValidityBondChanged(address(_universe), _validityBond);
        return true;
    }

    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit DesignatedReportStakeChanged(address(_universe), _designatedReportStake);
        return true;
    }

    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit NoShowBondChanged(address(_universe), _noShowBond);
        return true;
    }

    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit ReportingFeeChanged(address(_universe), _reportingFee);
        return true;
    }

    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool) {
        require(isKnownMarket(IMarket(msg.sender)));
        emit MarketRepBondTransferred(_universe, msg.sender, _from, _to);
    }

    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool) {
        require(msg.sender == registry["WarpSync"]);
        emit WarpSyncDataUpdated(_universe, _warpSyncHash, _marketEndTime);
    }

    function getAndValidateUniverse(address _untrustedUniverse) internal view returns (IUniverse) {
        IUniverse _universe = IUniverse(_untrustedUniverse);
        require(isKnownUniverse(_universe));
        return _universe;
    }
}

Settings
{
  "remappings": [
    "ROOT=/home/achapman/augur/packages/augur-core/src/contracts//"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200,
    "details": {
      "yul": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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"},{"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":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"EIP1271_ORDER_WITH_HASH_SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_DOMAIN_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"askBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"augur","outputs":[{"internalType":"contract IAugur","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"augurTrading","outputs":[{"internalType":"contract IAugurTrading","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances_","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"bidBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order[]","name":"_orders","type":"tuple[]"},{"internalType":"bytes[]","name":"_signatures","type":"bytes[]"},{"internalType":"uint256","name":"_maxProtocolFeeDai","type":"uint256"}],"name":"cancelOrders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cash","outputs":[{"internalType":"contract ICash","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sender","type":"address"}],"name":"cashAvailableForTransferFrom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_attoshares","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"_salt","type":"uint256"}],"name":"createZeroXOrder","outputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"uint8","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_attoshares","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"_salt","type":"uint256"}],"name":"createZeroXOrderFor","outputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"creatorHasFundsForTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"decodeAssetData","outputs":[{"internalType":"bytes4","name":"_assetProxyId","type":"bytes4"},{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_tokenValues","type":"uint256[]"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"decodeTradeAssetData","outputs":[{"internalType":"bytes4","name":"_assetProxyId","type":"bytes4"},{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_tokenValues","type":"uint256[]"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"name":"encodeAssetData","outputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"name":"encodeEIP1271OrderWithHash","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_numOrders","type":"uint256"},{"internalType":"uint256","name":"_gasPrice","type":"uint256"}],"name":"estimateProtocolFeeCostInCash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethExchange","outputs":[{"internalType":"contract IUniswapV2Pair","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"exchange","outputs":[{"internalType":"contract IExchange","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fillOrder","outputs":[{"internalType":"contract IFillOrder","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"}],"name":"getTokenIdFromOrder","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTransferFromAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"getZeroXTradeTokenData","outputs":[{"internalType":"contract IERC1155","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IAugur","name":"_augur","type":"address"},{"internalType":"contract IAugurTrading","name":"_augurTrading","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint256","name":"_orderAmount","type":"uint256"}],"name":"isOrderAmountValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"}],"name":"parseOrderData","outputs":[{"components":[{"internalType":"address","name":"marketAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint8","name":"outcome","type":"uint8"},{"internalType":"uint8","name":"orderType","type":"uint8"}],"internalType":"struct IZeroXTrade.AugurOrderData","name":"_data","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"shareToken","outputs":[{"internalType":"contract IShareToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token0IsCash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_requestedFillAmount","type":"uint256"},{"internalType":"bytes32","name":"_fingerprint","type":"bytes32"},{"internalType":"bytes32","name":"_tradeGroupId","type":"bytes32"},{"internalType":"uint256","name":"_maxProtocolFeeDai","type":"uint256"},{"internalType":"uint256","name":"_maxTrades","type":"uint256"},{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order[]","name":"_orders","type":"tuple[]"},{"internalType":"bytes[]","name":"_signatures","type":"bytes[]"}],"name":"trade","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"unpackTokenId","outputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"}]

60806040526000805461ffff1916905534801561001b57600080fd5b506147d18061002b6000396000f3fe6080604052600436106102445760003560e01c80637a0d8f8a11610139578063afc6d8ba116100b6578063e264cff11161007a578063e264cff1146106c1578063e306f779146106e1578063e985e9c5146106f6578063ee89dab414610716578063f242432a1461072b578063f94515f01461074b57610244565b8063afc6d8ba1461061e578063b3ca8e251461063e578063bd85b0391461065e578063d2f7265a1461067e578063e186955b1461069357610244565b8063961be391116100fd578063961be391146105925780639c6fbce5146105a7578063a22cb465146105c7578063ad5c22c8146105e7578063ad5c46481461060957610244565b80637a0d8f8a146105025780637b66c82a146105175780637cb111251461052c57806385f8c2591461055d5780638e1bfa731461057d57610244565b80633fc6f627116101c757806353e569a11161018b57806353e569a1146104695780635c1ad8441461048b5780635e03e6e4146104a057806361a4760b146104c05780636c9fa59e146104ed57610244565b80633fc6f627146103bc578063485cc955146103dc5780634bf1ee87146103fc5780634e1273f41461041c5780634ea96c301461044957610244565b8063235f9e081161020e578063235f9e081461030c57806326afd2e8146103395780632c52071c146103695780632eb2c2d6146103895780632f562016146103a957610244565b8062ee354214610246578062fdd58e1461027d57806309c1df9f146102aa5780631d4b44bb146102cc5780631f981bde146102ec575b005b34801561025257600080fd5b50610266610261366004613abb565b61076b565b60405161027492919061415d565b60405180910390f35b34801561028957600080fd5b5061029d610298366004613816565b6107ad565b6040516102749190614262565b3480156102b657600080fd5b506102bf610831565b6040516102749190614257565b3480156102d857600080fd5b5061029d6102e736600461362e565b61083f565b3480156102f857600080fd5b5061029d610307366004613841565b610967565b34801561031857600080fd5b5061032c610327366004613841565b6109a0565b60405161027491906142e5565b34801561034557600080fd5b50610359610354366004613c27565b610b06565b6040516102749493929190614176565b34801561037557600080fd5b5061029d6103843660046137c6565b610b2d565b34801561039557600080fd5b506102446103a4366004613666565b610cf2565b61029d6103b7366004613c57565b610d6b565b3480156103c857600080fd5b5061029d6103d7366004613ce7565b610f83565b3480156103e857600080fd5b506102446103f7366004613aed565b610ff7565b34801561040857600080fd5b5061032c610417366004613b91565b611678565b34801561042857600080fd5b5061043c610437366004613915565b6116cf565b60405161027491906141d4565b34801561045557600080fd5b506102bf61046436600461397d565b6117d7565b34801561047557600080fd5b5061047e611ba8565b6040516102749190614077565b34801561049757600080fd5b5061047e611bb7565b3480156104ac57600080fd5b5061029d6104bb3660046137c6565b611bc6565b3480156104cc57600080fd5b506104e06104db366004613b5f565b611d1f565b60405161027491906145d3565b3480156104f957600080fd5b5061047e611d9e565b34801561050e57600080fd5b5061047e611dad565b34801561052357600080fd5b506102bf611dbc565b34801561053857600080fd5b5061054c610547366004613abb565b611dcc565b604051610274959493929190614280565b34801561056957600080fd5b5061029d610578366004613d2b565b611f42565b34801561058957600080fd5b5061047e611fc2565b34801561059e57600080fd5b5061047e611fd1565b3480156105b357600080fd5b506102bf6105c2366004613816565b611fe0565b3480156105d357600080fd5b506102446105e2366004613799565b61207f565b3480156105f357600080fd5b506105fc612097565b604051610274919061426b565b34801561061557600080fd5b5061047e6120a2565b34801561062a57600080fd5b5061029d610639366004613b5f565b6120b1565b34801561064a57600080fd5b5061054c610659366004613abb565b6120f4565b34801561066a57600080fd5b5061029d610679366004613c27565b61215e565b34801561068a57600080fd5b5061047e612164565b34801561069f57600080fd5b506106b36106ae366004613893565b612173565b604051610274929190614623565b3480156106cd57600080fd5b506102bf6106dc366004613b91565b612287565b3480156106ed57600080fd5b5061029d612314565b34801561070257600080fd5b506102bf61071136600461362e565b61231a565b34801561072257600080fd5b506102bf612322565b34801561073757600080fd5b50610244610746366004613720565b61232b565b34801561075757600080fd5b506106b3610766366004613d56565b61239e565b600080600080606080606061077f88611dcc565b945094509450945094508260008151811061079657fe5b602002602001015195508396505050505050915091565b60008060008060006107be86610b06565b935093509350935060008160ff1660018111156107d757fe5b905060018160018111156107e757fe5b1415610805576107f988868587611bc6565b9550505050505061082b565b600081600181111561081357fe5b1415610825576107f988868587610b2d565b50505050505b92915050565b600054610100900460ff1690565b6005546040516370a0823160e01b815260009182916001600160a01b03909116906370a0823190610874908790600401614077565b60206040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c49190810190613c3f565b600554604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e906108fc90889088906004016140f7565b60206040518083038186803b15801561091457600080fd5b505afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061094c9190810190613c3f565b905061095e828263ffffffff6123c816565b95945050505050565b60006060858585856040516020016109829493929190613f76565b60408051601f19818403018152919052602001519695505050505050565b60408051600380825260808201909252606091829190816020015b60608152602001906001900390816109bb5750506040805160038082526080820190925291925060609190602082018380388339019050509050610a01878787876123df565b82600081518110610a0e57fe5b6020026020010181905250610a216124d4565b82600181518110610a2e57fe5b6020026020010181905250610a41612533565b82600281518110610a4e57fe5b6020026020010181905250600181600081518110610a6857fe5b602002602001018181525050600081600181518110610a8357fe5b602002602001018181525050600081600281518110610a9e57fe5b60200260200101818152505060606394cfcdd760e01b8284604051602401610ac79291906141e7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529350505050949350505050565b606081901c9169ffffffffffffffffffff601083901c169160ff600882901c811692911690565b600080846001600160a01b03166327ce5b8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6957600080fd5b505afa158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ba19190810190613c3f565b9050606060018203604051908082528060200260200182016040528015610bd2578160200160208202803883390190505b5090506000805b60018403811015610c1a578660ff16811415610bf6576001909101905b81838281518110610c0357fe5b602090810291909101015260019182019101610bd9565b5060065460405163f8a2167b60e01b81526000916001600160a01b03169063f8a2167b90610c50908b9087908e906004016142f8565b60206040518083038186803b158015610c6857600080fd5b505afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ca09190810190613c3f565b600454909150600090610cbd908b906001600160a01b031661083f565b90506000610cd1828963ffffffff6125b316565b9050610ce3838263ffffffff6125c816565b9b9a5050505050505050505050565b600054610100900460ff16610d0657600080fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89898989604051610d5994939291906141a2565b60405180910390a45050505050505050565b600080835111610d7a57600080fd5b6000805461ff00191661010017815560075460408051631ce4c78b60e01b815290518b9392610e1b923a926001600160a01b0390921691631ce4c78b91600480820192602092909190829003018186803b158015610dd757600080fd5b505afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0f9190810190613c3f565b9063ffffffff6125e116565b9050610e36610e30828863ffffffff6125e116565b88612608565b60005b855181108015610e4857508215155b15610ef957610e55613118565b868281518110610e6157fe5b60200260200101519050610e7581856127d7565b610e7d6131ab565b610e9c8286898681518110610e8e57fe5b6020026020010151876128f8565b9050806020015160001415610eb2575050610ef1565b6000610ec58383602001518f8f336129f1565b9050610ed7868263ffffffff612b3d16565b600019909a0199955089610eed57505050610ef9565b5050505b600101610e39565b506000805461ff00191690554715610f76576000336001600160a01b031647604051610f2490613ffe565b60006040518083038185875af1925050503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5050905080610f7457600080fd5b505b5098975050505050505050565b600080610fd883600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b90506000610fec828663ffffffff6125e116565b905061095e81612b52565b60005460ff161561100757600080fd5b61100f612c37565b600280546001600160a01b038085166001600160a01b03199283168117909355600380549185169190921617905560405163f39ec1f760e01b815263f39ec1f79061105c90600401614494565b60206040518083038186803b15801561107457600080fd5b505afa158015611088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110ac9190810190613612565b600580546001600160a01b0319166001600160a01b039283161790819055166110d457600080fd5b60405163f39ec1f760e01b81526001600160a01b0383169063f39ec1f7906110fe906004016144b5565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190613612565b600680546001600160a01b0319166001600160a01b0392831617908190551661117657600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906111a0906004016144fc565b60206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f09190810190613612565b600780546001600160a01b0319166001600160a01b0392831617908190551661121857600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f790611242906004016144cb565b60206040518083038186803b15801561125a57600080fd5b505afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112929190810190613612565b600480546001600160a01b0319166001600160a01b039283161790819055166112ba57600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906112e4906004016144a4565b60206040518083038186803b1580156112fc57600080fd5b505afa158015611310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113349190810190613612565b600980546001600160a01b0319166001600160a01b0392831617905560405163f39ec1f760e01b815260009184169063f39ec1f790611375906004016144e0565b60206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c59190810190613612565b60095460055460405163e6a4390560e01b81529293506000926001600160a01b038086169363e6a4390593611402939183169216906004016140f7565b60206040518083038186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114529190810190613612565b90506001600160a01b0381166114ee576009546005546040516364e329cb60e11b81526001600160a01b038086169363c9c6539693611499939183169216906004016140f7565b602060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114eb9190810190613612565b90505b600880546001600160a01b0319166001600160a01b03838116919091179182905560055460408051630dfe168160e01b815290519183169390921691630dfe1681916004808301926020929190829003018186803b15801561154f57600080fd5b505afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115879190810190613612565b6001600160a01b031614600960146101000a81548160ff0219169083151502179055506040516020016115b990614001565b60408051601f1981840301815282825280516020918201208383018352600b84526a0c1e08141c9bdd1bd8dbdb60aa1b938201939093528151808301835260018152601960f91b90820152905161165792917ff0f24618f4c4be1e62e026fb039a20ef96f4495294817d1027ffaa6d1f70e61e917fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a591309101613fc7565b60408051601f19818403018152919052805160209091012060015550505050565b6060633efe50c860e01b8383604051602401611695929190614623565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905092915050565b6040805184815260208086028201019091526060908480156116fb578160200160208202803883390190505b50905060005b848110156117ce573062fdd58e87878481811061171a57fe5b905060200201602061172f91908101906135f6565b86868581811061173b57fe5b905060200201356040518363ffffffff1660e01b815260040161175f92919061415d565b60206040518083038186803b15801561177757600080fd5b505afa15801561178b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117af9190810190613c3f565b8282815181106117bb57fe5b6020908102919091010152600101611701565b50949350505050565b600082518451146117e757600080fd5b600061183b3a600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b905061185a6118548651836125e190919063ffffffff16565b84612608565b6000805461ff0019166101001781555b8551811015611b205761187b613118565b86828151811061188757fe5b60200260200101519050606086838151811061189f57fe5b6020026020010151905081600001516001600160a01b0316336001600160a01b0316146118cb57600080fd5b6118d36131da565b600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990611903908690600401614610565b60606040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119539190810190613b1a565b9050600061197282604001518560a00151612b3d90919063ffffffff16565b600754604051634da26aab60e11b81529192506001600160a01b031690639b44d5569088906119a990889086908990600401614645565b60a0604051808303818588803b1580156119c257600080fd5b505af11580156119d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052506119fb9190810190613aff565b50611a046131fa565b611a0d85611d1f565b9050600081600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a869190810190613612565b6003548351885160408087015160208089015160608a0151918c01519351632bbddc3760e11b81529798506001600160a01b039096169663577bb86e96611adc968a96909590949391928d929190600401614111565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506001909801975061186a9650505050505050565b506000805461ff00191690554715611b9d576000336001600160a01b031647604051611b4b90613ffe565b60006040518083038185875af1925050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611b9b57600080fd5b505b506001949350505050565b6008546001600160a01b031681565b6004546001600160a01b031681565b60065460405163d64c62f360e01b815260009182916001600160a01b039091169063d64c62f390611bff90889088908b9060040161432d565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c4f9190810190613c3f565b600454909150600090611c6c9088906001600160a01b031661083f565b90506000611d01611cf486896001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb057600080fd5b505afa158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ce89190810190613c3f565b9063ffffffff612b3d16565b839063ffffffff6125b316565b9050611d13838263ffffffff6125c816565b98975050505050505050565b611d276131fa565b6000806060806060611d3d876101400151611dcc565b94509450945094509450600080600080611d6a87600081518110611d5d57fe5b6020026020010151610b06565b6001600160a01b039093168d5260208d019190915260ff91821660608d01521660408b015250979998505050505050505050565b6006546001600160a01b031681565b6002546001600160a01b031681565b600954600160a01b900460ff1681565b60208101516001600160e01b0319166000606080806394cfcdd760e01b8514611e105760405162461bcd60e51b8152600401611e07906145ab565b60405180910390fd5b6060806060611e2c60048a518b612c569092919063ffffffff16565b905080806020019051611e4291908101906139e6565b81519194509250600314611e5557600080fd5b82600081518110611e6257fe5b6020026020010151600114611e7657600080fd5b82600181518110611e8357fe5b6020026020010151600014611e9757600080fd5b82600281518110611ea457fe5b6020026020010151600014611eb857600080fd5b611ee6611ec36124d4565b83600181518110611ed057fe5b6020026020010151612cc190919063ffffffff16565b611eef57600080fd5b611f07611efa612533565b83600281518110611ed057fe5b611f1057600080fd5b611f2d82600081518110611f2057fe5b60200260200101516120f4565b939d929c50909a509850909650945050505050565b6000808411611f5057600080fd5b600083118015611f605750600082115b611f6957600080fd5b6000611f816103e8610e0f868863ffffffff6125e116565b90506000611f9b6103e5610e0f868963ffffffff612b3d16565b9050611fb86001828481611fab57fe5b049063ffffffff6125c816565b9695505050505050565b6003546001600160a01b031681565b6005546001600160a01b031681565b60025460405163f9c45f7160e01b815260009182916001600160a01b039091169063f9c45f7190612015908790600401614077565b60206040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120659190810190613c3f565b9050612077838263ffffffff612ce716565b949350505050565b60405162461bcd60e51b8152600401611e0790614584565b6307dfca1960e31b81565b6009546001600160a01b031681565b600080600060608060606120c9876101400151611dcc565b94509450945094509450826000815181106120e057fe5b602002602001015195505050505050919050565b60208101516001600160e01b03191660006060808063a7cb5fb760e01b851461212f5760405162461bcd60e51b8152600401611e07906145ab565b505050506024828101516044840151606485015160848601519496929591820184019490820184019391010190565b50600090565b6007546001600160a01b031681565b61217b613118565b6000606061218b8789888d6109a0565b9050612197878a611fe0565b6121b35760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b038b1683526080830189905260a083018990526101008301859052610120830184905261014083018190526121ed612cfb565b610160840152600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990612223908690600401614610565b60606040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122739190810190613b1a565b602001519150509850989650505050505050565b600080612293846120b1565b8451604051627eeac760e11b8152919250309162fdd58e916122b991859060040161415d565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123099190810190613c3f565b909211159392505050565b60015481565b600192915050565b60005460ff1690565b600054610100900460ff1661233f57600080fd5b846001600160a01b0316866001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62878760405161238e929190614670565b60405180910390a4505050505050565b6123a6613118565b60006123b8338a8a8a8a8a8a8a612173565b9150915097509795505050505050565b60008183116123d857508161082b565b508061082b565b604080516001808252818301909252606091829190602080830190803883395050604080516001808252818301909252929350606092915060208083019080388339019050509050600061243588888888610967565b9050808360008151811061244557fe5b60200260200101818152505060018260008151811061246057fe5b6020908102919091018101919091526040805160008152918201905263a7cb5fb760e01b61249430868685604481016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152945050505050949350505050565b600554604051606091630f47261b60e41b916124fc916001600160a01b031690602401614077565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905090565b60408051600080825260208201818152828401918252606080840190945260065490919063a7cb5fb760e01b90612579906001600160a01b0316858585608483016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152935050505090565b6000808284816125bf57fe5b04949350505050565b6000828201838110156125da57600080fd5b9392505050565b6000826125f05750600061082b565b828202828482816125fd57fe5b04146125da57600080fd5b814710156127d357478203600061261e82612b52565b9050828111156126405760405162461bcd60e51b8152600401611e0790614515565b6005546008546040516323b872dd60e01b81526001600160a01b03928316926323b872dd9261267992339290911690869060040161408b565b602060405180830381600087803b15801561269357600080fd5b505af11580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126cb9190810190613a9f565b6126d457600080fd5b6008546009546001600160a01b039091169063022c0d9f90600160a01b900460ff166127005783612703565b60005b600954600160a01b900460ff1661271b57600061271d565b845b306040518463ffffffff1660e01b815260040161273c9392919061467e565b600060405180830381600087803b15801561275657600080fd5b505af115801561276a573d6000803e3d6000fd5b5050600954604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061279e908590600401614262565b600060405180830381600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b5050505050505b5050565b6127f46127e2612cfb565b6101608401519063ffffffff612cc116565b6127fd57600080fd5b81608001518260a001511461281157600080fd5b60008061282284610140015161076b565b9150915060008060008061283585610b06565b93509350935093506000846001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287857600080fd5b505afa15801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128b09190810190613c3f565b90506128bc8589611fe0565b6128d85760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b03871630146128ed57600080fd5b505050505050505050565b6129006131ab565b604051606090634da26aab60e11b9061292190889088908890602401614645565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925260075491519092506000916060916001600160a01b0390911690869061297a908690613fe2565b60006040518083038185875af1925050503d80600081146129b7576040519150601f19603f3d011682016040523d82523d6000602084013e6129bc565b606091505b509150915081156129e657805160a0146129d257fe5b80806020019051611d139190810190613aff565b505050949350505050565b60006129fb6131fa565b612a0487611d1f565b9050612a108787612287565b612a1e57600091505061095e565b826001600160a01b031687600001516001600160a01b03161415612a45578591505061095e565b600080600460009054906101000a90046001600160a01b03166001600160a01b031663f5df1f24846000015185604001518660200151876060015160ff166001811115612a8e57fe5b8e600001518e8e8e8e6040518a63ffffffff1660e01b8152600401612abb99989796959493929190614353565b6040805180830381600087803b158015612ad457600080fd5b505af1158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b0c9190810190613d08565b9092509050612b21888363ffffffff612b3d16565b9350612b31898487898886612d32565b50505095945050505050565b600082821115612b4c57600080fd5b50900390565b600080600080600860009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bde9190810190613bd3565b92509250925061095e85600960149054906101000a900460ff16612c025783612c04565b845b6001600160701b0316600960149054906101000a900460ff16612c275785612c29565b845b6001600160701b0316611f42565b60005460ff1615612c4757600080fd5b6000805460ff19166001179055565b606081831115612c6557600080fd5b8351821115612c7357600080fd5b8282036040519080825280601f01601f191660200182016040528015612ca0576020820181803883390190505b5090506125da612caf8261306c565b84612cb98761306c565b018351613072565b6000815183511480156125da575081805190602001208380519060200120149392505050565b6000818381612cf257fe5b06159392505050565b6040805160008082526020820181815282840191825260608084019094529063a7cb5fb760e01b61257930858585608483016140af565b600754604051639d3fa4b960e01b81526000916001600160a01b031690639d3fa4b990612d63908a90600401614610565b60606040518083038186803b158015612d7b57600080fd5b505afa158015612d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612db39190810190613b1a565b6020015160408051600280825260608281019093529293509091816020016020820280388339505060408051600a8082526101608201909252929350606092915060208201610140803883390190505090506000886060015160ff166001811115612e1a57fe5b9050896000015183600081518110612e2e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508783600181518110612e5c57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050886020015182600081518110612e8e57fe5b602002602001018181525050600082600181518110612ea957fe5b602002602001018181525050886040015160ff1682600281518110612eca57fe5b6020026020010181815250508482600581518110612ee457fe5b6020026020010181815250508582600681518110612efe57fe5b602002602001018181525050600082600881518110612f1957fe5b602002602001018181525050600082600981518110612f3457fe5b602002602001018181525050600360009054906101000a90046001600160a01b03166001600160a01b03166399b537a08a600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612fd99190810190613612565b8b51878b866001811115612fe957fe5b89896040518863ffffffff1660e01b815260040161300d97969594939291906143b8565b602060405180830381600087803b15801561302757600080fd5b505af115801561303b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061305f9190810190613a9f565b5050505050505050505050565b60200190565b602081101561309c576001816020036101000a038019835116818551168082178652505050613113565b828214156130a957613113565b828211156130e35760208103905080820181840181515b828510156130db5784518652602095860195909401936130c0565b905250613113565b60208103905080820181840183515b8186121561310e5782518252601f1992830192909101906130f2565b855250505b505050565b604051806101c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b803561082b81614744565b60008083601f84011261323d578182fd5b5081356001600160401b03811115613253578182fd5b602083019150836020808302850101111561326d57600080fd5b9250929050565b600082601f830112613284578081fd5b8151613297613292826146d2565b6146ac565b818152915060208083019084810160005b84811015610825578151870188603f8201126132c357600080fd5b838101516132d3613292826146f1565b8181528a60408385010111156132e857600080fd5b6132f88287830160408601614714565b8652505092820192908201906001016132a8565b600082601f83011261331c578081fd5b813561332a613292826146d2565b8181529150602080830190840160005b8381101561336757613352876020843589010161340b565b8352602092830192919091019060010161333a565b5050505092915050565b600082601f830112613381578081fd5b813561338f613292826146d2565b8181529150602080830190840160005b83811015613367576133b787602084358901016134a8565b8352602092830192919091019060010161339f565b60008083601f8401126133dd578182fd5b5081356001600160401b038111156133f3578182fd5b60208301915083602082850101111561326d57600080fd5b600082601f83011261341b578081fd5b8135613429613292826146f1565b915080825283602082850101111561344057600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561346a578081fd5b61347460a06146ac565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b60006101c08083850312156134bb578182fd5b6134c4816146ac565b9150506134d18383613221565b81526134e08360208401613221565b60208201526134f28360408401613221565b60408201526135048360608401613221565b60608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140808301356001600160401b038082111561356557600080fd5b6135718683870161340b565b8385015261016092508285013591508082111561358d57600080fd5b6135998683870161340b565b838501526101809250828501359150808211156135b557600080fd5b6135c18683870161340b565b838501526101a09250828501359150808211156135dd57600080fd5b506135ea8582860161340b565b82840152505092915050565b600060208284031215613607578081fd5b81356125da81614744565b600060208284031215613623578081fd5b81516125da81614744565b60008060408385031215613640578081fd5b823561364b81614744565b9150602083013561365b81614744565b809150509250929050565b60008060008060008060008060a0898b031215613681578384fd5b883561368c81614744565b9750602089013561369c81614744565b965060408901356001600160401b03808211156136b7578586fd5b6136c38c838d0161322c565b909850965060608b01359150808211156136db578586fd5b6136e78c838d0161322c565b909650945060808b01359150808211156136ff578384fd5b5061370c8b828c016133cc565b999c989b5096995094979396929594505050565b60008060008060008060a08789031215613738578384fd5b863561374381614744565b9550602087013561375381614744565b9450604087013593506060870135925060808701356001600160401b0381111561377b578283fd5b61378789828a016133cc565b979a9699509497509295939492505050565b600080604083850312156137ab578182fd5b82356137b681614744565b9150602083013561365b8161475c565b600080600080608085870312156137db578182fd5b84356137e681614744565b935060208501356137f681614744565b925060408501356138068161477f565b9396929550929360600135925050565b60008060408385031215613828578182fd5b823561383381614744565b946020939093013593505050565b60008060008060808587031215613856578182fd5b843561386181614744565b93506020850135925060408501356138788161477f565b915060608501356138888161477f565b939692955090935050565b600080600080600080600080610100898b0312156138af578182fd5b88356138ba81614744565b975060208901356138ca8161477f565b9650604089013595506060890135945060808901356138e881614744565b935060a08901356138f88161477f565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806040858703121561392a578182fd5b84356001600160401b0380821115613940578384fd5b61394c8883890161322c565b90965094506020870135915080821115613964578384fd5b506139718782880161322c565b95989497509550505050565b600080600060608486031215613991578081fd5b83356001600160401b03808211156139a7578283fd5b6139b387838801613371565b945060208601359150808211156139c8578283fd5b506139d58682870161330c565b925050604084013590509250925092565b600080604083850312156139f8578182fd5b82516001600160401b0380821115613a0e578384fd5b81850186601f820112613a1f578485fd5b80519250613a2f613292846146d2565b80848252602080830192508084018a828389028701011115613a4f578889fd5b8894505b86851015613a71578051845260019490940193928101928101613a53565b508801519096509350505080821115613a88578283fd5b50613a9585828601613274565b9150509250929050565b600060208284031215613ab0578081fd5b81516125da8161475c565b600060208284031215613acc578081fd5b81356001600160401b03811115613ae1578182fd5b6120778482850161340b565b60008060408385031215613640578182fd5b600060a08284031215613b10578081fd5b6125da8383613459565b600060608284031215613b2b578081fd5b613b3560606146ac565b8251613b408161477f565b8152602083810151908201526040928301519281019290925250919050565b600060208284031215613b70578081fd5b81356001600160401b03811115613b85578182fd5b612077848285016134a8565b60008060408385031215613ba3578182fd5b82356001600160401b03811115613bb8578283fd5b613bc4858286016134a8565b95602094909401359450505050565b600080600060608486031215613be7578081fd5b8351613bf28161476a565b6020850151909350613c038161476a565b604085015190925063ffffffff81168114613c1c578182fd5b809150509250925092565b600060208284031215613c38578081fd5b5035919050565b600060208284031215613c50578081fd5b5051919050565b600080600080600080600060e0888a031215613c71578081fd5b873596506020880135955060408801359450606088013593506080880135925060a08801356001600160401b0380821115613caa578283fd5b613cb68b838c01613371565b935060c08a0135915080821115613ccb578283fd5b50613cd88a828b0161330c565b91505092959891949750929550565b60008060408385031215613cf9578182fd5b50508035926020909101359150565b60008060408385031215613d1a578182fd5b505080516020909101519092909150565b600080600060608486031215613d3f578081fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a031215613d70578081fd5b8735613d7b8161477f565b965060208801359550604088013594506060880135613d9981614744565b93506080880135613da98161477f565b9699959850939692959460a0840135945060c09093013592915050565b6001600160a01b0316815260200190565b6001600160a01b03169052565b81835260006001600160fb1b03831115613dfc578081fd5b6020830280836020870137939093016020019283525090919050565b6000815180845260208401935060208301825b82811015613e49578151865260209586019590910190600101613e2b565b5093949350505050565b60008151808452613e6b816020860160208601614714565b601f01601f19169290920160200192915050565b60006101c0613e8f848451613dd7565b6020830151613ea16020860182613dd7565b506040830151613eb46040860182613dd7565b506060830151613ec76060860182613dd7565b506080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401518282870152613f2083870182613e53565b91505061016091508184015185820383870152613f3d8282613e53565b925050506101808084015185830382870152613f598382613e53565b9150506101a091508184015185820383870152611fb88282613e53565b60609490941b6bffffffffffffffffffffffff1916845260b09290921b6001600160b01b031916601484015260f890811b6001600160f81b0319908116601e85015291901b16601f82015260200190565b93845260208401929092526040830152606082015260800190565b60008251613ff4818460208701614714565b9190910192915050565b90565b6c08a92a06e626488dedac2d2dc5609b1b81526b1cdd1c9a5b99c81b985b594b60a21b600d8201526e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b60198201527f6164647265737320766572696679696e67436f6e7472616374000000000000006028820152602960f81b604182015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03851681526080602082018190526000906140d390830186613e18565b82810360408401526140e58186613e18565b8381036060850152611d138186613e53565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039889168152968816602088015294909616604086015260ff9283166060860152608085019190915260a084015290921660c082015260e08101919091526101000190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6000604082526141b6604083018688613de4565b82810360208401526141c9818587613de4565b979650505050505050565b6000602082526125da6020830184613e18565b6000604082526141fa6040830185613e18565b602083820381850152818551808452828401915082838202850101838801865b8381101561424857601f19878403018552614236838351613e53565b9486019492509085019060010161421a565b50909998505050505050505050565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b6001600160e01b0319861681526001600160a01b038516602082015260a0604082018190526000906142b490830186613e18565b82810360608401526142c68186613e18565b83810360808501526142d88186613e53565b9998505050505050505050565b6000602082526125da6020830184613e53565b600060018060a01b0380861683526060602084015261431a6060840186613e18565b9150808416604084015250949350505050565b6001600160a01b03938416815260ff929092166020830152909116604082015260600190565b6001600160a01b038a8116825260ff8a166020830152604082018990526101208201906002891061438057fe5b88606084015280881660808401528660a08401528560c08401528460e0840152808416610100840152509a9950505050505050505050565b600060e0820160018060a01b03808b168452808a1660208501525087604084015286606084015260ff8616608084015260e060a08401528085516143fc8184614262565b9150602087019250835b8181101561442a57614419838551613dc6565b602094909401939250600101614406565b505083810360c0850152610ce38186613e18565b60208082526036908201527f4f72646572206d7573742062652061206d756c7469706c65206f6620746865206040820152751b585c9ad95d081d1c985919481a5b98dc995b595b9d60521b606082015260800190565b63086c2e6d60e31b815260200190565b64574554483960d81b815260200190565b6929b430b932aa37b5b2b760b11b815260200190565b682334b63627b93232b960b91b815260200190565b6f556e69737761705632466163746f727960801b815260200190565b6c5a65726f5845786368616e676560981b815260200190565b60208082526049908201527f436f7374206f662070757263686173696e672045544820746f20636f7665722060408201527f70726f746f636f6c20466565206f6e207468652065786368616e676520776173606082015268040e8dede40d0d2ced60bb1b608082015260a00190565b6020808252600d908201526c139bdd081cdd5c1c1bdc9d1959609a1b604082015260600190565b6020808252600e908201526d15d493d391d7d41493d61657d25160921b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015160ff90811691830191909152606092830151169181019190915260800190565b6000602082526125da6020830184613e7f565b6000604082526146366040830185613e7f565b90508260208301529392505050565b6000606082526146586060830186613e7f565b8460208401528281036040840152611fb88185613e53565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b6040518181016001600160401b03811182821017156146ca57600080fd5b604052919050565b60006001600160401b038211156146e7578081fd5b5060209081020190565b60006001600160401b03821115614706578081fd5b50601f01601f191660200190565b60005b8381101561472f578181015183820152602001614717565b8381111561473e576000848401525b50505050565b6001600160a01b038116811461475957600080fd5b50565b801515811461475957600080fd5b6001600160701b038116811461475957600080fd5b60ff8116811461475957600080fdfea365627a7a723158209038d4e8a8c7fe935f8ee4cc5d68a9ae777dfeb32839253038dcc9376cd96e486c6578706572696d656e74616cf564736f6c634300050f0040

Deployed Bytecode

0x6080604052600436106102445760003560e01c80637a0d8f8a11610139578063afc6d8ba116100b6578063e264cff11161007a578063e264cff1146106c1578063e306f779146106e1578063e985e9c5146106f6578063ee89dab414610716578063f242432a1461072b578063f94515f01461074b57610244565b8063afc6d8ba1461061e578063b3ca8e251461063e578063bd85b0391461065e578063d2f7265a1461067e578063e186955b1461069357610244565b8063961be391116100fd578063961be391146105925780639c6fbce5146105a7578063a22cb465146105c7578063ad5c22c8146105e7578063ad5c46481461060957610244565b80637a0d8f8a146105025780637b66c82a146105175780637cb111251461052c57806385f8c2591461055d5780638e1bfa731461057d57610244565b80633fc6f627116101c757806353e569a11161018b57806353e569a1146104695780635c1ad8441461048b5780635e03e6e4146104a057806361a4760b146104c05780636c9fa59e146104ed57610244565b80633fc6f627146103bc578063485cc955146103dc5780634bf1ee87146103fc5780634e1273f41461041c5780634ea96c301461044957610244565b8063235f9e081161020e578063235f9e081461030c57806326afd2e8146103395780632c52071c146103695780632eb2c2d6146103895780632f562016146103a957610244565b8062ee354214610246578062fdd58e1461027d57806309c1df9f146102aa5780631d4b44bb146102cc5780631f981bde146102ec575b005b34801561025257600080fd5b50610266610261366004613abb565b61076b565b60405161027492919061415d565b60405180910390f35b34801561028957600080fd5b5061029d610298366004613816565b6107ad565b6040516102749190614262565b3480156102b657600080fd5b506102bf610831565b6040516102749190614257565b3480156102d857600080fd5b5061029d6102e736600461362e565b61083f565b3480156102f857600080fd5b5061029d610307366004613841565b610967565b34801561031857600080fd5b5061032c610327366004613841565b6109a0565b60405161027491906142e5565b34801561034557600080fd5b50610359610354366004613c27565b610b06565b6040516102749493929190614176565b34801561037557600080fd5b5061029d6103843660046137c6565b610b2d565b34801561039557600080fd5b506102446103a4366004613666565b610cf2565b61029d6103b7366004613c57565b610d6b565b3480156103c857600080fd5b5061029d6103d7366004613ce7565b610f83565b3480156103e857600080fd5b506102446103f7366004613aed565b610ff7565b34801561040857600080fd5b5061032c610417366004613b91565b611678565b34801561042857600080fd5b5061043c610437366004613915565b6116cf565b60405161027491906141d4565b34801561045557600080fd5b506102bf61046436600461397d565b6117d7565b34801561047557600080fd5b5061047e611ba8565b6040516102749190614077565b34801561049757600080fd5b5061047e611bb7565b3480156104ac57600080fd5b5061029d6104bb3660046137c6565b611bc6565b3480156104cc57600080fd5b506104e06104db366004613b5f565b611d1f565b60405161027491906145d3565b3480156104f957600080fd5b5061047e611d9e565b34801561050e57600080fd5b5061047e611dad565b34801561052357600080fd5b506102bf611dbc565b34801561053857600080fd5b5061054c610547366004613abb565b611dcc565b604051610274959493929190614280565b34801561056957600080fd5b5061029d610578366004613d2b565b611f42565b34801561058957600080fd5b5061047e611fc2565b34801561059e57600080fd5b5061047e611fd1565b3480156105b357600080fd5b506102bf6105c2366004613816565b611fe0565b3480156105d357600080fd5b506102446105e2366004613799565b61207f565b3480156105f357600080fd5b506105fc612097565b604051610274919061426b565b34801561061557600080fd5b5061047e6120a2565b34801561062a57600080fd5b5061029d610639366004613b5f565b6120b1565b34801561064a57600080fd5b5061054c610659366004613abb565b6120f4565b34801561066a57600080fd5b5061029d610679366004613c27565b61215e565b34801561068a57600080fd5b5061047e612164565b34801561069f57600080fd5b506106b36106ae366004613893565b612173565b604051610274929190614623565b3480156106cd57600080fd5b506102bf6106dc366004613b91565b612287565b3480156106ed57600080fd5b5061029d612314565b34801561070257600080fd5b506102bf61071136600461362e565b61231a565b34801561072257600080fd5b506102bf612322565b34801561073757600080fd5b50610244610746366004613720565b61232b565b34801561075757600080fd5b506106b3610766366004613d56565b61239e565b600080600080606080606061077f88611dcc565b945094509450945094508260008151811061079657fe5b602002602001015195508396505050505050915091565b60008060008060006107be86610b06565b935093509350935060008160ff1660018111156107d757fe5b905060018160018111156107e757fe5b1415610805576107f988868587611bc6565b9550505050505061082b565b600081600181111561081357fe5b1415610825576107f988868587610b2d565b50505050505b92915050565b600054610100900460ff1690565b6005546040516370a0823160e01b815260009182916001600160a01b03909116906370a0823190610874908790600401614077565b60206040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c49190810190613c3f565b600554604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e906108fc90889088906004016140f7565b60206040518083038186803b15801561091457600080fd5b505afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061094c9190810190613c3f565b905061095e828263ffffffff6123c816565b95945050505050565b60006060858585856040516020016109829493929190613f76565b60408051601f19818403018152919052602001519695505050505050565b60408051600380825260808201909252606091829190816020015b60608152602001906001900390816109bb5750506040805160038082526080820190925291925060609190602082018380388339019050509050610a01878787876123df565b82600081518110610a0e57fe5b6020026020010181905250610a216124d4565b82600181518110610a2e57fe5b6020026020010181905250610a41612533565b82600281518110610a4e57fe5b6020026020010181905250600181600081518110610a6857fe5b602002602001018181525050600081600181518110610a8357fe5b602002602001018181525050600081600281518110610a9e57fe5b60200260200101818152505060606394cfcdd760e01b8284604051602401610ac79291906141e7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529350505050949350505050565b606081901c9169ffffffffffffffffffff601083901c169160ff600882901c811692911690565b600080846001600160a01b03166327ce5b8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6957600080fd5b505afa158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ba19190810190613c3f565b9050606060018203604051908082528060200260200182016040528015610bd2578160200160208202803883390190505b5090506000805b60018403811015610c1a578660ff16811415610bf6576001909101905b81838281518110610c0357fe5b602090810291909101015260019182019101610bd9565b5060065460405163f8a2167b60e01b81526000916001600160a01b03169063f8a2167b90610c50908b9087908e906004016142f8565b60206040518083038186803b158015610c6857600080fd5b505afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ca09190810190613c3f565b600454909150600090610cbd908b906001600160a01b031661083f565b90506000610cd1828963ffffffff6125b316565b9050610ce3838263ffffffff6125c816565b9b9a5050505050505050505050565b600054610100900460ff16610d0657600080fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89898989604051610d5994939291906141a2565b60405180910390a45050505050505050565b600080835111610d7a57600080fd5b6000805461ff00191661010017815560075460408051631ce4c78b60e01b815290518b9392610e1b923a926001600160a01b0390921691631ce4c78b91600480820192602092909190829003018186803b158015610dd757600080fd5b505afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0f9190810190613c3f565b9063ffffffff6125e116565b9050610e36610e30828863ffffffff6125e116565b88612608565b60005b855181108015610e4857508215155b15610ef957610e55613118565b868281518110610e6157fe5b60200260200101519050610e7581856127d7565b610e7d6131ab565b610e9c8286898681518110610e8e57fe5b6020026020010151876128f8565b9050806020015160001415610eb2575050610ef1565b6000610ec58383602001518f8f336129f1565b9050610ed7868263ffffffff612b3d16565b600019909a0199955089610eed57505050610ef9565b5050505b600101610e39565b506000805461ff00191690554715610f76576000336001600160a01b031647604051610f2490613ffe565b60006040518083038185875af1925050503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5050905080610f7457600080fd5b505b5098975050505050505050565b600080610fd883600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b90506000610fec828663ffffffff6125e116565b905061095e81612b52565b60005460ff161561100757600080fd5b61100f612c37565b600280546001600160a01b038085166001600160a01b03199283168117909355600380549185169190921617905560405163f39ec1f760e01b815263f39ec1f79061105c90600401614494565b60206040518083038186803b15801561107457600080fd5b505afa158015611088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110ac9190810190613612565b600580546001600160a01b0319166001600160a01b039283161790819055166110d457600080fd5b60405163f39ec1f760e01b81526001600160a01b0383169063f39ec1f7906110fe906004016144b5565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190613612565b600680546001600160a01b0319166001600160a01b0392831617908190551661117657600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906111a0906004016144fc565b60206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f09190810190613612565b600780546001600160a01b0319166001600160a01b0392831617908190551661121857600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f790611242906004016144cb565b60206040518083038186803b15801561125a57600080fd5b505afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112929190810190613612565b600480546001600160a01b0319166001600160a01b039283161790819055166112ba57600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906112e4906004016144a4565b60206040518083038186803b1580156112fc57600080fd5b505afa158015611310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113349190810190613612565b600980546001600160a01b0319166001600160a01b0392831617905560405163f39ec1f760e01b815260009184169063f39ec1f790611375906004016144e0565b60206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c59190810190613612565b60095460055460405163e6a4390560e01b81529293506000926001600160a01b038086169363e6a4390593611402939183169216906004016140f7565b60206040518083038186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114529190810190613612565b90506001600160a01b0381166114ee576009546005546040516364e329cb60e11b81526001600160a01b038086169363c9c6539693611499939183169216906004016140f7565b602060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114eb9190810190613612565b90505b600880546001600160a01b0319166001600160a01b03838116919091179182905560055460408051630dfe168160e01b815290519183169390921691630dfe1681916004808301926020929190829003018186803b15801561154f57600080fd5b505afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115879190810190613612565b6001600160a01b031614600960146101000a81548160ff0219169083151502179055506040516020016115b990614001565b60408051601f1981840301815282825280516020918201208383018352600b84526a0c1e08141c9bdd1bd8dbdb60aa1b938201939093528151808301835260018152601960f91b90820152905161165792917ff0f24618f4c4be1e62e026fb039a20ef96f4495294817d1027ffaa6d1f70e61e917fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a591309101613fc7565b60408051601f19818403018152919052805160209091012060015550505050565b6060633efe50c860e01b8383604051602401611695929190614623565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905092915050565b6040805184815260208086028201019091526060908480156116fb578160200160208202803883390190505b50905060005b848110156117ce573062fdd58e87878481811061171a57fe5b905060200201602061172f91908101906135f6565b86868581811061173b57fe5b905060200201356040518363ffffffff1660e01b815260040161175f92919061415d565b60206040518083038186803b15801561177757600080fd5b505afa15801561178b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117af9190810190613c3f565b8282815181106117bb57fe5b6020908102919091010152600101611701565b50949350505050565b600082518451146117e757600080fd5b600061183b3a600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b905061185a6118548651836125e190919063ffffffff16565b84612608565b6000805461ff0019166101001781555b8551811015611b205761187b613118565b86828151811061188757fe5b60200260200101519050606086838151811061189f57fe5b6020026020010151905081600001516001600160a01b0316336001600160a01b0316146118cb57600080fd5b6118d36131da565b600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990611903908690600401614610565b60606040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119539190810190613b1a565b9050600061197282604001518560a00151612b3d90919063ffffffff16565b600754604051634da26aab60e11b81529192506001600160a01b031690639b44d5569088906119a990889086908990600401614645565b60a0604051808303818588803b1580156119c257600080fd5b505af11580156119d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052506119fb9190810190613aff565b50611a046131fa565b611a0d85611d1f565b9050600081600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a869190810190613612565b6003548351885160408087015160208089015160608a0151918c01519351632bbddc3760e11b81529798506001600160a01b039096169663577bb86e96611adc968a96909590949391928d929190600401614111565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506001909801975061186a9650505050505050565b506000805461ff00191690554715611b9d576000336001600160a01b031647604051611b4b90613ffe565b60006040518083038185875af1925050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611b9b57600080fd5b505b506001949350505050565b6008546001600160a01b031681565b6004546001600160a01b031681565b60065460405163d64c62f360e01b815260009182916001600160a01b039091169063d64c62f390611bff90889088908b9060040161432d565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c4f9190810190613c3f565b600454909150600090611c6c9088906001600160a01b031661083f565b90506000611d01611cf486896001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb057600080fd5b505afa158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ce89190810190613c3f565b9063ffffffff612b3d16565b839063ffffffff6125b316565b9050611d13838263ffffffff6125c816565b98975050505050505050565b611d276131fa565b6000806060806060611d3d876101400151611dcc565b94509450945094509450600080600080611d6a87600081518110611d5d57fe5b6020026020010151610b06565b6001600160a01b039093168d5260208d019190915260ff91821660608d01521660408b015250979998505050505050505050565b6006546001600160a01b031681565b6002546001600160a01b031681565b600954600160a01b900460ff1681565b60208101516001600160e01b0319166000606080806394cfcdd760e01b8514611e105760405162461bcd60e51b8152600401611e07906145ab565b60405180910390fd5b6060806060611e2c60048a518b612c569092919063ffffffff16565b905080806020019051611e4291908101906139e6565b81519194509250600314611e5557600080fd5b82600081518110611e6257fe5b6020026020010151600114611e7657600080fd5b82600181518110611e8357fe5b6020026020010151600014611e9757600080fd5b82600281518110611ea457fe5b6020026020010151600014611eb857600080fd5b611ee6611ec36124d4565b83600181518110611ed057fe5b6020026020010151612cc190919063ffffffff16565b611eef57600080fd5b611f07611efa612533565b83600281518110611ed057fe5b611f1057600080fd5b611f2d82600081518110611f2057fe5b60200260200101516120f4565b939d929c50909a509850909650945050505050565b6000808411611f5057600080fd5b600083118015611f605750600082115b611f6957600080fd5b6000611f816103e8610e0f868863ffffffff6125e116565b90506000611f9b6103e5610e0f868963ffffffff612b3d16565b9050611fb86001828481611fab57fe5b049063ffffffff6125c816565b9695505050505050565b6003546001600160a01b031681565b6005546001600160a01b031681565b60025460405163f9c45f7160e01b815260009182916001600160a01b039091169063f9c45f7190612015908790600401614077565b60206040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120659190810190613c3f565b9050612077838263ffffffff612ce716565b949350505050565b60405162461bcd60e51b8152600401611e0790614584565b6307dfca1960e31b81565b6009546001600160a01b031681565b600080600060608060606120c9876101400151611dcc565b94509450945094509450826000815181106120e057fe5b602002602001015195505050505050919050565b60208101516001600160e01b03191660006060808063a7cb5fb760e01b851461212f5760405162461bcd60e51b8152600401611e07906145ab565b505050506024828101516044840151606485015160848601519496929591820184019490820184019391010190565b50600090565b6007546001600160a01b031681565b61217b613118565b6000606061218b8789888d6109a0565b9050612197878a611fe0565b6121b35760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b038b1683526080830189905260a083018990526101008301859052610120830184905261014083018190526121ed612cfb565b610160840152600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990612223908690600401614610565b60606040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122739190810190613b1a565b602001519150509850989650505050505050565b600080612293846120b1565b8451604051627eeac760e11b8152919250309162fdd58e916122b991859060040161415d565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123099190810190613c3f565b909211159392505050565b60015481565b600192915050565b60005460ff1690565b600054610100900460ff1661233f57600080fd5b846001600160a01b0316866001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62878760405161238e929190614670565b60405180910390a4505050505050565b6123a6613118565b60006123b8338a8a8a8a8a8a8a612173565b9150915097509795505050505050565b60008183116123d857508161082b565b508061082b565b604080516001808252818301909252606091829190602080830190803883395050604080516001808252818301909252929350606092915060208083019080388339019050509050600061243588888888610967565b9050808360008151811061244557fe5b60200260200101818152505060018260008151811061246057fe5b6020908102919091018101919091526040805160008152918201905263a7cb5fb760e01b61249430868685604481016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152945050505050949350505050565b600554604051606091630f47261b60e41b916124fc916001600160a01b031690602401614077565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905090565b60408051600080825260208201818152828401918252606080840190945260065490919063a7cb5fb760e01b90612579906001600160a01b0316858585608483016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152935050505090565b6000808284816125bf57fe5b04949350505050565b6000828201838110156125da57600080fd5b9392505050565b6000826125f05750600061082b565b828202828482816125fd57fe5b04146125da57600080fd5b814710156127d357478203600061261e82612b52565b9050828111156126405760405162461bcd60e51b8152600401611e0790614515565b6005546008546040516323b872dd60e01b81526001600160a01b03928316926323b872dd9261267992339290911690869060040161408b565b602060405180830381600087803b15801561269357600080fd5b505af11580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126cb9190810190613a9f565b6126d457600080fd5b6008546009546001600160a01b039091169063022c0d9f90600160a01b900460ff166127005783612703565b60005b600954600160a01b900460ff1661271b57600061271d565b845b306040518463ffffffff1660e01b815260040161273c9392919061467e565b600060405180830381600087803b15801561275657600080fd5b505af115801561276a573d6000803e3d6000fd5b5050600954604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061279e908590600401614262565b600060405180830381600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b5050505050505b5050565b6127f46127e2612cfb565b6101608401519063ffffffff612cc116565b6127fd57600080fd5b81608001518260a001511461281157600080fd5b60008061282284610140015161076b565b9150915060008060008061283585610b06565b93509350935093506000846001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287857600080fd5b505afa15801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128b09190810190613c3f565b90506128bc8589611fe0565b6128d85760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b03871630146128ed57600080fd5b505050505050505050565b6129006131ab565b604051606090634da26aab60e11b9061292190889088908890602401614645565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925260075491519092506000916060916001600160a01b0390911690869061297a908690613fe2565b60006040518083038185875af1925050503d80600081146129b7576040519150601f19603f3d011682016040523d82523d6000602084013e6129bc565b606091505b509150915081156129e657805160a0146129d257fe5b80806020019051611d139190810190613aff565b505050949350505050565b60006129fb6131fa565b612a0487611d1f565b9050612a108787612287565b612a1e57600091505061095e565b826001600160a01b031687600001516001600160a01b03161415612a45578591505061095e565b600080600460009054906101000a90046001600160a01b03166001600160a01b031663f5df1f24846000015185604001518660200151876060015160ff166001811115612a8e57fe5b8e600001518e8e8e8e6040518a63ffffffff1660e01b8152600401612abb99989796959493929190614353565b6040805180830381600087803b158015612ad457600080fd5b505af1158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b0c9190810190613d08565b9092509050612b21888363ffffffff612b3d16565b9350612b31898487898886612d32565b50505095945050505050565b600082821115612b4c57600080fd5b50900390565b600080600080600860009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bde9190810190613bd3565b92509250925061095e85600960149054906101000a900460ff16612c025783612c04565b845b6001600160701b0316600960149054906101000a900460ff16612c275785612c29565b845b6001600160701b0316611f42565b60005460ff1615612c4757600080fd5b6000805460ff19166001179055565b606081831115612c6557600080fd5b8351821115612c7357600080fd5b8282036040519080825280601f01601f191660200182016040528015612ca0576020820181803883390190505b5090506125da612caf8261306c565b84612cb98761306c565b018351613072565b6000815183511480156125da575081805190602001208380519060200120149392505050565b6000818381612cf257fe5b06159392505050565b6040805160008082526020820181815282840191825260608084019094529063a7cb5fb760e01b61257930858585608483016140af565b600754604051639d3fa4b960e01b81526000916001600160a01b031690639d3fa4b990612d63908a90600401614610565b60606040518083038186803b158015612d7b57600080fd5b505afa158015612d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612db39190810190613b1a565b6020015160408051600280825260608281019093529293509091816020016020820280388339505060408051600a8082526101608201909252929350606092915060208201610140803883390190505090506000886060015160ff166001811115612e1a57fe5b9050896000015183600081518110612e2e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508783600181518110612e5c57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050886020015182600081518110612e8e57fe5b602002602001018181525050600082600181518110612ea957fe5b602002602001018181525050886040015160ff1682600281518110612eca57fe5b6020026020010181815250508482600581518110612ee457fe5b6020026020010181815250508582600681518110612efe57fe5b602002602001018181525050600082600881518110612f1957fe5b602002602001018181525050600082600981518110612f3457fe5b602002602001018181525050600360009054906101000a90046001600160a01b03166001600160a01b03166399b537a08a600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612fd99190810190613612565b8b51878b866001811115612fe957fe5b89896040518863ffffffff1660e01b815260040161300d97969594939291906143b8565b602060405180830381600087803b15801561302757600080fd5b505af115801561303b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061305f9190810190613a9f565b5050505050505050505050565b60200190565b602081101561309c576001816020036101000a038019835116818551168082178652505050613113565b828214156130a957613113565b828211156130e35760208103905080820181840181515b828510156130db5784518652602095860195909401936130c0565b905250613113565b60208103905080820181840183515b8186121561310e5782518252601f1992830192909101906130f2565b855250505b505050565b604051806101c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b803561082b81614744565b60008083601f84011261323d578182fd5b5081356001600160401b03811115613253578182fd5b602083019150836020808302850101111561326d57600080fd5b9250929050565b600082601f830112613284578081fd5b8151613297613292826146d2565b6146ac565b818152915060208083019084810160005b84811015610825578151870188603f8201126132c357600080fd5b838101516132d3613292826146f1565b8181528a60408385010111156132e857600080fd5b6132f88287830160408601614714565b8652505092820192908201906001016132a8565b600082601f83011261331c578081fd5b813561332a613292826146d2565b8181529150602080830190840160005b8381101561336757613352876020843589010161340b565b8352602092830192919091019060010161333a565b5050505092915050565b600082601f830112613381578081fd5b813561338f613292826146d2565b8181529150602080830190840160005b83811015613367576133b787602084358901016134a8565b8352602092830192919091019060010161339f565b60008083601f8401126133dd578182fd5b5081356001600160401b038111156133f3578182fd5b60208301915083602082850101111561326d57600080fd5b600082601f83011261341b578081fd5b8135613429613292826146f1565b915080825283602082850101111561344057600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561346a578081fd5b61347460a06146ac565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b60006101c08083850312156134bb578182fd5b6134c4816146ac565b9150506134d18383613221565b81526134e08360208401613221565b60208201526134f28360408401613221565b60408201526135048360608401613221565b60608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140808301356001600160401b038082111561356557600080fd5b6135718683870161340b565b8385015261016092508285013591508082111561358d57600080fd5b6135998683870161340b565b838501526101809250828501359150808211156135b557600080fd5b6135c18683870161340b565b838501526101a09250828501359150808211156135dd57600080fd5b506135ea8582860161340b565b82840152505092915050565b600060208284031215613607578081fd5b81356125da81614744565b600060208284031215613623578081fd5b81516125da81614744565b60008060408385031215613640578081fd5b823561364b81614744565b9150602083013561365b81614744565b809150509250929050565b60008060008060008060008060a0898b031215613681578384fd5b883561368c81614744565b9750602089013561369c81614744565b965060408901356001600160401b03808211156136b7578586fd5b6136c38c838d0161322c565b909850965060608b01359150808211156136db578586fd5b6136e78c838d0161322c565b909650945060808b01359150808211156136ff578384fd5b5061370c8b828c016133cc565b999c989b5096995094979396929594505050565b60008060008060008060a08789031215613738578384fd5b863561374381614744565b9550602087013561375381614744565b9450604087013593506060870135925060808701356001600160401b0381111561377b578283fd5b61378789828a016133cc565b979a9699509497509295939492505050565b600080604083850312156137ab578182fd5b82356137b681614744565b9150602083013561365b8161475c565b600080600080608085870312156137db578182fd5b84356137e681614744565b935060208501356137f681614744565b925060408501356138068161477f565b9396929550929360600135925050565b60008060408385031215613828578182fd5b823561383381614744565b946020939093013593505050565b60008060008060808587031215613856578182fd5b843561386181614744565b93506020850135925060408501356138788161477f565b915060608501356138888161477f565b939692955090935050565b600080600080600080600080610100898b0312156138af578182fd5b88356138ba81614744565b975060208901356138ca8161477f565b9650604089013595506060890135945060808901356138e881614744565b935060a08901356138f88161477f565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806040858703121561392a578182fd5b84356001600160401b0380821115613940578384fd5b61394c8883890161322c565b90965094506020870135915080821115613964578384fd5b506139718782880161322c565b95989497509550505050565b600080600060608486031215613991578081fd5b83356001600160401b03808211156139a7578283fd5b6139b387838801613371565b945060208601359150808211156139c8578283fd5b506139d58682870161330c565b925050604084013590509250925092565b600080604083850312156139f8578182fd5b82516001600160401b0380821115613a0e578384fd5b81850186601f820112613a1f578485fd5b80519250613a2f613292846146d2565b80848252602080830192508084018a828389028701011115613a4f578889fd5b8894505b86851015613a71578051845260019490940193928101928101613a53565b508801519096509350505080821115613a88578283fd5b50613a9585828601613274565b9150509250929050565b600060208284031215613ab0578081fd5b81516125da8161475c565b600060208284031215613acc578081fd5b81356001600160401b03811115613ae1578182fd5b6120778482850161340b565b60008060408385031215613640578182fd5b600060a08284031215613b10578081fd5b6125da8383613459565b600060608284031215613b2b578081fd5b613b3560606146ac565b8251613b408161477f565b8152602083810151908201526040928301519281019290925250919050565b600060208284031215613b70578081fd5b81356001600160401b03811115613b85578182fd5b612077848285016134a8565b60008060408385031215613ba3578182fd5b82356001600160401b03811115613bb8578283fd5b613bc4858286016134a8565b95602094909401359450505050565b600080600060608486031215613be7578081fd5b8351613bf28161476a565b6020850151909350613c038161476a565b604085015190925063ffffffff81168114613c1c578182fd5b809150509250925092565b600060208284031215613c38578081fd5b5035919050565b600060208284031215613c50578081fd5b5051919050565b600080600080600080600060e0888a031215613c71578081fd5b873596506020880135955060408801359450606088013593506080880135925060a08801356001600160401b0380821115613caa578283fd5b613cb68b838c01613371565b935060c08a0135915080821115613ccb578283fd5b50613cd88a828b0161330c565b91505092959891949750929550565b60008060408385031215613cf9578182fd5b50508035926020909101359150565b60008060408385031215613d1a578182fd5b505080516020909101519092909150565b600080600060608486031215613d3f578081fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a031215613d70578081fd5b8735613d7b8161477f565b965060208801359550604088013594506060880135613d9981614744565b93506080880135613da98161477f565b9699959850939692959460a0840135945060c09093013592915050565b6001600160a01b0316815260200190565b6001600160a01b03169052565b81835260006001600160fb1b03831115613dfc578081fd5b6020830280836020870137939093016020019283525090919050565b6000815180845260208401935060208301825b82811015613e49578151865260209586019590910190600101613e2b565b5093949350505050565b60008151808452613e6b816020860160208601614714565b601f01601f19169290920160200192915050565b60006101c0613e8f848451613dd7565b6020830151613ea16020860182613dd7565b506040830151613eb46040860182613dd7565b506060830151613ec76060860182613dd7565b506080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401518282870152613f2083870182613e53565b91505061016091508184015185820383870152613f3d8282613e53565b925050506101808084015185830382870152613f598382613e53565b9150506101a091508184015185820383870152611fb88282613e53565b60609490941b6bffffffffffffffffffffffff1916845260b09290921b6001600160b01b031916601484015260f890811b6001600160f81b0319908116601e85015291901b16601f82015260200190565b93845260208401929092526040830152606082015260800190565b60008251613ff4818460208701614714565b9190910192915050565b90565b6c08a92a06e626488dedac2d2dc5609b1b81526b1cdd1c9a5b99c81b985b594b60a21b600d8201526e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b60198201527f6164647265737320766572696679696e67436f6e7472616374000000000000006028820152602960f81b604182015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03851681526080602082018190526000906140d390830186613e18565b82810360408401526140e58186613e18565b8381036060850152611d138186613e53565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039889168152968816602088015294909616604086015260ff9283166060860152608085019190915260a084015290921660c082015260e08101919091526101000190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6000604082526141b6604083018688613de4565b82810360208401526141c9818587613de4565b979650505050505050565b6000602082526125da6020830184613e18565b6000604082526141fa6040830185613e18565b602083820381850152818551808452828401915082838202850101838801865b8381101561424857601f19878403018552614236838351613e53565b9486019492509085019060010161421a565b50909998505050505050505050565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b6001600160e01b0319861681526001600160a01b038516602082015260a0604082018190526000906142b490830186613e18565b82810360608401526142c68186613e18565b83810360808501526142d88186613e53565b9998505050505050505050565b6000602082526125da6020830184613e53565b600060018060a01b0380861683526060602084015261431a6060840186613e18565b9150808416604084015250949350505050565b6001600160a01b03938416815260ff929092166020830152909116604082015260600190565b6001600160a01b038a8116825260ff8a166020830152604082018990526101208201906002891061438057fe5b88606084015280881660808401528660a08401528560c08401528460e0840152808416610100840152509a9950505050505050505050565b600060e0820160018060a01b03808b168452808a1660208501525087604084015286606084015260ff8616608084015260e060a08401528085516143fc8184614262565b9150602087019250835b8181101561442a57614419838551613dc6565b602094909401939250600101614406565b505083810360c0850152610ce38186613e18565b60208082526036908201527f4f72646572206d7573742062652061206d756c7469706c65206f6620746865206040820152751b585c9ad95d081d1c985919481a5b98dc995b595b9d60521b606082015260800190565b63086c2e6d60e31b815260200190565b64574554483960d81b815260200190565b6929b430b932aa37b5b2b760b11b815260200190565b682334b63627b93232b960b91b815260200190565b6f556e69737761705632466163746f727960801b815260200190565b6c5a65726f5845786368616e676560981b815260200190565b60208082526049908201527f436f7374206f662070757263686173696e672045544820746f20636f7665722060408201527f70726f746f636f6c20466565206f6e207468652065786368616e676520776173606082015268040e8dede40d0d2ced60bb1b608082015260a00190565b6020808252600d908201526c139bdd081cdd5c1c1bdc9d1959609a1b604082015260600190565b6020808252600e908201526d15d493d391d7d41493d61657d25160921b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015160ff90811691830191909152606092830151169181019190915260800190565b6000602082526125da6020830184613e7f565b6000604082526146366040830185613e7f565b90508260208301529392505050565b6000606082526146586060830186613e7f565b8460208401528281036040840152611fb88185613e53565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b6040518181016001600160401b03811182821017156146ca57600080fd5b604052919050565b60006001600160401b038211156146e7578081fd5b5060209081020190565b60006001600160401b03821115614706578081fd5b50601f01601f191660200190565b60005b8381101561472f578181015183820152602001614717565b8381111561473e576000848401525b50505050565b6001600160a01b038116811461475957600080fd5b50565b801515811461475957600080fd5b6001600160701b038116811461475957600080fd5b60ff8116811461475957600080fdfea365627a7a723158209038d4e8a8c7fe935f8ee4cc5d68a9ae777dfeb32839253038dcc9376cd96e486c6578706572696d656e74616cf564736f6c634300050f0040

Deployed Bytecode Sourcemap

55760:31054:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84455:367;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;84455:367:1;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;60947:617;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60947:617:1;;;;;;;;:::i;:::-;;;;;;;;74267:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74267:104:1;;;:::i;:::-;;;;;;;;63116:262;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63116:262:1;;;;;;;;:::i;78535:459::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78535:459:1;;;;;;;;:::i;74775:802::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74775:802:1;;;;;;;;:::i;:::-;;;;;;;;79000:615;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;79000:615:1;;;;;;;;:::i;:::-;;;;;;;;;;;61666:970;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61666:970:1;;;;;;;;:::i;60476:246::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60476:246:1;;;;;;;;:::i;64929:1855::-;;;;;;;;;:::i;68187:319::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68187:319:1;;;;;;;;:::i;57976:1416::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57976:1416:1;;;;;;;;:::i;86439:336::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;86439:336:1;;;;;;;;:::i;63617:315::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63617:315:1;;;;;;;;:::i;:::-;;;;;;;;70195:1503;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;70195:1503:1;;;;;;;;:::i;57883:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57883:33:1;;;:::i;:::-;;;;;;;;57761:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57761:27:1;;;:::i;62642:468::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62642:468:1;;;;;;;;:::i;83916:533::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;83916:533:1;;;;;;;;:::i;:::-;;;;;;;;57817:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57817:29:1;;;:::i;57697:19::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57697:19:1;;;:::i;57945:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57945:24:1;;;:::i;80317:1480::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;80317:1480:1;;;;;;;;:::i;:::-;;;;;;;;;;;;68826:372;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68826:372:1;;;;;;;;:::i;57722:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57722:33:1;;;:::i;57794:17::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57794:17:1;;;:::i;69914:275::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;69914:275:1;;;;;;;;:::i;63938:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63938:109:1;;;;;;;;:::i;56585:68::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56585:68:1;;;:::i;:::-;;;;;;;;57922:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57922:17:1;;;:::i;84828:322::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;84828:322:1;;;;;;;;:::i;82497:1413::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;82497:1413:1;;;;;;;;:::i;61570:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61570:90:1;;;;;;;;:::i;57852:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57852:25:1;;;:::i;85528:905::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;85528:905:1;;;;;;;;:::i;:::-;;;;;;;;;74017:244;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74017:244:1;;;;;;;;:::i;57657:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57657:33:1;;;:::i;64053:116::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64053:116:1;;;;;;;;:::i;12336:88::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12336:88:1;;;:::i;59832:216::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;59832:216:1;;;;;;;;:::i;85156:366::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;85156:366:1;;;;;;;;:::i;84455:367::-;84533:15;84550:16;84579:20;84601:21;84624:26;84652:29;84683:26;84713:27;84729:10;84713:15;:27::i;:::-;84578:162;;;;;;;;;;84761:9;84771:1;84761:12;;;;;;;;;;;;;;84750:23;;84801:13;84783:32;;84455:367;;;;;;;;:::o;60947:617::-;61016:7;61036:15;61053:14;61069;61085:11;61100:17;61114:2;61100:13;:17::i;:::-;61035:82;;;;;;;;61259:22;61296:5;61284:18;;;;;;;;;;61259:43;-1:-1:-1;61330:15:1;61316:10;:29;;;;;;;;;61312:246;;;61368:53;61379:5;61394:7;61404:8;61414:6;61368:10;:53::i;:::-;61361:60;;;;;;;;;61312:246;61456:15;61442:10;:29;;;;;;;;;61438:120;;;61494:53;61505:5;61520:7;61530:8;61540:6;61494:10;:53::i;61438:120::-;60947:617;;;;;;;;;;:::o;74267:104::-;74322:4;74345:19;;;;;;;74267:104::o;63116:262::-;63246:4;;:22;;-1:-1:-1;;;63246:22:1;;63208:7;;;;-1:-1:-1;;;;;63246:4:1;;;;:14;;:22;;63261:6;;63246:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63246:22:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63246:22:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63246:22:1;;;;;;;;;63299:4;;:31;;-1:-1:-1;;;63299:31:1;;63227:41;;-1:-1:-1;63278:18:1;;-1:-1:-1;;;;;63299:4:1;;;;:14;;:31;;63314:6;;63322:7;;63299:31;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63299:31:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63299:31:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63299:31:1;;;;;;;;;63278:52;-1:-1:-1;63347:24:1;:8;63278:52;63347:24;:12;:24;:::i;:::-;63340:31;63116:262;-1:-1:-1;;;;;63116:262:1:o;78535:459::-;78638:16;78807:26;78853:7;78869:6;78878:8;78888:5;78836:58;;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;78836:58:1;;;49:4:-1;78945:32:1;78939:39;;78913:75;-1:-1:-1;;;;;;78913:75:1:o;74775:802::-;75018:14;;;75030:1;75018:14;;;;;;;;;74945:23;;;;75018:14;;;;;;;;;;;;;;;;;;-1:-1:-1;;75079:16:1;;;75093:1;75079:16;;;;;;;;;74984:48;;-1:-1:-1;75042:34:1;;75079:16;;;;75042:34;;105:10:-1;75079:16:1;88:34:-1;136:17;;-1:-1;75079:16:1;75042:53;;75127:54;75148:7;75157:6;75165:8;75175:5;75127:20;:54::i;:::-;75105:16;75122:1;75105:19;;;;;;;;;;;;;:76;;;;75213:21;:19;:21::i;:::-;75191:16;75208:1;75191:19;;;;;;;;;;;;;:43;;;;75266:22;:20;:22::i;:::-;75244:16;75261:1;75244:19;;;;;;;;;;;;;:44;;;;75321:1;75298:17;75316:1;75298:20;;;;;;;;;;;;;:24;;;;;75355:1;75332:17;75350:1;75332:20;;;;;;;;;;;;;:24;;;;;75389:1;75366:17;75384:1;75366:20;;;;;;;;;;;;;:24;;;;;75400:18;56123:10;75457:20;;75491:17;75522:16;75421:127;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;75421:127:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;75421:127:1;;;179:29:-1;;;;160:49;;;75421:127:1;-1:-1:-1;;;;74775:802:1;;;;;;:::o;79000:615::-;79172:2;79168:90;;;;79281:91;79285:2;79281:91;;;;;79397:89;79401:1;79397:89;;;;;;79518:81;;;79143:466::o;61666:970::-;61772:7;61791:25;61819:7;-1:-1:-1;;;;;61819:27:1;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61819:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61819:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;61819:29:1;;;;;;;;;61791:57;;61957:31;62025:1;62005:17;:21;61991:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;61991:36:1;-1:-1:-1;61957:70:1;-1:-1:-1;62037:21:1;;62072:224;62118:1;62098:17;:21;62093:2;:26;62072:224;;;62151:8;62145:14;;:2;:14;62141:68;;;62179:15;;;;;62141:68;62243:13;62222:14;62237:2;62222:18;;;;;;;;;;;;;;;;;:34;62270:15;;;;;62121:4;62072:224;;;-1:-1:-1;62333:10:1;;:73;;-1:-1:-1;;;62333:73:1;;62306:24;;-1:-1:-1;;;;;62333:10:1;;:40;;:73;;62374:7;;62383:14;;62399:6;;62333:73;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62333:73:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62333:73:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62333:73:1;;;;;;;;;62487:9;;62306:100;;-1:-1:-1;62417:22:1;;62442:56;;62471:6;;-1:-1:-1;;;;;62487:9:1;62442:28;:56::i;:::-;62417:81;-1:-1:-1;62508:30:1;62541:26;62417:81;62560:6;62541:26;:18;:26;:::i;:::-;62508:59;-1:-1:-1;62585:44:1;:16;62508:59;62585:44;:20;:44;:::i;:::-;62578:51;61666:970;-1:-1:-1;;;;;;;;;;;61666:970:1:o;60476:246::-;60632:19;;;;;;;60624:28;;;;;;60699:2;-1:-1:-1;;;;;60667:48:1;60693:4;-1:-1:-1;;;;;60667:48:1;60681:10;-1:-1:-1;;;;;60667:48:1;;60703:3;;60708:6;;60667:48;;;;;;;;;;;;;;;;;;60476:246;;;;;;;;:::o;64929:1855::-;65239:7;65287:1;65270:7;:14;:18;65262:27;;;;;;65299:28;65361:26;;-1:-1:-1;;65361:26:1;;;;;65421:8;;:32;;;-1:-1:-1;;;65421:32:1;;;;65330:20;;65299:28;65421:49;;65458:11;;-1:-1:-1;;;;;65421:8:1;;;;:30;;:32;;;;;;;;;;;;;;;:8;:32;;;5:2:-1;;;;30:1;27;20:12;5:2;65421:32:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65421:32:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65421:32:1;;;;;;;;;:36;:49;:36;:49;:::i;:::-;65398:72;-1:-1:-1;65480:66:1;65497:28;65398:72;65514:10;65497:28;:16;:28;:::i;:::-;65527:18;65480:16;:66::i;:::-;65603:9;65598:940;65622:7;:14;65618:1;:18;:47;;;;-1:-1:-1;65640:25:1;;;65618:47;65598:940;;;65686:29;;:::i;:::-;65718:7;65726:1;65718:10;;;;;;;;;;;;;;65686:42;;65742:43;65756:6;65764:20;65742:13;:43::i;:::-;65906:45;;:::i;:::-;65954:154;65988:6;66012:20;66050:11;66062:1;66050:14;;;;;;;;;;;;;;66082:12;65954:16;:154::i;:::-;65906:202;;66127:16;:39;;;66170:1;66127:44;66123:91;;;66191:8;;;;66123:91;66228:21;66252:97;66260:6;66268:16;:39;;;66309:12;66323:13;66338:10;66252:7;:97::i;:::-;66228:121;-1:-1:-1;66387:39:1;:20;66228:121;66387:39;:24;:39;:::i;:::-;-1:-1:-1;;66440:15:1;;;;66364:62;-1:-1:-1;66473:15:1;66469:59;;66508:5;;;;;66469:59;65598:940;;;;65667:3;;65598:940;;;-1:-1:-1;66570:5:1;66548:27;;-1:-1:-1;;66548:27:1;;;66590:21;:25;66586:154;;66632:13;66650:10;-1:-1:-1;;;;;66650:15:1;66672:21;66650:48;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;66631:67:1;;;66720:8;66712:17;;;;;;66586:154;;-1:-1:-1;66757:20:1;64929:1855;-1:-1:-1;;;;;;;;64929:1855:1:o;68187:319::-;68286:7;68305:20;68328:47;68365:9;68328:8;;;;;;;;;-1:-1:-1;;;;;68328:8:1;-1:-1:-1;;;;;68328:30:1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;68328:47:1;68305:70;-1:-1:-1;68385:26:1;68414:28;68305:70;68431:10;68414:28;:16;:28;:::i;:::-;68385:57;;68459:40;68480:18;68459:20;:40::i;57976:1416::-;12203:11;;;;12202:12;12194:21;;;;;;58075:19;:17;:19::i;:::-;58104:5;:14;;-1:-1:-1;;;;;58104:14:1;;;-1:-1:-1;;;;;;58104:14:1;;;;;;;;58128:12;:28;;;;;;;;;;;;58179:21;;-1:-1:-1;;;58179:21:1;;:13;;:21;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58179:21:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58179:21:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58179:21:1;;;;;;;;;58166:4;:35;;-1:-1:-1;;;;;;58166:35:1;-1:-1:-1;;;;;58166:35:1;;;;;;;;58219:4;58211:25;;;;;;58271:27;;-1:-1:-1;;;58271:27:1;;-1:-1:-1;;;;;58271:13:1;;;;;:27;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58271:27:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58271:27:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58271:27:1;;;;;;;;;58246:10;:53;;-1:-1:-1;;;;;;58246:53:1;-1:-1:-1;;;;;58246:53:1;;;;;;;;58317:10;58309:37;;;;;;58377;;-1:-1:-1;;;58377:37:1;;-1:-1:-1;;;;;58377:20:1;;;;;:37;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58377:37:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58377:37:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58377:37:1;;;;;;;;;58356:8;:59;;-1:-1:-1;;;;;;58356:59:1;-1:-1:-1;;;;;58356:59:1;;;;;;;;58433:8;58425:33;;;;;;58491;;-1:-1:-1;;;58491:33:1;;-1:-1:-1;;;;;58491:20:1;;;;;:33;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58491:33:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58491:33:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58491:33:1;;;;;;;;;58468:9;:57;;-1:-1:-1;;;;;;58468:57:1;-1:-1:-1;;;;;58468:57:1;;;;;;;;58543:9;58535:35;;;;;;58593:29;;-1:-1:-1;;;58593:29:1;;-1:-1:-1;;;;;58593:20:1;;;;;:29;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58593:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58593:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58593:29:1;;;;;;;;;58580:4;:43;;-1:-1:-1;;;;;;58580:43:1;-1:-1:-1;;;;;58580:43:1;;;;;;58687:33;;-1:-1:-1;;;58687:33:1;;-1:-1:-1;;58687:13:1;;;;;:33;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58687:33:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58687:33:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58687:33:1;;;;;;;;;58793:4;;58808;;58761:53;;-1:-1:-1;;;58761:53:1;;58633:88;;-1:-1:-1;58731:27:1;;-1:-1:-1;;;;;58761:23:1;;;;;;:53;;58793:4;;;;58808;;58761:53;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58761:53:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58761:53:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58761:53:1;;;;;;;;;58731:83;-1:-1:-1;;;;;;58828:33:1;;58824:142;;58934:4;;58949;;58899:56;;-1:-1:-1;;;58899:56:1;;-1:-1:-1;;;;;58899:26:1;;;;;;:56;;58934:4;;;;58949;;58899:56;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58899:56:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58899:56:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58899:56:1;;;;;;;;;58877:78;;58824:142;58975:11;:49;;-1:-1:-1;;;;;;58975:49:1;-1:-1:-1;;;;;58975:49:1;;;;;;;;;;;59081:4;;59049:20;;;-1:-1:-1;;;59049:20:1;;;;59081:4;;;;59049:11;;;;:18;;:20;;;;;;;;;;;;;;:11;:20;;;5:2:-1;;;;30:1;27;20:12;5:2;59049:20:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59049:20:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59049:20:1;;;;;;;;;-1:-1:-1;;;;;59049:37:1;;59034:12;;:52;;;;;;;;;;;;;;;;;;56793:148;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;56793:148:1;;;56774:168;;49:4:-1;56774:168:1;;;;59244:18;;;;;;;;-1:-1:-1;;;59244:18:1;;;;;;;59298:21;;;;;;;;;;-1:-1:-1;;;59298:21:1;;;;59141:234;;;;56774:168;59228:36;;59282:39;;59355:4;;59141:234;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;59141:234:1;;;59118:267;;49:4:-1;59118:267:1;;;;59097:18;:288;-1:-1:-1;;;;57976:1416:1:o;86439:336::-;86598:20;56643:10;86677:32;;86723:11;86748:10;86641:127;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;86641:127:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;86641:127:1;;;179:29:-1;;;;160:49;;;86641:127:1;-1:-1:-1;86439:336:1;;;;:::o;63617:315::-;63765:28;;;;;;;;;;;;;;;;63715:26;;63779:6;63765:28;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;63765:28:1;-1:-1:-1;63753:40:1;-1:-1:-1;63808:10:1;63803:123;63824:18;;;63803:123;;;63880:4;:14;63895:6;;63902:2;63895:10;;;;;;;;;;;;;;;;;;;;;;63907:3;;63911:2;63907:7;;;;;;;;;;;;;63880:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63880:35:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63880:35:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63880:35:1;;;;;;;;;63864:9;63874:2;63864:13;;;;;;;;;;;;;;;;;:51;63844:4;;63803:123;;;;63617:315;;;;;;:::o;70195:1503::-;70323:4;70365:11;:18;70347:7;:14;:36;70339:45;;;;;;70394:20;70417:49;70454:11;70417:8;;;;;;;;;-1:-1:-1;;;;;70417:8:1;-1:-1:-1;;;;;70417:30:1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;70417:49:1;70394:72;;70476:70;70493:32;70510:7;:14;70493:12;:16;;:32;;;;:::i;:::-;70527:18;70476:16;:70::i;:::-;70556:19;:26;;-1:-1:-1;;70556:26:1;;;;;70592:879;70616:7;:14;70612:1;:18;70592:879;;;70651:29;;:::i;:::-;70683:7;70691:1;70683:10;;;;;;;;;;;;;;70651:42;;70707:23;70733:11;70745:1;70733:14;;;;;;;;;;;;;;70707:40;;70783:6;:19;;;-1:-1:-1;;;;;70769:33:1;:10;-1:-1:-1;;;;;70769:33:1;;70761:42;;;;;;70817:37;;:::i;:::-;70857:8;;:29;;-1:-1:-1;;;70857:29:1;;-1:-1:-1;;;;;70857:8:1;;;;:21;;:29;;70879:6;;70857:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70857:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70857:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70857:29:1;;;;;;;;;70817:69;;70900:24;70927:67;70955:10;:38;;;70927:6;:23;;;:27;;:67;;;;:::i;:::-;71008:8;;:76;;-1:-1:-1;;;71008:76:1;;70900:94;;-1:-1:-1;;;;;;71008:8:1;;:18;;71033:12;;71008:76;;71047:6;;70900:94;;71073:10;;71008:76;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71008:76:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71008:76:1;;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71008:76:1;;;;;;;;;;71098:32;;:::i;:::-;71133:22;71148:6;71133:14;:22::i;:::-;71098:57;;71169:19;71199:10;:24;;;-1:-1:-1;;;;;71191:45:1;;:47;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71191:47:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71191:47:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71191:47:1;;;;;;;;;71252:12;;71307:24;;71333:19;;71354:18;;;;;71374:16;;;;;71416:20;;;;71439;;;;71252:208;;-1:-1:-1;;;71252:208:1;;71169:69;;-1:-1:-1;;;;;;71252:12:1;;;;:34;;:208;;71169:69;;71307:24;;71333:19;;71354:18;71374:16;;71392;;71416:20;71439;71252:208;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71252:208:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;70632:3:1;;;;;-1:-1:-1;70592:879:1;;-1:-1:-1;;;;;;;70592:879:1;;-1:-1:-1;71502:5:1;71480:27;;-1:-1:-1;;71480:27:1;;;71521:21;:25;71517:154;;71563:13;71581:10;-1:-1:-1;;;;;71581:15:1;71603:21;71581:48;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;71562:67:1;;;71651:8;71643:17;;;;;;71517:154;;-1:-1:-1;71687:4:1;;70195:1503;-1:-1:-1;;;;70195:1503:1:o;57883:33::-;;;-1:-1:-1;;;;;57883:33:1;;:::o;57761:27::-;;;-1:-1:-1;;;;;57761:27:1;;:::o;62642:468::-;62794:10;;:60;;-1:-1:-1;;;62794:60:1;;62748:7;;;;-1:-1:-1;;;;;62794:10:1;;;;:33;;:60;;62828:7;;62837:8;;62847:6;;62794:60;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62794:60:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62794:60:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62794:60:1;;;;;;;;;62934:9;;62767:87;;-1:-1:-1;62864:22:1;;62889:56;;62918:6;;-1:-1:-1;;;;;62934:9:1;62889:28;:56::i;:::-;62864:81;;62955:30;62988:53;63007:33;63033:6;63007:7;-1:-1:-1;;;;;63007:19:1;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63007:21:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63007:21:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63007:21:1;;;;;;;;;:25;:33;:25;:33;:::i;:::-;62988:14;;:53;:18;:53;:::i;:::-;62955:86;-1:-1:-1;63059:44:1;:16;62955:86;63059:44;:20;:44;:::i;:::-;63052:51;62642:468;-1:-1:-1;;;;;;;;62642:468:1:o;83916:533::-;83992:27;;:::i;:::-;84032:20;84054:21;84077:26;84105:29;84136:26;84166:38;84182:6;:21;;;84166:15;:38::i;:::-;84031:173;;;;;;;;;;84215:15;84232:14;84248;84264:11;84279:27;84293:9;84303:1;84293:12;;;;;;;;;;;;;;84279:13;:27::i;:::-;-1:-1:-1;;;;;84316:29:1;;;;;84355:11;;;:20;;;;84385:23;;;;:15;;;:23;84418:24;:13;;;:24;-1:-1:-1;84316:5:1;;83916:533;-1:-1:-1;;;;;;;;;83916:533:1:o;57817:29::-;;;-1:-1:-1;;;;;57817:29:1;;:::o;57697:19::-;;;-1:-1:-1;;;;;57697:19:1;;:::o;57945:24::-;;;-1:-1:-1;;;57945:24:1;;;;;:::o;80317:1480::-;80736:2;80720:19;;80714:26;-1:-1:-1;;;;;;80859:86:1;80425:20;80494:26;;;-1:-1:-1;;;80973:37:1;;80965:64;;;;-1:-1:-1;;;80965:64:1;;;;;;;;;;;;;;;;;81040:25;81075:31;81166:33;81202:38;81219:1;81222:10;:17;81202:10;:16;;:38;;;;;:::i;:::-;81166:74;;81293:20;81282:54;;;;;;;;;;;;;;81438:15;;81251:85;;-1:-1:-1;81251:85:1;-1:-1:-1;81457:1:1;81438:20;81430:29;;;;;;81481:8;81490:1;81481:11;;;;;;;;;;;;;;81496:1;81481:16;81473:25;;;;;;81520:8;81529:1;81520:11;;;;;;;;;;;;;;81535:1;81520:16;81512:25;;;;;;81559:8;81568:1;81559:11;;;;;;;;;;;;;;81574:1;81559:16;81551:25;;;;;;81598:49;81625:21;:19;:21::i;:::-;81598:16;81615:1;81598:19;;;;;;;;;;;;;;:26;;:49;;;;:::i;:::-;81590:58;;;;;;81670:50;81697:22;:20;:22::i;:::-;81670:16;81687:1;81670:19;;;;;;;:50;81662:59;;;;;;81749:41;81770:16;81787:1;81770:19;;;;;;;;;;;;;;81749:20;:41::i;:::-;81742:48;;;;-1:-1:-1;81742:48:1;;-1:-1:-1;81742:48:1;-1:-1:-1;81742:48:1;;-1:-1:-1;80317:1480:1;-1:-1:-1;;;;;80317:1480:1:o;68826:372::-;68917:13;68962:1;68950:9;:13;68942:22;;;;;;68994:1;68982:9;:13;:31;;;;;69012:1;68999:10;:14;68982:31;68974:40;;;;;;69024:14;69041:34;69070:4;69041:24;:9;69055;69041:24;:13;:24;:::i;:34::-;69024:51;-1:-1:-1;69085:16:1;69104:34;69134:3;69104:25;:10;69119:9;69104:25;:14;:25;:::i;:34::-;69085:53;;69159:32;69189:1;69172:11;69160:9;:23;;;;;;;69159:32;:29;:32;:::i;:::-;69148:43;68826:372;-1:-1:-1;;;;;;68826:372:1:o;57722:33::-;;;-1:-1:-1;;;;;57722:33:1;;:::o;57794:17::-;;;-1:-1:-1;;;;;57794:17:1;;:::o;69914:275::-;70074:5;;70043:81;;-1:-1:-1;;;70043:81:1;;70002:4;;;;-1:-1:-1;;;;;70074:5:1;;;;70043:72;;:81;;70116:7;;70043:81;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70043:81:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70043:81:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70043:81:1;;;;;;;;;70018:106;-1:-1:-1;70141:41:1;:12;70018:106;70141:41;:25;:41;:::i;:::-;70134:48;69914:275;-1:-1:-1;;;;69914:275:1:o;63938:109::-;64017:23;;-1:-1:-1;;;64017:23:1;;;;;;;;56585:68;-1:-1:-1;;;56585:68:1;:::o;57922:17::-;;;-1:-1:-1;;;;;57922:17:1;;:::o;84828:322::-;84909:16;84938:20;84960:21;84983:26;85011:29;85042:26;85072:38;85088:6;:21;;;85072:15;:38::i;:::-;84937:173;;;;;;;;;;85131:9;85141:1;85131:12;;;;;;;;;;;;;;85120:23;;84828:322;;;;;;;;:::o;82497:1413::-;82921:2;82905:19;;82899:26;-1:-1:-1;;;;;;83044:86:1;82610:20;82679:26;;;-1:-1:-1;;;83158:33:1;;83150:60;;;;-1:-1:-1;;;83150:60:1;;;;;;;;;-1:-1:-1;;;;83418:2:1;83402:19;;;83505:17;83570:19;;;83564:26;83642:19;;;83636:26;83715:19;;;83709:26;82497:1413;;83505:17;;83548:43;;;;;;83620;;;;;;83693;;;;82497:1413::o;61570:90::-;-1:-1:-1;61626:7:1;;61570:90::o;57852:25::-;;;-1:-1:-1;;;;;57852:25:1;;:::o;85528:905::-;85724:34;;:::i;:::-;85760:18;85790:23;85816:58;85840:7;85850:6;85858:8;85868:5;85816:15;:58::i;:::-;85790:84;;85892:49;85919:7;85929:11;85892:18;:49::i;:::-;85884:116;;;;-1:-1:-1;;;85884:116:1;;;;;;;;;-1:-1:-1;;;;;86010:33:1;;;;86053:28;;;:42;;;86105:28;;;:42;;;86157:33;;;:58;;;86225:16;;;:24;;;86259:26;;;:39;;;86337:22;:20;:22::i;:::-;86308:26;;;:51;86382:8;;:34;;-1:-1:-1;;;86382:34:1;;-1:-1:-1;;;;;86382:8:1;;;;:21;;:34;;86308:11;;86382:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86382:34:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86382:34:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;86382:34:1;;;;;;;;;:44;;;86369:57;;85528:905;;;;;;;;;;;;:::o;74017:244::-;74119:4;74135:16;74154:27;74174:6;74154:19;:27::i;:::-;74224:19;;74209:45;;-1:-1:-1;;;74209:45:1;;74135:46;;-1:-1:-1;74209:4:1;;:14;;:45;;74135:46;;74209:45;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74209:45:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74209:45:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74209:45:1;;;;;;;;;74198:56;;;;;74017:244;-1:-1:-1;;;74017:244:1:o;57657:33::-;;;;:::o;64053:116::-;64158:4;64053:116;;;;:::o;12336:88::-;12383:4;12406:11;;;12336:88;:::o;59832:216::-;59959:19;;;;;;;59951:28;;;;;;60027:2;-1:-1:-1;;;;;59994:47:1;60021:4;-1:-1:-1;;;;;59994:47:1;60009:10;-1:-1:-1;;;;;59994:47:1;;60031:2;60035:5;59994:47;;;;;;;;;;;;;;;;59832:216;;;;;;:::o;85156:366::-;85333:34;;:::i;:::-;85369:18;85406:109;85426:10;85438:5;85445:11;85458:6;85466:7;85475:8;85485:22;85509:5;85406:19;:109::i;:::-;85399:116;;;;85156:366;;;;;;;;;;:::o;21761:167::-;21819:7;21847:1;21842;:6;21838:84;;-1:-1:-1;21871:1:1;21864:8;;21838:84;-1:-1:-1;21910:1:1;21903:8;;75973:737;76217:16;;;76231:1;76217:16;;;;;;;;;76149:23;;;;76217:16;;;;;;;105:10:-1;76217:16:1;88:34:-1;-1:-1;;76275:16:1;;;76289:1;76275:16;;;;;;;;;76188:45;;-1:-1:-1;76243:29:1;;76275:16;-1:-1:-1;76275:16:1;;;;;;105:10:-1;76275:16:1;88:34:-1;136:17;;-1:-1;76275:16:1;76243:48;;76302:16;76321:53;76340:7;76350:6;76358:8;76368:5;76321:10;:53::i;:::-;76302:72;;76399:8;76384:9;76394:1;76384:12;;;;;;;;;;;;;:23;;;;;76435:1;76417:12;76430:1;76417:15;;;;;;;;;;;;;;;;;;:19;;;;76475:12;;;76485:1;76475:12;;;;;;;-1:-1:-1;;;76510:165:1;76584:4;76603:9;76626:12;76475;76510:165;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;76510:165:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;76510:165:1;;;179:29:-1;;;;160:49;;;76510:165:1;-1:-1:-1;;;;;75973:737:1;;;;;;:::o;76900:251::-;77101:4;;77029:87;;76977:23;;-1:-1:-1;;;77065:14:1;77029:87;;-1:-1:-1;;;;;77101:4:1;;77029:87;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;77029:87:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;77029:87:1;;;179:29:-1;;;;160:49;;;77029:87:1;-1:-1:-1;76900:251:1;:::o;77343:500::-;77489:16;;;77503:1;77489:16;;;;;;77547;;;;;;77602:12;;;77421:23;77602:12;;;;;;77711:10;;77489:16;;77547;-1:-1:-1;;;77673:16:1;77637:171;;-1:-1:-1;;;;;77711:10:1;77489:16;;77547;77637:171;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;77637:171:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;77637:171:1;;;179:29:-1;;;;160:49;;;77637:171:1;-1:-1:-1;;;;77343:500:1;:::o;21195:283::-;21253:7;21350:9;21366:1;21362;:5;;;;;;;21195:283;-1:-1:-1;;;;21195:283:1:o;21611:144::-;21669:7;21700:5;;;21723:6;;;;21715:15;;;;;;21747:1;21611:144;-1:-1:-1;;;21611:144:1:o;20768:421::-;20826:7;21066:6;21062:45;;-1:-1:-1;21095:1:1;21088:8;;21062:45;21129:5;;;21133:1;21129;:5;:1;21152:5;;;;;:10;21144:19;;;;;67513:668;67642:18;67618:21;:42;67614:561;;;67719:21;67698:42;;67676:19;67770:33;67698:42;67770:20;:33::i;:::-;67754:49;;67834:18;67825:5;:27;;67817:113;;;;-1:-1:-1;;;67817:113:1;;;;;;;;;67952:4;;67990:11;;67952:58;;-1:-1:-1;;;67952:58:1;;-1:-1:-1;;;;;67952:4:1;;;;:17;;:58;;67970:10;;67990:11;;;;68004:5;;67952:58;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67952:58:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67952:58:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67952:58:1;;;;;;;;;67944:67;;;;;;68025:11;;68042:12;;-1:-1:-1;;;;;68025:11:1;;;;:16;;-1:-1:-1;;;68042:12:1;;;;:30;;68061:11;68042:30;;;68057:1;68042:30;68074:12;;-1:-1:-1;;;68074:12:1;;;;:30;;68103:1;68074:30;;;68089:11;68074:30;68114:4;68025:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68025:99:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;68138:4:1;;:26;;-1:-1:-1;;;68138:26:1;;-1:-1:-1;;;;;68138:4:1;;;;-1:-1:-1;68138:13:1;;-1:-1:-1;68138:26:1;;68152:11;;68138:26;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68138:26:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68138:26:1;;;;67614:561;;;67513:668;;:::o;69204:704::-;69320:52;69349:22;:20;:22::i;:::-;69320:21;;;;;:52;:28;:52;:::i;:::-;69312:61;;;;;;69418:6;:23;;;69391:6;:23;;;:50;69383:59;;;;;;69453:30;69485:21;69510:45;69533:6;:21;;;69510:22;:45::i;:::-;69452:103;;;;69566:15;69583:14;69599;69615:11;69630:28;69644:13;69630;:28::i;:::-;69565:93;;;;;;;;69668:17;69696:7;-1:-1:-1;;;;;69688:28:1;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69688:30:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69688:30:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;69688:30:1;;;;;;;;;69668:50;;69736:58;69763:7;69773:20;69736:18;:58::i;:::-;69728:125;;;;-1:-1:-1;;;69728:125:1;;;;;;;;;-1:-1:-1;;;;;69871:29:1;;69896:4;69871:29;69863:38;;;;;;69204:704;;;;;;;;;:::o;66790:717::-;66943:40;;:::i;:::-;67028:165;;66995:30;;-1:-1:-1;;;67064:40:1;67028:165;;67118:6;;67138:21;;67173:10;;67028:165;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;67028:165:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;67028:165:1;;;179:29:-1;;;;160:49;;;67259:8:1;;67251:61;;67028:165;;-1:-1:-1;;;67223:24:1;;-1:-1:-1;;;;;67259:8:1;;;;67280:12;;67251:61;;67028:165;;67251:61;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;67204:108:1;;;;67326:11;67322:151;;;67360:11;:18;67382:3;67360:25;67353:33;;;;67425:11;67414:48;;;;;;;;;;;;;67322:151;-1:-1:-1;;;66790:717:1;;;;;;:::o;71704:1303::-;71847:21;71985:37;;:::i;:::-;72025:22;72040:6;72025:14;:22::i;:::-;71985:62;;72268:40;72292:6;72300:7;72268:23;:40::i;:::-;72263:80;;72331:1;72324:8;;;;;72263:80;72502:6;-1:-1:-1;;;;;72479:29:1;:6;:19;;;-1:-1:-1;;;;;72479:29:1;;72475:74;;;72531:7;72524:14;;;;;72475:74;72559:24;72585:13;72602:9;;;;;;;;;-1:-1:-1;;;;;72602:9:1;-1:-1:-1;;;;;72602:24:1;;72635:15;:29;;;72667:15;:23;;;72692:15;:21;;;72727:15;:25;;;72715:38;;;;;;;;;;72755:6;:19;;;72776:7;72785:12;72799:13;72814:6;72602:219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72602:219:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72602:219:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72602:219:1;;;;;;;;;72558:263;;-1:-1:-1;72558:263:1;-1:-1:-1;72847:29:1;:7;72558:263;72847:29;:11;:29;:::i;:::-;72831:45;;72886:84;72901:6;72909:15;72926:6;72934:13;72949;72964:5;72886:14;:84::i;:::-;-1:-1:-1;;;71704:1303:1;;;;;;;:::o;21484:121::-;21542:7;21574:1;21569;:6;;21561:15;;;;;;-1:-1:-1;21593:5:1;;;21484:121::o;68512:308::-;68584:7;68604:17;68623;68642:26;68672:11;;;;;;;;;-1:-1:-1;;;;;68672:11:1;-1:-1:-1;;;;;68672:23:1;;:25;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68672:25:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68672:25:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68672:25:1;;;;;;;;;68603:94;;;;;;68714:99;68726:10;68738:12;;;;;;;;;;;:36;;68765:9;68738:36;;;68753:9;68738:36;-1:-1:-1;;;;;68714:99:1;68776:12;;;;;;;;;;;:36;;68803:9;68776:36;;;68791:9;68776:36;-1:-1:-1;;;;;68714:99:1;:11;:99::i;12239:91::-;12203:11;;;;12202:12;12194:21;;;;;;12305:11;:18;;-1:-1:-1;;12305:18:1;12319:4;12305:18;;;12239:91::o;18365:669::-;18499:19;18679:2;18672:4;:9;18668:48;;;18697:8;;;18668:48;18734:1;:8;18729:2;:13;18725:52;;;18758:8;;;18725:52;18869:4;18864:2;:9;18854:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;18854:20:1;87:34:-1;135:17;;-1:-1;18854:20:1;;18845:29;;18884:120;18905:23;:6;:21;:23::i;:::-;18963:4;18942:18;:1;:16;:18::i;:::-;:25;18981:6;:13;18884:7;:120::i;12690:403::-;12811:10;13040:3;:10;13026:3;:10;:24;:60;;;;;13082:3;13072:14;;;;;;13064:3;13054:14;;;;;;:32;13019:67;12690:403;-1:-1:-1;;;12690:403:1:o;22681:107::-;22748:4;22775:1;22771;:5;;;;;;:10;;22681:107;-1:-1:-1;;;22681:107:1:o;78035:494::-;78181:16;;;78195:1;78181:16;;;;;;78239;;;;;;78294:12;;;78113:23;78294:12;;;;;;78181:16;-1:-1:-1;;;78329:165:1;78403:4;78181:16;;78239;78329:165;;;;;73013:998;73223:8;;:29;;-1:-1:-1;;;73223:29:1;;73202:18;;-1:-1:-1;;;;;73223:8:1;;:21;;:29;;73245:6;;73223:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73223:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73223:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73223:29:1;;;;;;;;;:39;;;73304:16;;;73318:1;73304:16;;;73272:29;73304:16;;;;;;73223:39;;-1:-1:-1;73272:29:1;;73304:16;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;;73362:17:1;;;73376:2;73362:17;;;;;;;;;73272:48;;-1:-1:-1;73330:29:1;;73362:17;-1:-1:-1;73362:17:1;;;17:15:-1;;105:10;73362:17:1;88:34:-1;136:17;;-1:-1;73362:17:1;73330:49;;73389:22;73426:15;:25;;;73414:38;;;;;;;;;;73389:63;;73480:6;:19;;;73462:12;73475:1;73462:15;;;;;;;;;;;;;:37;-1:-1:-1;;;;;73462:37:1;;;-1:-1:-1;;;;;73462:37:1;;;;;73527:6;73509:12;73522:1;73509:15;;;;;;;;;;;;;:24;-1:-1:-1;;;;;73509:24:1;;;-1:-1:-1;;;;;73509:24:1;;;;;73561:15;:21;;;73543:12;73556:1;73543:15;;;;;;;;;;;;;:39;;;;;73610:1;73592:12;73605:1;73592:15;;;;;;;;;;;;;:19;;;;;73639:15;:23;;;73621:41;;:12;73634:1;73621:15;;;;;;;;;;;;;:41;;;;;73690:5;73672:12;73685:1;73672:15;;;;;;;;;;;;;:23;;;;;73723:13;73705:12;73718:1;73705:15;;;;;;;;;;;;;:31;;;;;73764:1;73746:12;73759:1;73746:15;;;;;;;;;;;;;:19;;;;;73793:1;73775:12;73788:1;73775:15;;;;;;;;;;;;;:19;;;;;73804:12;;;;;;;;;-1:-1:-1;;;;;73804:12:1;-1:-1:-1;;;;;73804:32:1;;73845:15;:29;;;-1:-1:-1;;;;;73837:50:1;;:52;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73837:52:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73837:52:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73837:52:1;;;;;;;;;73899:29;;73931:10;73943:13;73964:10;73958:17;;;;;;;;73977:12;73991;73804:200;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73804:200:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73804:200:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73804:200:1;;;;;;;;;;73013:998;;;;;;;;;;:::o;13293:228::-;13472:2;13461:14;;13293:228::o;13760:4297::-;13910:2;13901:6;:11;13897:4154;;;14199:1;14189:6;14185:2;14181:15;14176:3;14172:25;14168:33;14250:4;14246:9;14237:6;14231:13;14227:29;14299:4;14292;14286:11;14282:22;14340:1;14337;14334:8;14328:4;14321:22;;;;14138:219;;;14461:4;14451:6;:14;14447:59;;;14485:7;;14447:59;15195:4;15186:6;:13;15182:2859;;;15521:2;15513:6;15509:15;15499:25;;15569:6;15561;15557:19;15619:6;15613:4;15609:17;15926:4;15920:11;16194:198;16212:4;16204:6;16201:16;16194:198;;;16260:13;;16247:27;;16321:2;16357:13;;;;16309:15;;;;16194:198;;;16461:18;;-1:-1:-1;15228:1269:1;;;16742:2;16734:6;16730:15;16720:25;;16790:6;16782;16778:19;16840:6;16834:4;16830:17;17150:6;17144:13;17729:191;17746:4;17740;17736:15;17729:191;;;17794:11;;17781:25;;-1:-1:-1;;17839:13:1;;;;17885;;;;17729:191;;;17990:19;;-1:-1:-1;;16544:1483:1;13760:4297;;;:::o;55760:31054::-;;;;;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;55760:31054:1;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;55760:31054:1;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;301:352;;;431:3;424:4;416:6;412:17;408:27;398:2;;-1:-1;;439:12;398:2;-1:-1;469:20;;-1:-1;;;;;498:30;;495:2;;;-1:-1;;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;575:4;;610:6;606:17;567:6;592:32;;589:41;586:2;;;643:1;;633:12;586:2;391:262;;;;;;677:693;;806:3;799:4;791:6;787:17;783:27;773:2;;-1:-1;;814:12;773:2;854:6;848:13;876:81;891:65;949:6;891:65;;;876:81;;;985:21;;;867:90;-1:-1;1029:4;1042:14;;;;1017:17;;;1137:1;1122:242;1147:6;1144:1;1141:13;1122:242;;;1223:3;1217:10;1021:6;1205:23;5441:3;5422:17;1205:23;5422:17;5418:27;5408:2;;1137:1;;5449:12;5408:2;1029:4;1205:23;;5483:13;5511:60;5526:44;5563:6;5526:44;;5511:60;5591:6;5584:5;5577:21;5695:3;5615:17;5686:6;1205:23;5677:16;;5674:25;5671:2;;;1137:1;;5702:12;5671:2;5722:39;5754:6;1029:4;5653:5;5649:16;5615:17;1205:23;5615:17;5722:39;;;1235:66;;-1:-1;;1315:14;;;;1343;;;;1169:1;1162:9;1122:242;;1394:693;;1516:3;1509:4;1501:6;1497:17;1493:27;1483:2;;-1:-1;;1524:12;1483:2;1571:6;1558:20;1593:85;1608:69;1670:6;1608:69;;1593:85;1706:21;;;1584:94;-1:-1;1750:4;1763:14;;;;1738:17;;1858:1;1843:238;1868:6;1865:1;1862:13;1843:238;;;1975:42;2013:3;1750:4;1951:3;1938:17;1742:6;1926:30;;1975:42;;;1963:55;;1750:4;2032:14;;;;2060;;;;;1890:1;1883:9;1843:238;;;1847:14;;;;1476:611;;;;;2128:735;;2264:3;2257:4;2249:6;2245:17;2241:27;2231:2;;-1:-1;;2272:12;2231:2;2319:6;2306:20;2341:99;2356:83;2432:6;2356:83;;2341:99;2468:21;;;2332:108;-1:-1;2512:4;2525:14;;;;2500:17;;2620:1;2605:252;2630:6;2627:1;2624:13;2605:252;;;2737:56;2789:3;2512:4;2713:3;2700:17;2504:6;2688:30;;2737:56;;;2725:69;;2512:4;2808:14;;;;2836;;;;;2652:1;2645:9;2605:252;;4547:336;;;4661:3;4654:4;4646:6;4642:17;4638:27;4628:2;;-1:-1;;4669:12;4628:2;-1:-1;4699:20;;-1:-1;;;;;4728:30;;4725:2;;;-1:-1;;4761:12;4725:2;4805:4;4797:6;4793:17;4781:29;;4856:3;4805:4;4836:17;4797:6;4822:32;;4819:41;4816:2;;;4873:1;;4863:12;4892:432;;4989:3;4982:4;4974:6;4970:17;4966:27;4956:2;;-1:-1;;4997:12;4956:2;5044:6;5031:20;5066:60;5081:44;5118:6;5081:44;;5066:60;5057:69;;5146:6;5139:5;5132:21;5250:3;5182:4;5241:6;5174;5232:16;;5229:25;5226:2;;;5267:1;;5257:12;5226:2;86852:6;5182:4;5174:6;5170:17;5182:4;5208:5;5204:16;86829:30;86908:1;86890:16;;;5182:4;86890:16;86883:27;5208:5;4949:375;-1:-1;;4949:375;6953:1029;;7078:4;7066:9;7061:3;7057:19;7053:30;7050:2;;;-1:-1;;7086:12;7050:2;7114:20;7078:4;7114:20;;;7105:29;;15660:6;15654:13;7216:16;7209:86;7374:2;7443:9;7439:22;15654:13;7374:2;7393:5;7389:16;7382:86;7537:2;7606:9;7602:22;15654:13;7537:2;7556:5;7552:16;7545:86;7700:2;7769:9;7765:22;15654:13;7700:2;7719:5;7715:16;7708:86;7866:3;7936:9;7932:22;15654:13;7866:3;7886:5;7882:16;7875:86;7044:938;;;;;9823:2714;;9931:6;;9919:9;9914:3;9910:19;9906:32;9903:2;;;-1:-1;;9941:12;9903:2;9969:22;9931:6;9969:22;;;9960:31;;;10081:49;10126:3;10102:22;10081:49;;;10063:16;10056:75;10233:49;10278:3;10200:2;10258:9;10254:22;10233:49;;;10200:2;10219:5;10215:16;10208:75;10392:49;10437:3;10359:2;10417:9;10413:22;10392:49;;;10359:2;10378:5;10374:16;10367:75;10545:49;10590:3;10512:2;10570:9;10566:22;10545:49;;;10512:2;10531:5;10527:16;10520:75;10668:3;10727:9;10723:22;15506:20;10668:3;10688:5;10684:16;10677:75;10825:3;10884:9;10880:22;15506:20;10825:3;10845:5;10841:16;10834:75;10974:3;11033:9;11029:22;15506:20;10974:3;10994:5;10990:16;10983:75;11123:3;11182:9;11178:22;15506:20;11123:3;11143:5;11139:16;11132:75;11285:3;;11346:9;11342:22;15506:20;11285:3;11305:5;11301:18;11294:77;;11432:3;;11493:9;11489:22;15506:20;11432:3;11452:5;11448:18;11441:77;;11617:3;;11606:9;11602:19;11589:33;-1:-1;;;;;11642:18;11634:6;11631:30;11628:2;;;10049:1;;11664:12;11628:2;11711:54;11761:3;11752:6;11741:9;11737:22;11711:54;;;11617:3;11695:5;11691:18;11684:82;11865:3;;;;11854:9;11850:19;11837:33;11823:47;;11642:18;11882:6;11879:30;11876:2;;;10049:1;;11912:12;11876:2;11959:54;12009:3;12000:6;11989:9;11985:22;11959:54;;;11865:3;11943:5;11939:18;11932:82;12116:3;;;;12105:9;12101:19;12088:33;12074:47;;11642:18;12133:6;12130:30;12127:2;;;10049:1;;12163:12;12127:2;12210:54;12260:3;12251:6;12240:9;12236:22;12210:54;;;12116:3;12194:5;12190:18;12183:82;12367:3;;;;12356:9;12352:19;12339:33;12325:47;;11642:18;12384:6;12381:30;12378:2;;;10049:1;;12414:12;12378:2;;12461:54;12511:3;12502:6;12491:9;12487:22;12461:54;;;12367:3;12445:5;12441:18;12434:82;;;9897:2640;;;;;16126:241;;16230:2;16218:9;16209:7;16205:23;16201:32;16198:2;;;-1:-1;;16236:12;16198:2;85:6;72:20;97:33;124:5;97:33;;16374:263;;16489:2;16477:9;16468:7;16464:23;16460:32;16457:2;;;-1:-1;;16495:12;16457:2;226:6;220:13;238:33;265:5;238:33;;16644:366;;;16765:2;16753:9;16744:7;16740:23;16736:32;16733:2;;;-1:-1;;16771:12;16733:2;85:6;72:20;97:33;124:5;97:33;;;16823:63;-1:-1;16923:2;16962:22;;72:20;97:33;72:20;97:33;;;16931:63;;;;16727:283;;;;;;17017:1179;;;;;;;;;17278:3;17266:9;17257:7;17253:23;17249:33;17246:2;;;-1:-1;;17285:12;17246:2;85:6;72:20;97:33;124:5;97:33;;;17337:63;-1:-1;17437:2;17476:22;;72:20;97:33;72:20;97:33;;;17445:63;-1:-1;17573:2;17558:18;;17545:32;-1:-1;;;;;17586:30;;;17583:2;;;-1:-1;;17619:12;17583:2;17657:80;17729:7;17720:6;17709:9;17705:22;17657:80;;;17647:90;;-1:-1;17647:90;-1:-1;17802:2;17787:18;;17774:32;;-1:-1;17815:30;;;17812:2;;;-1:-1;;17848:12;17812:2;17886:80;17958:7;17949:6;17938:9;17934:22;17886:80;;;17876:90;;-1:-1;17876:90;-1:-1;18031:3;18016:19;;18003:33;;-1:-1;18045:30;;;18042:2;;;-1:-1;;18078:12;18042:2;;18116:64;18172:7;18163:6;18152:9;18148:22;18116:64;;;17240:956;;;;-1:-1;17240:956;;-1:-1;17240:956;;;;;;18106:74;-1:-1;;;17240:956;18203:867;;;;;;;18394:3;18382:9;18373:7;18369:23;18365:33;18362:2;;;-1:-1;;18401:12;18362:2;85:6;72:20;97:33;124:5;97:33;;;18453:63;-1:-1;18553:2;18592:22;;72:20;97:33;72:20;97:33;;;18561:63;-1:-1;18661:2;18700:22;;15506:20;;-1:-1;18769:2;18808:22;;15506:20;;-1:-1;18905:3;18890:19;;18877:33;-1:-1;;;;;18919:30;;18916:2;;;-1:-1;;18952:12;18916:2;18990:64;19046:7;19037:6;19026:9;19022:22;18990:64;;;18356:714;;;;-1:-1;18356:714;;-1:-1;18356:714;;18980:74;;18356:714;-1:-1;;;18356:714;19077:360;;;19195:2;19183:9;19174:7;19170:23;19166:32;19163:2;;;-1:-1;;19201:12;19163:2;85:6;72:20;97:33;124:5;97:33;;;19253:63;-1:-1;19353:2;19389:22;;4053:20;4078:30;4053:20;4078:30;;19444:645;;;;;19613:3;19601:9;19592:7;19588:23;19584:33;19581:2;;;-1:-1;;19620:12;19581:2;85:6;72:20;97:33;124:5;97:33;;;19672:63;-1:-1;19772:2;19827:22;;6655:20;6680:49;6655:20;6680:49;;;19780:79;-1:-1;19896:2;19933:22;;15921:20;15946:31;15921:20;15946:31;;;19575:514;;;;-1:-1;19904:61;;20002:2;20041:22;15506:20;;-1:-1;;19575:514;20096:366;;;20217:2;20205:9;20196:7;20192:23;20188:32;20185:2;;;-1:-1;;20223:12;20185:2;85:6;72:20;97:33;124:5;97:33;;;20275:63;20375:2;20414:22;;;;15506:20;;-1:-1;;;20179:283;20469:609;;;;;20620:3;20608:9;20599:7;20595:23;20591:33;20588:2;;;-1:-1;;20627:12;20588:2;85:6;72:20;97:33;124:5;97:33;;;20679:63;-1:-1;20779:2;20818:22;;15506:20;;-1:-1;20887:2;20924:22;;15921:20;15946:31;15921:20;15946:31;;;20895:61;-1:-1;20993:2;21030:22;;15921:20;15946:31;15921:20;15946:31;;;20582:496;;;;-1:-1;20582:496;;-1:-1;;20582:496;21085:1113;;;;;;;;;21304:3;21292:9;21283:7;21279:23;21275:33;21272:2;;;-1:-1;;21311:12;21272:2;85:6;72:20;97:33;124:5;97:33;;;21363:63;-1:-1;21463:2;21500:22;;15921:20;15946:31;15921:20;15946:31;;;21471:61;-1:-1;21569:2;21608:22;;15506:20;;-1:-1;21677:2;21716:22;;15506:20;;-1:-1;21785:3;21825:22;;72:20;97:33;72:20;97:33;;;21794:63;-1:-1;21894:3;21932:22;;15921:20;15946:31;15921:20;15946:31;;;21266:932;;;;-1:-1;21266:932;;;;;;21903:61;;-1:-1;;;22001:3;22041:22;;15506:20;;22110:3;22150:22;15506:20;;21266:932;22205:678;;;;;22396:2;22384:9;22375:7;22371:23;22367:32;22364:2;;;-1:-1;;22402:12;22364:2;22460:17;22447:31;-1:-1;;;;;22498:18;22490:6;22487:30;22484:2;;;-1:-1;;22520:12;22484:2;22558:80;22630:7;22621:6;22610:9;22606:22;22558:80;;;22548:90;;-1:-1;22548:90;-1:-1;22703:2;22688:18;;22675:32;;-1:-1;22716:30;;;22713:2;;;-1:-1;;22749:12;22713:2;;22787:80;22859:7;22850:6;22839:9;22835:22;22787:80;;;22358:525;;;;-1:-1;22777:90;-1:-1;;;;22358:525;22890:811;;;;23102:2;23090:9;23081:7;23077:23;23073:32;23070:2;;;-1:-1;;23108:12;23070:2;23166:17;23153:31;-1:-1;;;;;23204:18;23196:6;23193:30;23190:2;;;-1:-1;;23226:12;23190:2;23256:97;23345:7;23336:6;23325:9;23321:22;23256:97;;;23246:107;;23418:2;23407:9;23403:18;23390:32;23376:46;;23204:18;23434:6;23431:30;23428:2;;;-1:-1;;23464:12;23428:2;;23494:83;23569:7;23560:6;23549:9;23545:22;23494:83;;;23484:93;;;23614:2;23657:9;23653:22;15506:20;23622:63;;23064:637;;;;;;23708:651;;;23887:2;23875:9;23866:7;23862:23;23858:32;23855:2;;;-1:-1;;23893:12;23855:2;23944:17;23938:24;-1:-1;;;;;23982:18;23974:6;23971:30;23968:2;;;-1:-1;;24004:12;23968:2;24102:6;24091:9;24087:22;3391:3;3384:4;3376:6;3372:17;3368:27;3358:2;;-1:-1;;3399:12;3358:2;3439:6;3433:13;3419:27;;3461:76;3476:60;3529:6;3476:60;;3461:76;3543:16;3579:6;3572:5;3565:21;3609:4;;3626:3;3622:14;3615:21;;3609:4;3601:6;3597:17;3731:3;3609:4;;3715:6;3711:17;3601:6;3702:27;;3699:36;3696:2;;;-1:-1;;3738:12;3696:2;-1:-1;3764:10;;3758:217;3783:6;3780:1;3777:13;3758:217;;;15654:13;;3851:61;;3805:1;3798:9;;;;;3926:14;;;;3954;;3758:217;;;-1:-1;24162:18;;24156:25;24024:95;;-1:-1;24156:25;-1:-1;;;24190:30;;;24187:2;;;-1:-1;;24223:12;24187:2;;24253:90;24335:7;24326:6;24315:9;24311:22;24253:90;;;24243:100;;;23849:510;;;;;;24366:257;;24478:2;24466:9;24457:7;24453:23;24449:32;24446:2;;;-1:-1;;24484:12;24446:2;4201:6;4195:13;4213:30;4237:5;4213:30;;24630:345;;24743:2;24731:9;24722:7;24718:23;24714:32;24711:2;;;-1:-1;;24749:12;24711:2;24807:17;24794:31;-1:-1;;;;;24837:6;24834:30;24831:2;;;-1:-1;;24867:12;24831:2;24897:62;24951:7;24942:6;24931:9;24927:22;24897:62;;24982:440;;;25140:2;25128:9;25119:7;25115:23;25111:32;25108:2;;;-1:-1;;25146:12;26788:314;;26928:3;26916:9;26907:7;26903:23;26899:33;26896:2;;;-1:-1;;26935:12;26896:2;26997:89;27078:7;27054:22;26997:89;;27438:317;;27580:2;27568:9;27559:7;27555:23;27551:32;27548:2;;;-1:-1;;27586:12;27548:2;9260:20;27580:2;9260:20;;;16071:6;16065:13;16083:31;16108:5;16083:31;;;9344:84;;9494:2;9559:22;;;4470:13;9509:16;;;9502:86;9672:2;9737:22;;;15654:13;9687:16;;;9680:86;;;;-1:-1;9351:16;27542:213;-1:-1;27542:213;27762:373;;27889:2;27877:9;27868:7;27864:23;27860:32;27857:2;;;-1:-1;;27895:12;27857:2;27953:17;27940:31;-1:-1;;;;;27983:6;27980:30;27977:2;;;-1:-1;;28013:12;27977:2;28043:76;28111:7;28102:6;28091:9;28087:22;28043:76;;28142:498;;;28286:2;28274:9;28265:7;28261:23;28257:32;28254:2;;;-1:-1;;28292:12;28254:2;28350:17;28337:31;-1:-1;;;;;28380:6;28377:30;28374:2;;;-1:-1;;28410:12;28374:2;28440:76;28508:7;28499:6;28488:9;28484:22;28440:76;;;28430:86;28553:2;28592:22;;;;4322:20;;-1:-1;;;;28248:392;29152:533;;;;29300:2;29288:9;29279:7;29275:23;29271:32;29268:2;;;-1:-1;;29306:12;29268:2;15382:6;15376:13;15394:33;15421:5;15394:33;;;29469:2;29519:22;;15376:13;29358:74;;-1:-1;15394:33;15376:13;15394:33;;;29588:2;29637:22;;15794:13;29477:74;;-1:-1;82662:10;82651:22;;89585:34;;89575:2;;-1:-1;;89623:12;89575:2;29596:73;;;;29262:423;;;;;;29692:241;;29796:2;29784:9;29775:7;29771:23;29767:32;29764:2;;;-1:-1;;29802:12;29764:2;-1:-1;15506:20;;29758:175;-1:-1;29758:175;29940:263;;30055:2;30043:9;30034:7;30030:23;30026:32;30023:2;;;-1:-1;;30061:12;30023:2;-1:-1;15654:13;;30017:186;-1:-1;30017:186;30210:1315;;;;;;;;30490:3;30478:9;30469:7;30465:23;30461:33;30458:2;;;-1:-1;;30497:12;30458:2;15519:6;15506:20;30549:63;;30649:2;30692:9;30688:22;4322:20;30657:63;;30757:2;30800:9;30796:22;4322:20;30765:63;;30865:2;30908:9;30904:22;15506:20;30873:63;;30973:3;31017:9;31013:22;15506:20;30982:63;;31110:3;31099:9;31095:19;31082:33;-1:-1;;;;;31135:18;31127:6;31124:30;31121:2;;;-1:-1;;31157:12;31121:2;31187:97;31276:7;31267:6;31256:9;31252:22;31187:97;;;31177:107;;31349:3;31338:9;31334:19;31321:33;31307:47;;31135:18;31366:6;31363:30;31360:2;;;-1:-1;;31396:12;31360:2;;31426:83;31501:7;31492:6;31481:9;31477:22;31426:83;;;31416:93;;;30452:1073;;;;;;;;;;;31532:366;;;31653:2;31641:9;31632:7;31628:23;31624:32;31621:2;;;-1:-1;;31659:12;31621:2;-1:-1;;15506:20;;;31811:2;31850:22;;;15506:20;;-1:-1;31615:283;31905:399;;;32037:2;32025:9;32016:7;32012:23;32008:32;32005:2;;;-1:-1;;32043:12;32005:2;-1:-1;;15654:13;;32206:2;32256:22;;;15654:13;;;;;-1:-1;31999:305;32311:491;;;;32449:2;32437:9;32428:7;32424:23;32420:32;32417:2;;;-1:-1;;32455:12;32417:2;-1:-1;;15506:20;;;32607:2;32646:22;;15506:20;;-1:-1;32715:2;32754:22;;;15506:20;;32411:391;-1:-1;32411:391;32809:987;;;;;;;;33011:3;32999:9;32990:7;32986:23;32982:33;32979:2;;;-1:-1;;33018:12;32979:2;15934:6;15921:20;15946:31;15971:5;15946:31;;;33070:61;-1:-1;33168:2;33207:22;;15506:20;;-1:-1;33276:2;33315:22;;15506:20;;-1:-1;33384:2;33423:22;;72:20;97:33;72:20;97:33;;;33392:63;-1:-1;33492:3;33530:22;;15921:20;15946:31;15921:20;15946:31;;;32973:823;;;;-1:-1;32973:823;;;;33501:61;33599:3;33639:22;;15506:20;;-1:-1;33708:3;33748:22;;;15506:20;;32973:823;-1:-1;;32973:823;33804:173;-1:-1;;;;;82445:54;34589:45;;33966:4;33957:14;;33884:93;34502:137;-1:-1;;;;;82445:54;34589:45;;34583:56;36718:467;79887:19;;;36718:467;-1:-1;;;;;36966:78;;36963:2;;;-1:-1;;37047:12;36963:2;79936:4;37082:6;37078:17;86852:6;86847:3;79936:4;79931:3;79927:14;86829:30;86890:16;;;;79936:4;86890:16;86883:27;;;-1:-1;86890:16;;36850:335;-1:-1;36850:335;37224:690;;37417:5;78832:12;79899:6;79894:3;79887:19;79936:4;79931:3;79927:14;37429:93;;79936:4;37593:5;78365:14;-1:-1;37632:260;37657:6;37654:1;37651:13;37632:260;;;37718:13;;38104:37;;79936:4;34325:14;;;;79507;;;;37679:1;37672:9;37632:260;;;-1:-1;37898:10;;37348:566;-1:-1;;;;37348:566;38429:343;;38571:5;78832:12;79899:6;79894:3;79887:19;38664:52;38709:6;79936:4;79931:3;79927:14;79936:4;38690:5;38686:16;38664:52;;;87836:7;87820:14;-1:-1;;87816:28;38728:39;;;;79936:4;38728:39;;38519:253;-1:-1;;38519:253;47336:2780;;47483:6;47588:63;47636:14;47565:16;47559:23;47588:63;;;47738:4;47731:5;47727:16;47721:23;47750:63;47738:4;47802:3;47798:14;47784:12;47750:63;;;;47907:4;47900:5;47896:16;47890:23;47919:63;47907:4;47971:3;47967:14;47953:12;47919:63;;;;48070:4;48063:5;48059:16;48053:23;48082:63;48070:4;48134:3;48130:14;48116:12;48082:63;;;;48236:4;48229:5;48225:16;48219:23;48236:4;48300:3;48296:14;38104:37;48402:4;48395:5;48391:16;48385:23;48402:4;48466:3;48462:14;38104:37;48560:4;48553:5;48549:16;48543:23;48560:4;48624:3;48620:14;38104:37;48718:4;48711:5;48707:16;48701:23;48718:4;48782:3;48778:14;38104:37;48889:6;;48882:5;48878:18;48872:25;48889:6;48955:3;48951:16;38104:37;;49047:6;;49040:5;49036:18;49030:25;49047:6;49113:3;49109:16;38104:37;;49215:6;;49208:5;49204:18;49198:25;47483:6;49215;49247:3;49243:16;49236:40;49291:67;47483:6;47478:3;47474:16;49339:12;49291:67;;;49283:75;;;49453:6;;;;49446:5;49442:18;49436:25;49509:3;49503:4;49499:14;49453:6;49485:3;49481:16;49474:40;49529:67;49591:4;49577:12;49529:67;;;49521:75;;;;49694:6;;49687:5;49683:18;49677:25;49750:3;49744:4;49740:14;49694:6;49726:3;49722:16;49715:40;49770:67;49832:4;49818:12;49770:67;;;49762:75;;;49935:6;;;;49928:5;49924:18;49918:25;49991:3;49985:4;49981:14;49935:6;49967:3;49963:16;49956:40;50011:67;50073:4;50059:12;50011:67;;51165:639;88139:2;88135:14;;;;-1:-1;;88135:14;34965:58;;87928:15;;;;;-1:-1;;;;;;87928:15;51455:2;51446:12;;50599:56;88032:15;;;;-1:-1;;;;;;88032:15;;;51555:12;;;51099:54;88032:15;;;;51662:11;;;51099:54;51768:11;;;51346:458;51811:661;38104:37;;;52111:2;52102:12;;38104:37;;;;52213:12;;;38104:37;52324:12;;;38104:37;52435:12;;;52002:470;52479:262;;38939:5;78832:12;39050:52;39095:6;39090:3;39083:4;39076:5;39072:16;39050:52;;;39114:16;;;;;52604:137;-1:-1;;52604:137;52748:370;53103:10;52927:191;53125:1440;-1:-1;;;45663:36;;-1:-1;;;45647:2;45718:12;;41749:35;-1:-1;;;41803:12;;;43737:38;42867:27;43794:12;;;42847:48;-1:-1;;;42914:12;;;43392:24;43435:11;;;53709:856;54572:213;-1:-1;;;;;82445:54;;;;34589:45;;54690:2;54675:18;;54661:124;54792:451;-1:-1;;;;;82445:54;;;34432:58;;82445:54;;;;55146:2;55131:18;;34589:45;55229:2;55214:18;;38104:37;;;;54974:2;54959:18;;54945:298;55250:959;-1:-1;;;;;82445:54;;34589:45;;55586:3;55721:2;55706:18;;55699:48;;;55250:959;;55761:108;;55571:19;;55855:6;55761:108;;;55917:9;55911:4;55907:20;55902:2;55891:9;55887:18;55880:48;55942:108;56045:4;56036:6;55942:108;;;56098:9;56092:4;56088:20;56083:2;56072:9;56068:18;56061:48;56123:76;56194:4;56185:6;56123:76;;56216:324;-1:-1;;;;;82445:54;;;34589:45;;82445:54;;56526:2;56511:18;;34589:45;56362:2;56347:18;;56333:207;56547:983;-1:-1;;;;;82445:54;;;34589:45;;82445:54;;;57020:2;57005:18;;34589:45;82445:54;;;;57103:2;57088:18;;34589:45;82756:4;82745:16;;;57184:2;57169:18;;50736:48;57267:3;57252:19;;38104:37;;;;82456:42;57336:19;;38104:37;82745:16;;;57431:3;57416:19;;50853:35;57515:3;57500:19;;38104:37;;;;56855:3;56840:19;;56826:704;58471:324;-1:-1;;;;;82445:54;;;;34589:45;;58781:2;58766:18;;38104:37;58617:2;58602:18;;58588:207;58802:531;-1:-1;;;;;82445:54;;;;34589:45;;59161:2;59146:18;;38104:37;;;;82756:4;82745:16;;;59240:2;59225:18;;50853:35;82745:16;59319:2;59304:18;;50853:35;58996:3;58981:19;;58967:366;59340:660;;59606:2;59627:17;59620:47;59681:118;59606:2;59595:9;59591:18;59785:6;59777;59681:118;;;59847:9;59841:4;59837:20;59832:2;59821:9;59817:18;59810:48;59872:118;59985:4;59976:6;59968;59872:118;;;59864:126;59577:423;-1:-1;;;;;;;59577:423;60007:361;;60175:2;60196:17;60189:47;60250:108;60175:2;60164:9;60160:18;60344:6;60250:108;;60375:640;;60631:2;60652:17;60645:47;60706:108;60631:2;60620:9;60616:18;60800:6;60706:108;;;60847:2;60862:9;60856:4;60852:20;60847:2;60836:9;60832:18;60825:48;60887:118;35999:5;78832:12;79899:6;79894:3;79887:19;60847:2;79931:3;79927:14;36011:98;;60847:2;;36166:6;36162:17;79931:3;36153:27;;60847:2;36256:5;78365:14;-1:-1;36295:345;36320:6;36317:1;36314:13;36295:345;;;87836:7;;79931:3;36376:4;36372:20;;36367:3;36360:33;34097:60;34153:3;36427:6;36421:13;34097:60;;;36619:14;;;;36441:82;-1:-1;79507:14;;;;36342:1;36335:9;36295:345;;;-1:-1;60879:126;;60602:413;-1:-1;;;;;;;;;60602:413;61022:201;81415:13;;81408:21;37987:34;;61134:2;61119:18;;61105:118;61230:213;38104:37;;;61348:2;61333:18;;61319:124;61450:209;-1:-1;;;;;;81581:78;;;;38381:36;;61566:2;61551:18;;61537:122;61666:1035;-1:-1;;;;;;81581:78;;38381:36;;-1:-1;;;;;82445:54;;62175:2;62160:18;;34589:45;82456:42;62212:2;62197:18;;62190:48;;;61666:1035;;62252:108;;61997:19;;62346:6;62252:108;;;62408:9;62402:4;62398:20;62393:2;62382:9;62378:18;62371:48;62433:108;62536:4;62527:6;62433:108;;;62590:9;62584:4;62580:20;62574:3;62563:9;62559:19;62552:49;62615:76;62686:4;62677:6;62615:76;;;62607:84;61983:718;-1:-1;;;;;;;;;61983:718;62708:297;;62844:2;62865:17;62858:47;62919:76;62844:2;62833:9;62829:18;62981:6;62919:76;;64905:615;;509:18;;82456:42;;;;81225:5;82445:54;39564:3;39557:72;65145:2;65279;65268:9;65264:18;65257:48;65319:108;65145:2;65134:9;65130:18;65413:6;65319:108;;;65311:116;;82456:42;34627:5;82445:54;65506:2;65495:9;65491:18;34589:45;;65116:404;;;;;;;65527:463;-1:-1;;;;;82445:54;;;39557:72;;82756:4;82745:16;;;;65893:2;65878:18;;50736:48;82445:54;;;65976:2;65961:18;;34589:45;65715:2;65700:18;;65686:304;65997:1151;-1:-1;;;;;82445:54;;;39557:72;;82756:4;82745:16;;66540:2;66525:18;;50736:48;66623:2;66608:18;;38104:37;;;66361:3;66346:19;;;88246:1;88236:12;;88226:2;;88252:9;88226:2;86370:34;66714:2;66703:9;66699:18;41402:58;82456:42;34627:5;82445:54;66797:3;66786:9;66782:19;34589:45;38134:5;66881:3;66870:9;66866:19;38104:37;38134:5;66965:3;66954:9;66950:19;38104:37;38134:5;67049:3;67038:9;67034:19;38104:37;82456:42;34627:5;82445:54;67133:3;67122:9;67118:19;34589:45;;66332:816;;;;;;;;;;;;;67683:1239;;68099:3;68088:9;68084:19;509:18;;82456:42;;;;81225:5;82445:54;39564:3;39557:72;82456:42;81225:5;82445:54;68298:2;68287:9;68283:18;39557:72;;38134:5;68381:2;68370:9;68366:18;38104:37;38134:5;68464:2;68453:9;68449:18;38104:37;82756:4;50881:5;82745:16;68543:3;68532:9;68528:19;50853:35;68099:3;68581;68570:9;68566:19;68559:49;68622:108;35259:5;78832:12;35278:86;35357:6;35352:3;35278:86;;;35271:93;;68298:2;35435:5;78365:14;35447:21;;-1:-1;35474:260;35499:6;35496:1;35493:13;35474:260;;;35587:63;35646:3;35566:6;35560:13;35587:63;;;68298:2;79507:14;;;;;35580:70;-1:-1;35521:1;35514:9;35474:260;;;35478:14;;68779:9;68773:4;68769:20;68763:3;68752:9;68748:19;68741:49;68804:108;68907:4;68898:6;68804:108;;69179:407;69370:2;69384:47;;;42054:2;69355:18;;;79887:19;42090:34;79927:14;;;42070:55;-1:-1;;;42145:12;;;42138:46;42203:12;;;69341:245;69593:339;-1:-1;;;42366:19;;69774:2;69759:18;;69745:187;69939:339;-1:-1;;;42536:20;;70120:2;70105:18;;70091:187;70285:339;-1:-1;;;43077:25;;70466:2;70451:18;;70437:187;70631:339;-1:-1;;;43957:24;;70812:2;70797:18;;70783:187;70977:339;-1:-1;;;44132:31;;71158:2;71143:18;;71129:187;71323:339;-1:-1;;;44888:28;;71504:2;71489:18;;71475:187;71669:407;71860:2;71874:47;;;45155:2;71845:18;;;79887:19;45191:34;79927:14;;;45171:55;45260:34;45246:12;;;45239:56;-1:-1;;;45315:12;;;45308:33;45360:12;;;71831:245;72083:407;72274:2;72288:47;;;45969:2;72259:18;;;79887:19;-1:-1;;;79927:14;;;45985:36;46040:12;;;72245:245;72497:407;72688:2;72702:47;;;46291:2;72673:18;;;79887:19;-1:-1;;;79927:14;;;46307:37;46363:12;;;72659:245;72911:342;46698:23;;-1:-1;;;;;82445:54;34589:45;;46870:4;46859:16;;;46853:23;46930:14;;;38104:37;47027:4;47016:16;;;47010:23;82756:4;82745:16;;;47083:14;;;50853:35;;;;47182:4;47171:16;;;47165:23;82745:16;47238:14;;;50853:35;;;;73093:3;73078:19;;73064:189;73260:353;;73424:2;73445:17;73438:47;73499:104;73424:2;73413:9;73409:18;73589:6;73499:104;;73620:464;;73812:2;73833:17;73826:47;73887:104;73812:2;73801:9;73797:18;73977:6;73887:104;;;73879:112;;38134:5;74070:2;74059:9;74055:18;38104:37;73783:301;;;;;;74091:659;;74329:2;74350:17;74343:47;74404:104;74329:2;74318:9;74314:18;74494:6;74404:104;;;38134:5;74587:2;74576:9;74572:18;38104:37;74639:9;74633:4;74629:20;74624:2;74613:9;74609:18;74602:48;74664:76;74735:4;74726:6;74664:76;;74977:324;38104:37;;;75287:2;75272:18;;38104:37;75123:2;75108:18;;75094:207;75308:755;38104:37;;;75755:2;75740:18;;38104:37;;;;-1:-1;;;;;82445:54;75846:2;75831:18;;34432:58;75590:3;75883:2;75868:18;;75861:48;;;75308:755;75575:19;;;79887;82456:42;79927:14;;75561:502;76070:256;76132:2;76126:9;76158:17;;;-1:-1;;;;;76218:34;;76254:22;;;76215:62;76212:2;;;76290:1;;76280:12;76212:2;76132;76299:22;76110:216;;-1:-1;76110:216;76333:305;;-1:-1;;;;;76485:6;76482:30;76479:2;;;-1:-1;;76515:12;76479:2;-1:-1;76560:4;76548:17;;;76613:15;;76416:222;77598:317;;-1:-1;;;;;77729:6;77726:30;77723:2;;;-1:-1;;77759:12;77723:2;-1:-1;87836:7;77813:17;-1:-1;;77809:33;77900:4;77890:15;;77660:255;86925:268;86990:1;86997:101;87011:6;87008:1;87005:13;86997:101;;;87078:11;;;87072:18;87059:11;;;87052:39;87033:2;87026:10;86997:101;;;87113:6;87110:1;87107:13;87104:2;;;86990:1;87169:6;87164:3;87160:16;87153:27;87104:2;;86974:219;;;;88275:117;-1:-1;;;;;82445:54;;88334:35;;88324:2;;88383:1;;88373:12;88324:2;88318:74;;88399:111;88480:5;81415:13;81408:21;88458:5;88455:32;88445:2;;88501:1;;88491:12;89279:117;-1:-1;;;;;89366:5;82329:42;89341:5;89338:35;89328:2;;89387:1;;89377:12;89649:113;82756:4;89732:5;82745:16;89709:5;89706:33;89696:2;;89753:1;;89743:12

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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