ETH Price: $2,664.44 (+1.07%)

Token

RadiCards (RADI)
 

Overview

Max Total Supply

484 RADI

Holders

276

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
errance.eth
Balance
3 RADI
0xe28d37e094ac43fc264bab5263b3694b985b39df
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:
RadiCards

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 500 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

pragma solidity ^0.4.24;

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting '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;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  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 _a / _b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

// File: openzeppelin-solidity/contracts/ownership/Ownable.sol

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  event OwnershipRenounced(address indexed previousOwner);
  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

// File: openzeppelin-solidity/contracts/access/rbac/Roles.sol

/**
 * @title Roles
 * @author Francisco Giordano (@frangio)
 * @dev Library for managing addresses assigned to a Role.
 * See RBAC.sol for example usage.
 */
library Roles {
  struct Role {
    mapping (address => bool) bearer;
  }

  /**
   * @dev give an address access to this role
   */
  function add(Role storage _role, address _addr)
    internal
  {
    _role.bearer[_addr] = true;
  }

  /**
   * @dev remove an address' access to this role
   */
  function remove(Role storage _role, address _addr)
    internal
  {
    _role.bearer[_addr] = false;
  }

  /**
   * @dev check if an address has this role
   * // reverts
   */
  function check(Role storage _role, address _addr)
    internal
    view
  {
    require(has(_role, _addr));
  }

  /**
   * @dev check if an address has this role
   * @return bool
   */
  function has(Role storage _role, address _addr)
    internal
    view
    returns (bool)
  {
    return _role.bearer[_addr];
  }
}

// File: openzeppelin-solidity/contracts/access/rbac/RBAC.sol

/**
 * @title RBAC (Role-Based Access Control)
 * @author Matt Condon (@Shrugs)
 * @dev Stores and provides setters and getters for roles and addresses.
 * Supports unlimited numbers of roles and addresses.
 * See //contracts/mocks/RBACMock.sol for an example of usage.
 * This RBAC method uses strings to key roles. It may be beneficial
 * for you to write your own implementation of this interface using Enums or similar.
 */
contract RBAC {
  using Roles for Roles.Role;

  mapping (string => Roles.Role) private roles;

  event RoleAdded(address indexed operator, string role);
  event RoleRemoved(address indexed operator, string role);

  /**
   * @dev reverts if addr does not have role
   * @param _operator address
   * @param _role the name of the role
   * // reverts
   */
  function checkRole(address _operator, string _role)
    public
    view
  {
    roles[_role].check(_operator);
  }

  /**
   * @dev determine if addr has role
   * @param _operator address
   * @param _role the name of the role
   * @return bool
   */
  function hasRole(address _operator, string _role)
    public
    view
    returns (bool)
  {
    return roles[_role].has(_operator);
  }

  /**
   * @dev add a role to an address
   * @param _operator address
   * @param _role the name of the role
   */
  function addRole(address _operator, string _role)
    internal
  {
    roles[_role].add(_operator);
    emit RoleAdded(_operator, _role);
  }

  /**
   * @dev remove a role from an address
   * @param _operator address
   * @param _role the name of the role
   */
  function removeRole(address _operator, string _role)
    internal
  {
    roles[_role].remove(_operator);
    emit RoleRemoved(_operator, _role);
  }

  /**
   * @dev modifier to scope access to a single role (uses msg.sender as addr)
   * @param _role the name of the role
   * // reverts
   */
  modifier onlyRole(string _role)
  {
    checkRole(msg.sender, _role);
    _;
  }

  /**
   * @dev modifier to scope access to a set of roles (uses msg.sender as addr)
   * @param _roles the names of the roles to scope access to
   * // reverts
   *
   * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this
   *  see: https://github.com/ethereum/solidity/issues/2467
   */
  // modifier onlyRoles(string[] _roles) {
  //     bool hasAnyRole = false;
  //     for (uint8 i = 0; i < _roles.length; i++) {
  //         if (hasRole(msg.sender, _roles[i])) {
  //             hasAnyRole = true;
  //             break;
  //         }
  //     }

  //     require(hasAnyRole);

  //     _;
  // }
}

// File: openzeppelin-solidity/contracts/access/Whitelist.sol

/**
 * @title Whitelist
 * @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions.
 * This simplifies the implementation of "user permissions".
 */
contract Whitelist is Ownable, RBAC {
  string public constant ROLE_WHITELISTED = "whitelist";

  /**
   * @dev Throws if operator is not whitelisted.
   * @param _operator address
   */
  modifier onlyIfWhitelisted(address _operator) {
    checkRole(_operator, ROLE_WHITELISTED);
    _;
  }

  /**
   * @dev add an address to the whitelist
   * @param _operator address
   * @return true if the address was added to the whitelist, false if the address was already in the whitelist
   */
  function addAddressToWhitelist(address _operator)
    public
    onlyOwner
  {
    addRole(_operator, ROLE_WHITELISTED);
  }

  /**
   * @dev getter to determine if address is in whitelist
   */
  function whitelist(address _operator)
    public
    view
    returns (bool)
  {
    return hasRole(_operator, ROLE_WHITELISTED);
  }

  /**
   * @dev add addresses to the whitelist
   * @param _operators addresses
   * @return true if at least one address was added to the whitelist,
   * false if all addresses were already in the whitelist
   */
  function addAddressesToWhitelist(address[] _operators)
    public
    onlyOwner
  {
    for (uint256 i = 0; i < _operators.length; i++) {
      addAddressToWhitelist(_operators[i]);
    }
  }

  /**
   * @dev remove an address from the whitelist
   * @param _operator address
   * @return true if the address was removed from the whitelist,
   * false if the address wasn't in the whitelist in the first place
   */
  function removeAddressFromWhitelist(address _operator)
    public
    onlyOwner
  {
    removeRole(_operator, ROLE_WHITELISTED);
  }

  /**
   * @dev remove addresses from the whitelist
   * @param _operators addresses
   * @return true if at least one address was removed from the whitelist,
   * false if all addresses weren't in the whitelist in the first place
   */
  function removeAddressesFromWhitelist(address[] _operators)
    public
    onlyOwner
  {
    for (uint256 i = 0; i < _operators.length; i++) {
      removeAddressFromWhitelist(_operators[i]);
    }
  }

}

// File: openzeppelin-solidity/contracts/introspection/ERC165.sol

/**
 * @title ERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface ERC165 {

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool);
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Basic.sol

/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Basic is ERC165 {

  bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd;
  /*
   * 0x80ac58cd ===
   *   bytes4(keccak256('balanceOf(address)')) ^
   *   bytes4(keccak256('ownerOf(uint256)')) ^
   *   bytes4(keccak256('approve(address,uint256)')) ^
   *   bytes4(keccak256('getApproved(uint256)')) ^
   *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
   *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
   *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
   */

  bytes4 internal constant InterfaceId_ERC721Exists = 0x4f558e79;
  /*
   * 0x4f558e79 ===
   *   bytes4(keccak256('exists(uint256)'))
   */

  bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63;
  /**
   * 0x780e9d63 ===
   *   bytes4(keccak256('totalSupply()')) ^
   *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
   *   bytes4(keccak256('tokenByIndex(uint256)'))
   */

  bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */

  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 indexed _tokenId
  );
  event Approval(
    address indexed _owner,
    address indexed _approved,
    uint256 indexed _tokenId
  );
  event ApprovalForAll(
    address indexed _owner,
    address indexed _operator,
    bool _approved
  );

  function balanceOf(address _owner) public view returns (uint256 _balance);
  function ownerOf(uint256 _tokenId) public view returns (address _owner);
  function exists(uint256 _tokenId) public view returns (bool _exists);

  function approve(address _to, uint256 _tokenId) public;
  function getApproved(uint256 _tokenId)
    public view returns (address _operator);

  function setApprovalForAll(address _operator, bool _approved) public;
  function isApprovedForAll(address _owner, address _operator)
    public view returns (bool);

  function transferFrom(address _from, address _to, uint256 _tokenId) public;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId)
    public;

  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public;
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Enumerable is ERC721Basic {
  function totalSupply() public view returns (uint256);
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256 _tokenId);

  function tokenByIndex(uint256 _index) public view returns (uint256);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Metadata is ERC721Basic {
  function name() external view returns (string _name);
  function symbol() external view returns (string _symbol);
  function tokenURI(uint256 _tokenId) public view returns (string);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, full implementation interface
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Receiver.sol

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract ERC721Receiver {
  /**
   * @dev Magic value to be returned upon successful reception of an NFT
   *  Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
   *  which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
   */
  bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;

  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   * after a `safetransfer`. This function MAY throw to revert and reject the
   * transfer. Return of other than the magic value MUST result in the
   * transaction being reverted.
   * Note: the contract address is always the message sender.
   * @param _operator The address which called `safeTransferFrom` function
   * @param _from The address which previously owned the token
   * @param _tokenId The NFT identifier which is being transferred
   * @param _data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
   */
  function onERC721Received(
    address _operator,
    address _from,
    uint256 _tokenId,
    bytes _data
  )
    public
    returns(bytes4);
}

// File: openzeppelin-solidity/contracts/AddressUtils.sol

/**
 * Utility library of inline functions on addresses
 */
library AddressUtils {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   * as the code is not actually created until after the constructor finishes.
   * @param _addr address to check
   * @return whether the target address is a contract
   */
  function isContract(address _addr) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(_addr) }
    return size > 0;
  }

}

// File: openzeppelin-solidity/contracts/introspection/SupportsInterfaceWithLookup.sol

/**
 * @title SupportsInterfaceWithLookup
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract SupportsInterfaceWithLookup is ERC165 {

  bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
  /**
   * 0x01ffc9a7 ===
   *   bytes4(keccak256('supportsInterface(bytes4)'))
   */

  /**
   * @dev a mapping of interface id to whether or not it's supported
   */
  mapping(bytes4 => bool) internal supportedInterfaces;

  /**
   * @dev A contract implementing SupportsInterfaceWithLookup
   * implement ERC165 itself
   */
  constructor()
    public
  {
    _registerInterface(InterfaceId_ERC165);
  }

  /**
   * @dev implement supportsInterface(bytes4) using a lookup table
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool)
  {
    return supportedInterfaces[_interfaceId];
  }

  /**
   * @dev private method for registering an interface
   */
  function _registerInterface(bytes4 _interfaceId)
    internal
  {
    require(_interfaceId != 0xffffffff);
    supportedInterfaces[_interfaceId] = true;
  }
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721BasicToken.sol

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721BasicToken is SupportsInterfaceWithLookup, ERC721Basic {

  using SafeMath for uint256;
  using AddressUtils for address;

  // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
  // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
  bytes4 private constant ERC721_RECEIVED = 0x150b7a02;

  // Mapping from token ID to owner
  mapping (uint256 => address) internal tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) internal tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) internal ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) internal operatorApprovals;

  constructor()
    public
  {
    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721);
    _registerInterface(InterfaceId_ERC721Exists);
  }

  /**
   * @dev Gets the balance of the specified address
   * @param _owner address to query the balance of
   * @return uint256 representing the amount owned by the passed address
   */
  function balanceOf(address _owner) public view returns (uint256) {
    require(_owner != address(0));
    return ownedTokensCount[_owner];
  }

  /**
   * @dev Gets the owner of the specified token ID
   * @param _tokenId uint256 ID of the token to query the owner of
   * @return owner address currently marked as the owner of the given token ID
   */
  function ownerOf(uint256 _tokenId) public view returns (address) {
    address owner = tokenOwner[_tokenId];
    require(owner != address(0));
    return owner;
  }

  /**
   * @dev Returns whether the specified token exists
   * @param _tokenId uint256 ID of the token to query the existence of
   * @return whether the token exists
   */
  function exists(uint256 _tokenId) public view returns (bool) {
    address owner = tokenOwner[_tokenId];
    return owner != address(0);
  }

  /**
   * @dev Approves another address to transfer the given token ID
   * The zero address indicates there is no approved address.
   * There can only be one approved address per token at a given time.
   * Can only be called by the token owner or an approved operator.
   * @param _to address to be approved for the given token ID
   * @param _tokenId uint256 ID of the token to be approved
   */
  function approve(address _to, uint256 _tokenId) public {
    address owner = ownerOf(_tokenId);
    require(_to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    tokenApprovals[_tokenId] = _to;
    emit Approval(owner, _to, _tokenId);
  }

  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * @param _tokenId uint256 ID of the token to query the approval of
   * @return address currently approved for the given token ID
   */
  function getApproved(uint256 _tokenId) public view returns (address) {
    return tokenApprovals[_tokenId];
  }

  /**
   * @dev Sets or unsets the approval of a given operator
   * An operator is allowed to transfer all tokens of the sender on their behalf
   * @param _to operator address to set the approval
   * @param _approved representing the status of the approval to be set
   */
  function setApprovalForAll(address _to, bool _approved) public {
    require(_to != msg.sender);
    operatorApprovals[msg.sender][_to] = _approved;
    emit ApprovalForAll(msg.sender, _to, _approved);
  }

  /**
   * @dev Tells whether an operator is approved by a given owner
   * @param _owner owner address which you want to query the approval of
   * @param _operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    public
    view
    returns (bool)
  {
    return operatorApprovals[_owner][_operator];
  }

  /**
   * @dev Transfers the ownership of a given token ID to another address
   * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    public
  {
    require(isApprovedOrOwner(msg.sender, _tokenId));
    require(_from != address(0));
    require(_to != address(0));

    clearApproval(_from, _tokenId);
    removeTokenFrom(_from, _tokenId);
    addTokenTo(_to, _tokenId);

    emit Transfer(_from, _to, _tokenId);
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   *
   * Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    public
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(_from, _to, _tokenId, "");
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   * Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public
  {
    transferFrom(_from, _to, _tokenId);
    // solium-disable-next-line arg-overflow
    require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
  }

  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param _spender address of the spender to query
   * @param _tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
  function isApprovedOrOwner(
    address _spender,
    uint256 _tokenId
  )
    internal
    view
    returns (bool)
  {
    address owner = ownerOf(_tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      _spender == owner ||
      getApproved(_tokenId) == _spender ||
      isApprovedForAll(owner, _spender)
    );
  }

  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param _to The address that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    require(_to != address(0));
    addTokenTo(_to, _tokenId);
    emit Transfer(address(0), _to, _tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    clearApproval(_owner, _tokenId);
    removeTokenFrom(_owner, _tokenId);
    emit Transfer(_owner, address(0), _tokenId);
  }

  /**
   * @dev Internal function to clear current approval of a given token ID
   * Reverts if the given address is not indeed the owner of the token
   * @param _owner owner of the token
   * @param _tokenId uint256 ID of the token to be transferred
   */
  function clearApproval(address _owner, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _owner);
    if (tokenApprovals[_tokenId] != address(0)) {
      tokenApprovals[_tokenId] = address(0);
    }
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    require(tokenOwner[_tokenId] == address(0));
    tokenOwner[_tokenId] = _to;
    ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _from);
    ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
    tokenOwner[_tokenId] = address(0);
  }

  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * The call is not executed if the target address is not a contract
   * @param _from address representing the previous owner of the given token ID
   * @param _to target address that will receive the tokens
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes optional data to send along with the call
   * @return whether the call correctly returned the expected magic value
   */
  function checkAndCallSafeTransfer(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!_to.isContract()) {
      return true;
    }
    bytes4 retval = ERC721Receiver(_to).onERC721Received(
      msg.sender, _from, _tokenId, _data);
    return (retval == ERC721_RECEIVED);
  }
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Token.sol

/**
 * @title Full ERC721 Token
 * This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 {

  // Token name
  string internal name_;

  // Token symbol
  string internal symbol_;

  // Mapping from owner to list of owned token IDs
  mapping(address => uint256[]) internal ownedTokens;

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

  // Array with all token ids, used for enumeration
  uint256[] internal allTokens;

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

  // Optional mapping for token URIs
  mapping(uint256 => string) internal tokenURIs;

  /**
   * @dev Constructor function
   */
  constructor(string _name, string _symbol) public {
    name_ = _name;
    symbol_ = _symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Enumerable);
    _registerInterface(InterfaceId_ERC721Metadata);
  }

  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() external view returns (string) {
    return name_;
  }

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string) {
    return symbol_;
  }

  /**
   * @dev Returns an URI for a given token ID
   * Throws if the token ID does not exist. May return an empty string.
   * @param _tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 _tokenId) public view returns (string) {
    require(exists(_tokenId));
    return tokenURIs[_tokenId];
  }

  /**
   * @dev Gets the token ID at a given index of the tokens list of the requested owner
   * @param _owner address owning the tokens list to be accessed
   * @param _index uint256 representing the index to be accessed of the requested tokens list
   * @return uint256 token ID at the given index of the tokens list owned by the requested address
   */
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256)
  {
    require(_index < balanceOf(_owner));
    return ownedTokens[_owner][_index];
  }

  /**
   * @dev Gets the total amount of tokens stored by the contract
   * @return uint256 representing the total amount of tokens
   */
  function totalSupply() public view returns (uint256) {
    return allTokens.length;
  }

  /**
   * @dev Gets the token ID at a given index of all the tokens in this contract
   * Reverts if the index is greater or equal to the total number of tokens
   * @param _index uint256 representing the index to be accessed of the tokens list
   * @return uint256 token ID at the given index of the tokens list
   */
  function tokenByIndex(uint256 _index) public view returns (uint256) {
    require(_index < totalSupply());
    return allTokens[_index];
  }

  /**
   * @dev Internal function to set the token URI for a given token
   * Reverts if the token ID does not exist
   * @param _tokenId uint256 ID of the token to set its URI
   * @param _uri string URI to assign
   */
  function _setTokenURI(uint256 _tokenId, string _uri) internal {
    require(exists(_tokenId));
    tokenURIs[_tokenId] = _uri;
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    super.addTokenTo(_to, _tokenId);
    uint256 length = ownedTokens[_to].length;
    ownedTokens[_to].push(_tokenId);
    ownedTokensIndex[_tokenId] = length;
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    super.removeTokenFrom(_from, _tokenId);

    // To prevent a gap in the array, we store the last token in the index of the token to delete, and
    // then delete the last slot.
    uint256 tokenIndex = ownedTokensIndex[_tokenId];
    uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
    uint256 lastToken = ownedTokens[_from][lastTokenIndex];

    ownedTokens[_from][tokenIndex] = lastToken;
    // This also deletes the contents at the last position of the array
    ownedTokens[_from].length--;

    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    ownedTokensIndex[_tokenId] = 0;
    ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param _to address the beneficiary that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    super._mint(_to, _tokenId);

    allTokensIndex[_tokenId] = allTokens.length;
    allTokens.push(_tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param _owner owner of the token to burn
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    super._burn(_owner, _tokenId);

    // Clear metadata (if any)
    if (bytes(tokenURIs[_tokenId]).length != 0) {
      delete tokenURIs[_tokenId];
    }

    // Reorg all tokens array
    uint256 tokenIndex = allTokensIndex[_tokenId];
    uint256 lastTokenIndex = allTokens.length.sub(1);
    uint256 lastToken = allTokens[lastTokenIndex];

    allTokens[tokenIndex] = lastToken;
    allTokens[lastTokenIndex] = 0;

    allTokens.length--;
    allTokensIndex[_tokenId] = 0;
    allTokensIndex[lastToken] = tokenIndex;
  }

}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Holder.sol

contract ERC721Holder is ERC721Receiver {
  function onERC721Received(
    address,
    address,
    uint256,
    bytes
  )
    public
    returns(bytes4)
  {
    return ERC721_RECEIVED;
  }
}

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * See https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address _who) public view returns (uint256);
  function transfer(address _to, uint256 _value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

// File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) internal balances;

  uint256 internal totalSupply_;

  /**
  * @dev Total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  /**
  * @dev Transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value <= balances[msg.sender]);
    require(_to != address(0));

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
  }

}

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address _owner, address _spender)
    public view returns (uint256);

  function transferFrom(address _from, address _to, uint256 _value)
    public returns (bool);

  function approve(address _spender, uint256 _value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

// File: openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/issues/20
 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) internal allowed;


  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    require(_to != address(0));

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(
    address _owner,
    address _spender
   )
    public
    view
    returns (uint256)
  {
    return allowed[_owner][_spender];
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(
    address _spender,
    uint256 _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(
    address _spender,
    uint256 _subtractedValue
  )
    public
    returns (bool)
  {
    uint256 oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue >= oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

// File: contracts/Strings.sol

library Strings {
  // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
  function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) {
    bytes memory _ba = bytes(_a);
    bytes memory _bb = bytes(_b);
    bytes memory _bc = bytes(_c);
    bytes memory _bd = bytes(_d);
    bytes memory _be = bytes(_e);
    string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
    bytes memory babcde = bytes(abcde);
    uint k = 0;
    for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
    for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
    for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
    for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
    for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
    return string(babcde);
  }

  function strConcat(string _a, string _b) internal pure returns (string) {
    return strConcat(_a, _b, "", "", "");
  }
}

// File: contracts/Medianizer.sol

// This is the original medianizer implementation used by MakerDAO. we use this
// contract to fetch the latest ether price by calling the read() function.
// public deployed instances of  this contract can be found here:
//1) kovan: https://kovan.etherscan.io/address/0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc#code
//2) mainnet: https://etherscan.io/address/0x729D19f657BD0614b4985Cf1D82531c67569197B#readContract

/// return median value of feeds

// Copyright (C) 2017  DappHub, LLC

// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied).

pragma solidity ^0.4.8;

contract DSAuthority {
    function canCall(
        address src, address dst, bytes4 sig
    ) constant returns (bool);
}

contract DSAuthEvents {
    event LogSetAuthority (address indexed authority);
    event LogSetOwner     (address indexed owner);
}

contract DSAuth is DSAuthEvents {
    DSAuthority  public  authority;
    address      public  owner;

    function DSAuth() {
        owner = msg.sender;
        LogSetOwner(msg.sender);
    }

    function setOwner(address owner_)
        auth
    {
        owner = owner_;
        LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_)
        auth
    {
        authority = authority_;
        LogSetAuthority(authority);
    }

    modifier auth {
        assert(isAuthorized(msg.sender, msg.sig));
        _;
    }

    modifier authorized(bytes4 sig) {
        assert(isAuthorized(msg.sender, sig));
        _;
    }

    function isAuthorized(address src, bytes4 sig) internal returns (bool) {
        if (src == address(this)) {
            return true;
        } else if (src == owner) {
            return true;
        } else if (authority == DSAuthority(0)) {
            return false;
        } else {
            return authority.canCall(src, this, sig);
        }
    }

    function assert(bool x) internal {
        if (!x) throw;
    }
}

contract DSNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  guy,
        bytes32  indexed  foo,
        bytes32  indexed  bar,
	uint	 	  wad,
        bytes             fax
    ) anonymous;

    modifier note {
        bytes32 foo;
        bytes32 bar;

        assembly {
            foo := calldataload(4)
            bar := calldataload(36)
        }

        LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);

        _;
    }
}

contract DSMath {

    /*
    standard uint256 functions
     */

    function add(uint256 x, uint256 y) constant internal returns (uint256 z) {
        assert((z = x + y) >= x);
    }

    function sub(uint256 x, uint256 y) constant internal returns (uint256 z) {
        assert((z = x - y) <= x);
    }

    function mul(uint256 x, uint256 y) constant internal returns (uint256 z) {
        assert((z = x * y) >= x);
    }

    function div(uint256 x, uint256 y) constant internal returns (uint256 z) {
        z = x / y;
    }

    function min(uint256 x, uint256 y) constant internal returns (uint256 z) {
        return x <= y ? x : y;
    }
    function max(uint256 x, uint256 y) constant internal returns (uint256 z) {
        return x >= y ? x : y;
    }

    /*
    uint128 functions (h is for half)
     */


    function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) {
        assert((z = x + y) >= x);
    }

    function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) {
        assert((z = x - y) <= x);
    }

    function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
        assert((z = x * y) >= x);
    }

    function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
        z = x / y;
    }

    function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) {
        return x <= y ? x : y;
    }
    function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) {
        return x >= y ? x : y;
    }


    /*
    int256 functions
     */

    function imin(int256 x, int256 y) constant internal returns (int256 z) {
        return x <= y ? x : y;
    }
    function imax(int256 x, int256 y) constant internal returns (int256 z) {
        return x >= y ? x : y;
    }

    /*
    WAD math
     */

    uint128 constant WAD = 10 ** 18;

    function wadd(uint128 x, uint128 y) constant internal returns (uint128) {
        return hadd(x, y);
    }

    function wsub(uint128 x, uint128 y) constant internal returns (uint128) {
        return hsub(x, y);
    }

    function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
        z = cast((uint256(x) * y + WAD / 2) / WAD);
    }

    function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
        z = cast((uint256(x) * WAD + y / 2) / y);
    }

    function wmin(uint128 x, uint128 y) constant internal returns (uint128) {
        return hmin(x, y);
    }
    function wmax(uint128 x, uint128 y) constant internal returns (uint128) {
        return hmax(x, y);
    }

    /*
    RAY math
     */

    uint128 constant RAY = 10 ** 27;

    function radd(uint128 x, uint128 y) constant internal returns (uint128) {
        return hadd(x, y);
    }

    function rsub(uint128 x, uint128 y) constant internal returns (uint128) {
        return hsub(x, y);
    }

    function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
        z = cast((uint256(x) * y + RAY / 2) / RAY);
    }

    function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
        z = cast((uint256(x) * RAY + y / 2) / y);
    }

    function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) {
        // This famous algorithm is called "exponentiation by squaring"
        // and calculates x^n with x as fixed-point and n as regular unsigned.
        //
        // It's O(log n), instead of O(n) for naive repeated multiplication.
        //
        // These facts are why it works:
        //
        //  If n is even, then x^n = (x^2)^(n/2).
        //  If n is odd,  then x^n = x * x^(n-1),
        //   and applying the equation for even x gives
        //    x^n = x * (x^2)^((n-1) / 2).
        //
        //  Also, EVM division is flooring and
        //    floor[(n-1) / 2] = floor[n / 2].

        z = n % 2 != 0 ? x : RAY;

        for (n /= 2; n != 0; n /= 2) {
            x = rmul(x, x);

            if (n % 2 != 0) {
                z = rmul(z, x);
            }
        }
    }

    function rmin(uint128 x, uint128 y) constant internal returns (uint128) {
        return hmin(x, y);
    }
    function rmax(uint128 x, uint128 y) constant internal returns (uint128) {
        return hmax(x, y);
    }

    function cast(uint256 x) constant internal returns (uint128 z) {
        assert((z = uint128(x)) == x);
    }

}

contract DSThing is DSAuth, DSNote, DSMath {
}

contract DSValue is DSThing {
    bool    has;
    bytes32 val;
    function peek() constant returns (bytes32, bool) {
        return (val,has);
    }
    function read() constant returns (bytes32) {
        var (wut, has) = peek();
        assert(has);
        return wut;
    }
    function poke(bytes32 wut) note auth {
        val = wut;
        has = true;
    }
    function void() note auth { // unset the value
        has = false;
    }
}

contract Medianizer is DSValue {
    mapping (bytes12 => address) public values;
    mapping (address => bytes12) public indexes;
    bytes12 public next = 0x1;

    uint96 public min = 0x1;

    function set(address wat) auth {
        bytes12 nextId = bytes12(uint96(next) + 1);
        assert(nextId != 0x0);
        set(next, wat);
        next = nextId;
    }

    function set(bytes12 pos, address wat) note auth {
        if (pos == 0x0) throw;

        if (wat != 0 && indexes[wat] != 0) throw;

        indexes[values[pos]] = 0; // Making sure to remove a possible existing address in that position

        if (wat != 0) {
            indexes[wat] = pos;
        }

        values[pos] = wat;
    }

    function setMin(uint96 min_) note auth {
        if (min_ == 0x0) throw;
        min = min_;
    }

    function setNext(bytes12 next_) note auth {
        if (next_ == 0x0) throw;
        next = next_;
    }

    function unset(bytes12 pos) {
        set(pos, 0);
    }

    function unset(address wat) {
        set(indexes[wat], 0);
    }

    function poke() {
        poke(0);
    }

    function poke(bytes32) note {
        (val, has) = compute();
    }

    function compute() constant returns (bytes32, bool) {
        bytes32[] memory wuts = new bytes32[](uint96(next) - 1);
        uint96 ctr = 0;
        for (uint96 i = 1; i < uint96(next); i++) {
            if (values[bytes12(i)] != 0) {
                var (wut, wuz) = DSValue(values[bytes12(i)]).peek();
                if (wuz) {
                    if (ctr == 0 || wut >= wuts[ctr - 1]) {
                        wuts[ctr] = wut;
                    } else {
                        uint96 j = 0;
                        while (wut >= wuts[j]) {
                            j++;
                        }
                        for (uint96 k = ctr; k > j; k--) {
                            wuts[k] = wuts[k - 1];
                        }
                        wuts[j] = wut;
                    }
                    ctr++;
                }
            }
        }

        if (ctr < min) return (val, false);

        bytes32 value;
        if (ctr % 2 == 0) {
            uint128 val1 = uint128(wuts[(ctr / 2) - 1]);
            uint128 val2 = uint128(wuts[ctr / 2]);
            value = bytes32(wdiv(hadd(val1, val2), 2 ether));
        } else {
            value = wuts[(ctr - 1) / 2];
        }

        return (value, true);
    }

}

// File: contracts/RadiCards.sol

/**
* @title Radi.Cards
* This is the main Radi Cards NFT (ERC721) contract. It allows for the minting of
* cards(NFTs) that can be sent to either a known EOA or to a claimable link.
* ETH or DAI can be sent along with the card and the sender can choose a ratio
* between a participating benefactor and the recipient, with no restriction.
* Predefined cards can be added, with the artwork stored on IPFS.
* The card message is stored within the smart contract. Cards can have a defined max
* quantity that can be minted and a minimum purchase price. The claimable link sender
* generates a public/private key pair that is used to take the NFT out of escrow (held within
* this contract). The private key can then be sent to the recipient by email,
* telergram, wechat ect. and is embedded within a URL to a claim page. When the user
* opens the claim URL the private key is used to redeem the NFT and any associated gift (ETH/DAI).

* @author blockrocket.tech (smart contracts)
* @author cryptodecks.co
* @author knownorigin.io
* @author pheme.app
* @author d1labs.com
* @author mbdoesthings.com
* @author chrismaree.io (smart contracts v2 update)
*/
contract RadiCards is ERC721Token, ERC721Holder, Whitelist {
    using SafeMath for uint256;

    // dai support
    StandardToken daiContract;
    Medianizer medianizerContract;

    string public tokenBaseURI = "https://ipfs.infura.io/ipfs/";
    uint256 public tokenIdPointer = 0;

    struct Benefactor {
        address ethAddress;
        string name;
        string website;
        string logo;
    }

    struct CardDesign {
        string tokenURI;
        bool active;
        uint minted;
        uint maxQnty; //set to zero for unlimited
        //minimum price per card set in Atto (SI prefix for 1x10-18 dai)
        uint256 minPrice; //set to zero to default to the minimumContribution
    }

    // claimable link support
    enum Statuses { Empty, Deposited, Claimed, Cancelled }
    uint256 public EPHEMERAL_ADDRESS_FEE = 0.01 ether;
    mapping(address => uint256) public ephemeralWalletCards; // ephemeral wallet => tokenId

    struct RadiCard {
        address gifter;
        string message;
        bool daiDonation;
        uint256 giftAmount;
        uint256 donationAmount;
        Statuses status;
        uint256 cardIndex;
        uint256 benefactorIndex;
    }

    mapping(uint256 => Benefactor) public benefactors;
    uint256[] internal benefactorsIndex;

    mapping(uint256 => CardDesign) public cards;
    uint256[] internal cardsIndex;

    mapping(uint256 => RadiCard) public tokenIdToRadiCardIndex;

    //total gifted/donated in ETH
    uint256 public totalGiftedInWei;
    uint256 public totalDonatedInWei;

    //total gifted/donated in DAI
    uint256 public totalGiftedInAtto; //SI prefix for 1x10-18 dai is Atto.
    uint256 public totalDonatedInAtto;

    event CardGifted(
        address indexed _to,
        uint256 indexed _benefactorIndex,
        uint256 indexed _cardIndex,
        address _from,
        uint256 _tokenId,
        bool daiDonation,
        uint256 giftAmount,
        uint256 donationAmount,
        Statuses status
    );

    event LogClaimGift(
            address indexed ephemeralAddress,
            address indexed sender,
            uint tokenId,
            address receiver,
            uint giftAmount,
        bool daiDonation
    );

    event LogCancelGift(
        address indexed ephemeralAddress,
        address indexed sender,
        uint tokenId
    );


    event BenefactorAdded(
        uint256 indexed _benefactorIndex
    );

    event CardAdded(
        uint256 indexed _cardIndex
    );

    constructor () public ERC721Token("RadiCards", "RADI") {
        addAddressToWhitelist(msg.sender);
    }

    function gift(address _to, uint256 _benefactorIndex, uint256 _cardIndex, string _message, uint256 _donationAmount, uint256 _giftAmount, bool _claimableLink) payable public returns (bool) {
        require(_to != address(0), "Must be a valid address");
        if(_donationAmount > 0){
            require(benefactors[_benefactorIndex].ethAddress != address(0), "Must specify existing benefactor");
        }

        require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card");
        require(cards[_cardIndex].active, "Must be an active card");

        Statuses _giftStatus;
        address _sentToAddress;

        if(_claimableLink){
            require(_donationAmount + _giftAmount + EPHEMERAL_ADDRESS_FEE == msg.value, "Can only request to donate and gift the amount of ether sent + Ephemeral fee");
            _giftStatus = Statuses.Deposited;
            _sentToAddress = this;
            ephemeralWalletCards[_to] = tokenIdPointer;
            _to.transfer(EPHEMERAL_ADDRESS_FEE);
        }

        else {
            require(_donationAmount + _giftAmount == msg.value,"Can only request to donate and gift the amount of ether sent");
            _giftStatus = Statuses.Claimed;
            _sentToAddress = _to;
        }

        if (cards[_cardIndex].maxQnty > 0){ //the max quantity is set to zero to indicate no limit. Only need to check that can mint if limited
            require(cards[_cardIndex].minted < cards[_cardIndex].maxQnty, "Can't exceed maximum quantity of card type");
        }

        if(cards[_cardIndex].minPrice > 0){ //if the card has a minimum price check that enough has been sent
        // Convert the current value of the eth send to a USD value of atto (1 usd = 10^18 atto).
        // require(getEthUsdValue(msg.value) >= (cards[_cardIndex].minPrice), "Must send at least the minimum amount");
            require (getMinCardPriceInWei(_cardIndex) <= msg.value,"Must send at least the minimum amount to buy card");
        }

        tokenIdToRadiCardIndex[tokenIdPointer] = RadiCard({
            gifter: msg.sender,
            message: _message,
            daiDonation: false,
            giftAmount: _giftAmount,
            donationAmount: _donationAmount,
            status: _giftStatus,
            cardIndex: _cardIndex,
            benefactorIndex: _benefactorIndex
        });

        // Card is minted to the _sentToAddress. This is either this radicards contract(if claimableLink==true)
        // and the creator chose to use the escrow for a claimable link or to the recipient EOA directly
        uint256 _tokenId = _mint(_sentToAddress, cards[_cardIndex].tokenURI);
        cards[_cardIndex].minted++;

        // transfer the ETH to the benefactor
        if(_donationAmount > 0){
            benefactors[_benefactorIndex].ethAddress.transfer(_donationAmount);
            totalDonatedInWei = totalDonatedInWei.add(_donationAmount);
        }
        // transfer gift to recipient.

        if(_giftAmount > 0){
            totalGiftedInWei = totalGiftedInWei.add(_giftAmount);
        // note that we only do the transfer if the link is not claimable as if it is the eth sits in escrow within this contract
            if(!_claimableLink){
                _sentToAddress.transfer(_giftAmount);
            }
        }
        emit CardGifted(_sentToAddress, _benefactorIndex, _cardIndex, msg.sender, _tokenId, false, _giftAmount, _donationAmount, _giftStatus);
        return true;
    }

    function giftInDai(address _to, uint256 _benefactorIndex, uint256 _cardIndex, string _message, uint256 _donationAmount, uint256 _giftAmount, bool _claimableLink) public payable returns (bool) {
        require(_to != address(0), "Must be a valid address");
        if (_donationAmount > 0){
            require(benefactors[_benefactorIndex].ethAddress != address(0), "Must specify existing benefactor");
        }

        require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card");
        require(cards[_cardIndex].active, "Must be an active card");

        require((_donationAmount + _giftAmount) <= daiContract.allowance(msg.sender, this), "Must have provided high enough alowance to Radicard contract");
        require((_donationAmount + _giftAmount) <= daiContract.balanceOf(msg.sender), "Must have enough token balance of dai to pay for donation and gift amount");

        if (cards[_cardIndex].maxQnty > 0){ //the max quantity is set to zero to indicate no limit. Only need to check that can mint if limited
            require(cards[_cardIndex].minted < cards[_cardIndex].maxQnty, "Can't exceed maximum quantity of card type");
        }

        if(cards[_cardIndex].minPrice > 0){ //if the card has a minimum price check that enough has been sent
            require((_donationAmount + _giftAmount) >= cards[_cardIndex].minPrice, "The total dai sent with the transaction is less than the min price of the token");
        }

        //parameters that change based on the if the card is setup as with a claimable link
        Statuses _giftStatus;
        address _sentToAddress;

        if(_claimableLink){
            require(msg.value == EPHEMERAL_ADDRESS_FEE, "A claimable link was generated but not enough ephemeral ether was sent!");
            _giftStatus = Statuses.Deposited;
            _sentToAddress = this;
            // need to store the address of the ephemeral account and the card that it owns for claimable link functionality
            ephemeralWalletCards[_to] = tokenIdPointer;
            _to.transfer(EPHEMERAL_ADDRESS_FEE);
        }

        else {
            _giftStatus = Statuses.Claimed;
            _sentToAddress = _to;
        }

        tokenIdToRadiCardIndex[tokenIdPointer] = RadiCard({
            gifter: msg.sender,
            message: _message,
            daiDonation: true,
            giftAmount: _giftAmount,
            donationAmount: _donationAmount,
            status: _giftStatus,
            cardIndex: _cardIndex,
            benefactorIndex: _benefactorIndex
        });

        // Card is minted to the _sentToAddress. This is either this radicards contract(if claimableLink==true)
        // and the creator chose to use the escrow for a claimable link or to the recipient EOA directly
        uint256 _tokenId = _mint(_sentToAddress, cards[_cardIndex].tokenURI);

        cards[_cardIndex].minted++;

        // transfer the DAI to the benefactor
        if(_donationAmount > 0){
            address _benefactorAddress = benefactors[_benefactorIndex].ethAddress;
            require(daiContract.transferFrom(msg.sender, _benefactorAddress, _donationAmount),"Sending to benefactor failed");
            totalDonatedInAtto = totalDonatedInAtto.add(_donationAmount);
        }

        // transfer gift to recipient. note that this pattern is slightly different from the eth case as irrespective of
        // if it is a claimable link or not we preform the transaction. if it is indeed a claimable link the dai is sent
        // to the contract and held in escrow
        if(_giftAmount > 0){
            require(daiContract.transferFrom(msg.sender, _sentToAddress, _giftAmount),"Sending to recipient failed");
            totalGiftedInAtto = totalGiftedInAtto.add(_giftAmount);
        }

        emit CardGifted(_sentToAddress, _benefactorIndex, _cardIndex, msg.sender, _tokenId, true, _giftAmount, _donationAmount, _giftStatus);
        return true;
    }

    function _mint(address to, string tokenURI) internal returns (uint256 _tokenId) {
        uint256 tokenId = tokenIdPointer;

        super._mint(to, tokenId);
        _setTokenURI(tokenId, tokenURI);

        tokenIdPointer = tokenIdPointer.add(1);

        return tokenId;
    }

    function cancelGift(address _ephemeralAddress) public returns (bool) {
        uint256 tokenId = ephemeralWalletCards[_ephemeralAddress];
        require(tokenId != 0, "Can only call this function on an address that was used as an ephemeral");
        RadiCard storage card = tokenIdToRadiCardIndex[tokenId];

        // is deposited and wasn't claimed or cancelled before
        require(card.status == Statuses.Deposited, "can only cancel gifts that are unclaimed (deposited)");

        // only gifter can cancel transfer;
        require(msg.sender == card.gifter, "only the gifter of the card can cancel a gift");

        // update status to cancelled
        card.status = Statuses.Cancelled;

        // transfer optional ether or dai back to creators address
        if (card.giftAmount > 0) {
            if(card.daiDonation){
                require(daiContract.transfer(msg.sender, card.giftAmount),"Sending to recipient after cancel gift failed");
            }
            else{
                msg.sender.transfer(card.giftAmount);
            }
        }

        // send nft to buyer. for this we use a custom transfer function to take the nft out of escrow and
        // send it back to the buyer.
        transferFromEscrow(msg.sender, tokenId);

        // log cancel event
        emit LogCancelGift(_ephemeralAddress, msg.sender, tokenId);
        return true;
    }

    function claimGift(address _receiver) public returns (bool success) {
        // only holder of ephemeral private key can claim gift
        address _ephemeralAddress = msg.sender;

        uint256 tokenId = ephemeralWalletCards[_ephemeralAddress];

        require(tokenId != 0, "The calling address does not have an ephemeral card associated with it");

        RadiCard storage card = tokenIdToRadiCardIndex[tokenId];

        // is deposited and wasn't claimed or cancelled before
        require(card.status == Statuses.Deposited, "Can only claim a gift that is unclaimed");

        // update gift status to claimed
        card.status = Statuses.Claimed;

        // send nft to receiver
        transferFromEscrow(_receiver, tokenId);

        // transfer optional ether & dai to receiver's address
        if (card.giftAmount > 0) {
            if(card.daiDonation){
                require(daiContract.transfer(_receiver, card.giftAmount),"Sending to recipient after cancel gift failed");
        }
            else{
                _receiver.transfer(card.giftAmount);
            }
        }

        // log claim event
        emit LogClaimGift(
            _ephemeralAddress,
            card.gifter,
            tokenId,
            _receiver,
            card.giftAmount,
            card.daiDonation
        );
        return true;
    }

    function burn(uint256 _tokenId) public pure  {
        revert("Radi.Cards are censorship resistant!");
    }

    function tokenURI(uint256 _tokenId) public view returns (string) {
        require(exists(_tokenId), "token does not exist");

        return Strings.strConcat(tokenBaseURI, tokenURIs[_tokenId]);
    }

    function tokenDetails(uint256 _tokenId)
    public view
    returns (
        address _gifter,
        string _message,
        bool _daiDonation,
        uint256 _giftAmount,
        uint256 _donationAmount,
        Statuses status,
        uint256 _cardIndex,
        uint256 _benefactorIndex
    ) {
        require(exists(_tokenId), "token does not exist");
        RadiCard memory _radiCard = tokenIdToRadiCardIndex[_tokenId];
        return (
        _radiCard.gifter,
        _radiCard.message,
        _radiCard.daiDonation,
        _radiCard.giftAmount,
        _radiCard.donationAmount,
        _radiCard.status,
        _radiCard.cardIndex,
        _radiCard.benefactorIndex
        );
    }

    function tokenBenefactor(uint256 _tokenId)
    public view
    returns (
        address _ethAddress,
        string _name,
        string _website,
        string _logo
    ) {
        require(exists(_tokenId),"Card must exist");
        RadiCard memory _radiCard = tokenIdToRadiCardIndex[_tokenId];
        Benefactor memory _benefactor = benefactors[_radiCard.benefactorIndex];
        return (
        _benefactor.ethAddress,
        _benefactor.name,
        _benefactor.website,
        _benefactor.logo
        );
    }

    function tokensOf(address _owner) public view returns (uint256[] _tokenIds) {
        return ownedTokens[_owner];
    }

    function benefactorsKeys() public view returns (uint256[] _keys) {
        return benefactorsIndex;
    }

    function cardsKeys() public view returns (uint256[] _keys) {
        return cardsIndex;
    }

    function addBenefactor(uint256 _benefactorIndex, address _ethAddress, string _name, string _website, string _logo)
    public onlyIfWhitelisted(msg.sender)
    returns (bool) {
        require(address(_ethAddress) != address(0), "Invalid address");
        require(bytes(_name).length != 0, "Invalid name");
        require(bytes(_website).length != 0, "Invalid name");
        require(bytes(_logo).length != 0, "Invalid name");

        benefactors[_benefactorIndex] = Benefactor(
            _ethAddress,
            _name,
            _website,
            _logo
        );
        benefactorsIndex.push(_benefactorIndex);

        emit BenefactorAdded(_benefactorIndex);
        return true;
    }

    function addCard(uint256 _cardIndex, string _tokenURI, bool _active, uint256 _maxQnty, uint256 _minPrice)
    public onlyIfWhitelisted(msg.sender)
    returns (bool) {
        require(bytes(_tokenURI).length != 0, "Invalid token URI");

        cards[_cardIndex] = CardDesign(
            _tokenURI,
            _active,
            0,
            _maxQnty,
            _minPrice
        );
        cardsIndex.push(_cardIndex);

        emit CardAdded(_cardIndex);
        return true;
    }

    function setTokenBaseURI(string _newBaseURI) external onlyIfWhitelisted(msg.sender) {
        require(bytes(_newBaseURI).length != 0, "Base URI invalid");

        tokenBaseURI = _newBaseURI;
    }

    function setActive(uint256 _cardIndex, bool _active) external onlyIfWhitelisted(msg.sender) {
        require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card");
        cards[_cardIndex].active = _active;
    }

    function setMaxQuantity(uint256 _cardIndex, uint256 _maxQnty) external onlyIfWhitelisted(msg.sender) {
        require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card");
        require(cards[_cardIndex].minted <= _maxQnty, "Can't set the max quantity less than the current total minted");
        cards[_cardIndex].maxQnty = _maxQnty;
    }

    function setMinPrice(uint256 _cardIndex, uint256 _minPrice) external onlyIfWhitelisted(msg.sender) {
        require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card");
        cards[_cardIndex].minPrice = _minPrice;
    }

    function setDaiContractAddress(address _daiERC20ContractAddress) external onlyIfWhitelisted(msg.sender){
        require(_daiERC20ContractAddress != address(0), "Must be a valid address");
        daiContract = StandardToken(_daiERC20ContractAddress);
    }

    // sets the medianizer contract for the makerdao implementation used as a price oracle
    function setMedianizerContractAddress(address _MedianizerContractAddress) external onlyIfWhitelisted(msg.sender){
        require(_MedianizerContractAddress != address(0), "Must be a valid address");
        medianizerContract = Medianizer(_MedianizerContractAddress);
    }

    // returns the current ether price in usd. 18 decimal point precision used
    function getEtherPrice() public view returns(uint256){
        return uint256(medianizerContract.read());
    }

    // returns the value of ether in atto  (1 usd of ether = 10^18 atto)
    function getEthUsdValue(uint256 _ether) public view returns(uint256){
        return ((_ether*getEtherPrice())/(1 ether));
    }

    // returns the minimum required in wei for a particular card given the card min price in dai
    function getMinCardPriceInWei(uint256 _cardIndex) public view returns(uint256){
        return ((cards[_cardIndex].minPrice * 1 ether)/getEtherPrice());
    }
    // transfer tokens held by this contract in escrow to the recipient. Used when either claiming or cancelling gifts
    function transferFromEscrow(address _recipient,uint256 _tokenId) internal{
        require(super.ownerOf(_tokenId) == address(this),"The card must be owned by the contract for it to be in escrow");
        super.clearApproval(this, _tokenId);
        super.removeTokenFrom(this, _tokenId);
        super.addTokenTo(_recipient, _tokenId);
        emit Transfer(this, _recipient, _tokenId);
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"benefactorsKeys","outputs":[{"name":"_keys","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_daiERC20ContractAddress","type":"address"}],"name":"setDaiContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"}],"name":"claimGift","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenIdToRadiCardIndex","outputs":[{"name":"gifter","type":"address"},{"name":"message","type":"string"},{"name":"daiDonation","type":"bool"},{"name":"giftAmount","type":"uint256"},{"name":"donationAmount","type":"uint256"},{"name":"status","type":"uint8"},{"name":"cardIndex","type":"uint256"},{"name":"benefactorIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"},{"name":"_role","type":"string"}],"name":"checkRole","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"benefactors","outputs":[{"name":"ethAddress","type":"address"},{"name":"name","type":"string"},{"name":"website","type":"string"},{"name":"logo","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROLE_WHITELISTED","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenBenefactor","outputs":[{"name":"_ethAddress","type":"address"},{"name":"_name","type":"string"},{"name":"_website","type":"string"},{"name":"_logo","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"},{"name":"_role","type":"string"}],"name":"hasRole","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operators","type":"address[]"}],"name":"removeAddressesFromWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_ephemeralAddress","type":"address"}],"name":"cancelGift","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"}],"name":"removeAddressFromWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_benefactorIndex","type":"uint256"},{"name":"_ethAddress","type":"address"},{"name":"_name","type":"string"},{"name":"_website","type":"string"},{"name":"_logo","type":"string"}],"name":"addBenefactor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenIdPointer","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_tokenURI","type":"string"},{"name":"_active","type":"bool"},{"name":"_maxQnty","type":"uint256"},{"name":"_minPrice","type":"uint256"}],"name":"addCard","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalGiftedInAtto","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"EPHEMERAL_ADDRESS_FEE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ether","type":"uint256"}],"name":"getEthUsdValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_minPrice","type":"uint256"}],"name":"setMinPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenBaseURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOf","outputs":[{"name":"_tokenIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_maxQnty","type":"uint256"}],"name":"setMaxQuantity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardIndex","type":"uint256"}],"name":"getMinCardPriceInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"}],"name":"addAddressToWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"ephemeralWalletCards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_MedianizerContractAddress","type":"address"}],"name":"setMedianizerContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"cards","outputs":[{"name":"tokenURI","type":"string"},{"name":"active","type":"bool"},{"name":"minted","type":"uint256"},{"name":"maxQnty","type":"uint256"},{"name":"minPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newBaseURI","type":"string"}],"name":"setTokenBaseURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalDonatedInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"}],"name":"whitelist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_benefactorIndex","type":"uint256"},{"name":"_cardIndex","type":"uint256"},{"name":"_message","type":"string"},{"name":"_donationAmount","type":"uint256"},{"name":"_giftAmount","type":"uint256"},{"name":"_claimableLink","type":"bool"}],"name":"giftInDai","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_benefactorIndex","type":"uint256"},{"name":"_cardIndex","type":"uint256"},{"name":"_message","type":"string"},{"name":"_donationAmount","type":"uint256"},{"name":"_giftAmount","type":"uint256"},{"name":"_claimableLink","type":"bool"}],"name":"gift","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEtherPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operators","type":"address[]"}],"name":"addAddressesToWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_active","type":"bool"}],"name":"setActive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalDonatedInAtto","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cardsKeys","outputs":[{"name":"_keys","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalGiftedInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenDetails","outputs":[{"name":"_gifter","type":"address"},{"name":"_message","type":"string"},{"name":"_daiDonation","type":"bool"},{"name":"_giftAmount","type":"uint256"},{"name":"_donationAmount","type":"uint256"},{"name":"status","type":"uint8"},{"name":"_cardIndex","type":"uint256"},{"name":"_benefactorIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_benefactorIndex","type":"uint256"},{"indexed":true,"name":"_cardIndex","type":"uint256"},{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"daiDonation","type":"bool"},{"indexed":false,"name":"giftAmount","type":"uint256"},{"indexed":false,"name":"donationAmount","type":"uint256"},{"indexed":false,"name":"status","type":"uint8"}],"name":"CardGifted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ephemeralAddress","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"receiver","type":"address"},{"indexed":false,"name":"giftAmount","type":"uint256"},{"indexed":false,"name":"daiDonation","type":"bool"}],"name":"LogClaimGift","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ephemeralAddress","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"LogCancelGift","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_benefactorIndex","type":"uint256"}],"name":"BenefactorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_cardIndex","type":"uint256"}],"name":"CardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"role","type":"string"}],"name":"RoleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"role","type":"string"}],"name":"RoleRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

60c0604052601c60808190527f68747470733a2f2f697066732e696e667572612e696f2f697066732f0000000060a09081526200004091601091906200044c565b506000601155662386f26fc100006012553480156200005e57600080fd5b50604080518082018252600981527f52616469436172647300000000000000000000000000000000000000000000006020808301919091528251808401909352600483527f52414449000000000000000000000000000000000000000000000000000000009083015290620000fc7f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001307f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001647f4f558e790000000000000000000000000000000000000000000000000000000064010000000062000229810204565b8151620001799060059060208501906200044c565b5080516200018f9060069060208401906200044c565b50620001c47f780e9d630000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001f87f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000229810204565b5050600c8054600160a060020a03191633908117909155620002239064010000000062000296810204565b620004f1565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200025957600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b600c54600160a060020a03163314620002ae57600080fd5b620002fe816040805190810160405280600981526020017f77686974656c697374000000000000000000000000000000000000000000000081525062000301640100000000026401000000009004565b50565b6200037d82600d836040518082805190602001908083835b602083106200033a5780518252601f19909201916020918201910162000319565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220929150506401000000006200042781026200527d1704565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b700489826040518080602001828103825283818151815260200191508051906020019080838360005b83811015620003e8578181015183820152602001620003ce565b50505050905090810190601f168015620004165780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200048f57805160ff1916838001178555620004bf565b82800160010185558215620004bf579182015b82811115620004bf578251825591602001919060010190620004a2565b50620004cd929150620004d1565b5090565b620004ee91905b80821115620004cd5760008155600101620004d8565b90565b61584a80620005016000396000f3006080604052600436106102df5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a781146102e457806303cfe12d1461032f578063040e0d311461039457806304f3c40e146103b757806306fdde03146103d85780630701fd6b14610462578063081812fc14610547578063095ea7b31461057b5780630988ca8c1461059f578063128ee16114610606578063150b7a021461077b57806318160ddd1461081c57806318b919e91461084357806319fa8f50146108585780631db1b4fd1461086d578063217fe6c61461088557806323b872dd146108ec57806324953eaa14610916578063254e6f261461096b578063286dd3f51461098c5780632f745c59146109ad57806337073a87146109d15780633b3a1a7a14610ab65780633bac8f9014610acb5780633eeb8d1714610b3657806342842e0e14610b4b57806342966c6814610b755780634b745f9014610b8d5780634d02fef714610ba25780634d7bb88114610bba5780634e99b80014610bd55780634f558e7914610bea5780634f6ccce714610c025780635a3f267214610c1a5780636352211e14610c3b57806370a0823114610c53578063715018a614610c74578063757000f714610c89578063757f015514610ca45780637b9417c814610cbc57806388f0e36414610cdd57806389ae3b1f14610cfe5780638da5cb5b14610d1f5780638dc1076814610d345780638ef79e9114610de457806395d89b4114610e045780639b10acdc14610e195780639b19251a14610e2e578063a10b79bc14610e4f578063a22cb46514610ebd578063b88d4fde14610ee3578063c28ae87614610f52578063c87b56dd14610fc0578063ca7c4dba14610fd8578063e2ec6ec314610fed578063e60a955d14611042578063e7ac2a521461105f578063e985e9c514611074578063f2fde38b1461109b578063f7ad51ce146110bc578063f9256de1146110d1578063fc314e31146110e6575b600080fd5b3480156102f057600080fd5b5061031b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19600435166110fe565b604080519115158252519081900360200190f35b34801561033b57600080fd5b50610344611132565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610380578181015183820152602001610368565b505050509050019250505060405180910390f35b3480156103a057600080fd5b506103b5600160a060020a036004351661118b565b005b3480156103c357600080fd5b5061031b600160a060020a0360043516611249565b3480156103e457600080fd5b506103ed6115a3565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046e57600080fd5b5061047a600435611630565b6040518089600160a060020a0316600160a060020a0316815260200180602001881515151581526020018781526020018681526020018560038111156104bc57fe5b60ff168152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b838110156105055781810151838201526020016104ed565b50505050905090810190601f1680156105325780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b34801561055357600080fd5b5061055f60043561170f565b60408051600160a060020a039092168252519081900360200190f35b34801561058757600080fd5b506103b5600160a060020a036004351660243561172a565b3480156105ab57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526103b5958335600160a060020a03169536956044949193909101919081908401838280828437509497506117e09650505050505050565b34801561061257600080fd5b5061061e60043561184e565b6040518085600160a060020a0316600160a060020a03168152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561067b578181015183820152602001610663565b50505050905090810190601f1680156106a85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156106db5781810151838201526020016106c3565b50505050905090810190601f1680156107085780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561073b578181015183820152602001610723565b50505050905090810190601f1680156107685780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34801561078757600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526107ea94600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750611a249650505050505050565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199092168252519081900360200190f35b34801561082857600080fd5b50610831611a4d565b60408051918252519081900360200190f35b34801561084f57600080fd5b506103ed611a53565b34801561086457600080fd5b506107ea611a78565b34801561087957600080fd5b5061061e600435611a9c565b34801561089157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e419650505050505050565b3480156108f857600080fd5b506103b5600160a060020a0360043581169060243516604435611eb4565b34801561092257600080fd5b50604080516020600480358082013583810280860185019096528085526103b595369593946024949385019291829185019084908082843750949750611f579650505050505050565b34801561097757600080fd5b5061031b600160a060020a0360043516611fa6565b34801561099857600080fd5b506103b5600160a060020a0360043516612358565b3480156109b957600080fd5b50610831600160a060020a036004351660243561239f565b3480156109dd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261031b9482359460248035600160a060020a03169536959460649492019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506123ec9650505050505050565b348015610ac257600080fd5b5061083161269d565b348015610ad757600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b9583359536956044949193909101919081908401838280828437509497505050508235151593505050602081013590604001356126a3565b348015610b4257600080fd5b50610831612822565b348015610b5757600080fd5b506103b5600160a060020a0360043581169060243516604435612828565b348015610b8157600080fd5b506103b5600435612849565b348015610b9957600080fd5b506108316128be565b348015610bae57600080fd5b506108316004356128c4565b348015610bc657600080fd5b506103b56004356024356128e9565b348015610be157600080fd5b506103ed6129a5565b348015610bf657600080fd5b5061031b600435612a33565b348015610c0e57600080fd5b50610831600435612a50565b348015610c2657600080fd5b50610344600160a060020a0360043516612a85565b348015610c4757600080fd5b5061055f600435612af1565b348015610c5f57600080fd5b50610831600160a060020a0360043516612b1b565b348015610c8057600080fd5b506103b5612b4e565b348015610c9557600080fd5b506103b5600435602435612bbc565b348015610cb057600080fd5b50610831600435612d07565b348015610cc857600080fd5b506103b5600160a060020a0360043516612d36565b348015610ce957600080fd5b50610831600160a060020a0360043516612d7a565b348015610d0a57600080fd5b506103b5600160a060020a0360043516612d8c565b348015610d2b57600080fd5b5061055f612e4a565b348015610d4057600080fd5b50610d4c600435612e59565b604051808060200186151515158152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b83811015610da5578181015183820152602001610d8d565b50505050905090810190601f168015610dd25780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610df057600080fd5b506103b56004803560248101910135612f17565b348015610e1057600080fd5b506103ed612fae565b348015610e2557600080fd5b5061083161300f565b348015610e3a57600080fd5b5061031b600160a060020a0360043516613015565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a0381351694602480359560443595369560849493019181908401838280828437509497505084359550505060208301359260400135151591506130449050565b348015610ec957600080fd5b506103b5600160a060020a03600435166024351515613b8d565b348015610eef57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526103b594600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750613c119650505050505050565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a038135169460248035956044359536956084949301918190840183828082843750949750508435955050506020830135926040013515159150613c339050565b348015610fcc57600080fd5b506103ed6004356143ca565b348015610fe457600080fd5b50610831614559565b348015610ff957600080fd5b50604080516020600480358082013583810280860185019096528085526103b5953695939460249493850192918291850190849080828437509497506145e99650505050505050565b34801561104e57600080fd5b506103b56004356024351515614638565b34801561106b57600080fd5b50610831614702565b34801561108057600080fd5b5061031b600160a060020a0360043581169060243516614708565b3480156110a757600080fd5b506103b5600160a060020a0360043516614736565b3480156110c857600080fd5b50610344614756565b3480156110dd57600080fd5b506108316147ac565b3480156110f257600080fd5b5061047a6004356147b2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b6060601580548060200260200160405190810160405280929190818152602001828054801561118057602002820191906000526020600020905b81548152602001906001019080831161116c575b505050505090505b90565b336111b9816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515611219576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b3360008181526013602052604081205490919082811515611300576040805160e560020a62461bcd02815260206004820152604660248201527f5468652063616c6c696e67206164647265737320646f6573206e6f742068617660448201527f6520616e20657068656d6572616c2063617264206173736f636961746564207760648201527f6974682069740000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561132457fe5b1461139f576040805160e560020a62461bcd02815260206004820152602760248201527f43616e206f6e6c7920636c61696d20612067696674207468617420697320756e60448201527f636c61696d656400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660021790556113b8858361498c565b60008160030154111561152f57600281015460ff16156114f457600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561144757600080fd5b505af115801561145b573d6000803e3d6000fd5b505050506040513d602081101561147157600080fd5b505115156114ef576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b61152f565b6003810154604051600160a060020a0387169180156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b80546003820154600283015460408051868152600160a060020a038a811660208301528183019490945260ff909216151560608301525192821692918616917f8944759db4d9e17454f6653113d7eb5bbd79f48e6ee8daef92bfce7bc5d5b1569181900360800190a3506001949350505050565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b820191906000526020600020905b81548152906001019060200180831161161257509395945050505050565b6018602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156116da5780601f106116af576101008083540402835291602001916116da565b820191906000526020600020905b8154815290600101906020018083116116bd57829003601f168201915b5050505060028301546003840154600485015460058601546006870154600790970154959660ff948516969395509193169188565b600090815260026020526040902054600160a060020a031690565b600061173582612af1565b9050600160a060020a03838116908216141561175057600080fd5b33600160a060020a038216148061176c575061176c8133614708565b151561177757600080fd5b600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61184a82600d836040518082805190602001908083835b602083106118165780518252601f1990920191602091820191016117f7565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a74565b5050565b6014602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156118f85780601f106118cd576101008083540402835291602001916118f8565b820191906000526020600020905b8154815290600101906020018083116118db57829003601f168201915b50505060028085018054604080516020601f600019610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561198a5780601f1061195f5761010080835404028352916020019161198a565b820191906000526020600020905b81548152906001019060200180831161196d57829003601f168201915b5050505060038301805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152949594935090830182828015611a1a5780601f106119ef57610100808354040283529160200191611a1a565b820191906000526020600020905b8154815290600101906020018083116119fd57829003601f168201915b5050505050905084565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60095490565b60408051808201909152600981526000805160206157ff833981519152602082015281565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60006060806060611aab615660565b611ab36156a6565b611abc87612a33565b1515611b12576040805160e560020a62461bcd02815260206004820152600f60248201527f43617264206d7573742065786973740000000000000000000000000000000000604482015290519081900360640190fd5b600087815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f8101869004860283018601909652858252919492938581019391929190830182828015611bc65780601f10611b9b57610100808354040283529160200191611bc6565b820191906000526020600020905b815481529060010190602001808311611ba957829003601f168201915b5050509183525050600282015460ff90811615156020830152600380840154604084015260048401546060840152600584015460809093019290911690811115611c0c57fe5b6003811115611c1757fe5b8152600682015460208083019190915260079092015460409182015260e083015160009081526014835281902081516080810183528154600160a060020a03168152600180830180548551600261010094831615949094026000190190911692909204601f8101879004870283018701909552848252959750909491938581019391929190830182828015611ced5780601f10611cc257610100808354040283529160200191611ced565b820191906000526020600020905b815481529060010190602001808311611cd057829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611d7f5780601f10611d5457610100808354040283529160200191611d7f565b820191906000526020600020905b815481529060010190602001808311611d6257829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611e135780601f10611de857610100808354040283529160200191611e13565b820191906000526020600020905b815481529060010190602001808311611df657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000611ead83600d846040518082805190602001908083835b60208310611e795780518252601f199092019160209182019101611e5a565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a89565b9392505050565b611ebe3382614aa8565b1515611ec957600080fd5b600160a060020a0383161515611ede57600080fd5b600160a060020a0382161515611ef357600080fd5b611efd8382614b07565b611f078382614b76565b611f118282614c7d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600c54600090600160a060020a03163314611f7157600080fd5b5060005b815181101561184a57611f9e8282815181101515611f8f57fe5b90602001906020020151612358565b600101611f75565b600160a060020a03811660009081526013602052604081205481811515612063576040805160e560020a62461bcd02815260206004820152604760248201527f43616e206f6e6c792063616c6c20746869732066756e6374696f6e206f6e206160448201527f6e2061646472657373207468617420776173207573656420617320616e20657060648201527f68656d6572616c00000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561208757fe5b14612102576040805160e560020a62461bcd02815260206004820152603460248201527f63616e206f6e6c792063616e63656c206769667473207468617420617265207560448201527f6e636c61696d656420286465706f736974656429000000000000000000000000606482015290519081900360840190fd5b8054600160a060020a03163314612189576040805160e560020a62461bcd02815260206004820152602d60248201527f6f6e6c792074686520676966746572206f662074686520636172642063616e2060448201527f63616e63656c2061206769667400000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660039081179091558101546000101561230457600281015460ff16156122d257600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481019290925251600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d602081101561224f57600080fd5b505115156122cd576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b612304565b6003810154604051339180156108fc02916000818181858888f19350505050158015612302573d6000803e3d6000fd5b505b61230e338361498c565b6040805183815290513391600160a060020a038716917f93be937d7f02e2964b3a79b3a26d9a782f74bf10449a0c34c03cf59c6dab85339181900360200190a35060019392505050565b600c54600160a060020a0316331461236f57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614cc6565b50565b60006123aa83612b1b565b82106123b557600080fd5b600160a060020a03831660009081526007602052604090208054839081106123d957fe5b9060005260206000200154905092915050565b60003361241c816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a038616151561247c576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b845115156124d4576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b8351151561252c576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b82511515612584576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b60408051608081018252600160a060020a03888116825260208083018981528385018990526060840188905260008c815260148352949094208351815473ffffffffffffffffffffffffffffffffffffffff1916931692909217825592518051929391926125f892600185019201906156d8565b50604082015180516126149160028401916020909101906156d8565b50606082015180516126309160038401916020909101906156d8565b50506015805460018101825560009182527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475018990556040518992507f5f4aa3ef0a4bf82c0f10f704eb578f57422b27f40709f8a4aca4694b6bda8ab39190a25060019695505050505050565b60115481565b6000336126d3816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b8551151561272b576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420746f6b656e20555249000000000000000000000000000000604482015290519081900360640190fd5b6040805160a081018252878152861515602080830191909152600082840181905260608301889052608083018790528a81526016825292909220815180519293919261277a92849201906156d8565b5060208201516001828101805460ff19169215159290921790915560408084015160028401556060840151600384015560809093015160049092019190915560178054918201815560009081527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15909101899055905188917fee4df2a71cd5144f989eafc284d855a4cc517ca03f21c5270ed8e2e9dcc3d29c91a25060019695505050505050565b601b5481565b6128448383836020604051908101604052806000815250613c11565b505050565b6040805160e560020a62461bcd028152602060048201526024808201527f526164692e4361726473206172652063656e736f72736869702072657369737460448201527f616e742100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60125481565b6000670de0b6b3a76400006128d7614559565b83028115156128e257fe5b0492915050565b33612917816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b60008381526016602052604090205460026000196101006001841615020190911604151561298f576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b5060009182526016602052604090912060040155565b6010805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612a2b5780601f10612a0057610100808354040283529160200191612a2b565b820191906000526020600020905b815481529060010190602001808311612a0e57829003601f168201915b505050505081565b600090815260016020526040902054600160a060020a0316151590565b6000612a5a611a4d565b8210612a6557600080fd5b6009805483908110612a7357fe5b90600052602060002001549050919050565b600160a060020a038116600090815260076020908152604091829020805483518184028101840190945280845260609392830182828015612ae557602002820191906000526020600020905b815481526020019060010190808311612ad1575b50505050509050919050565b600081815260016020526040812054600160a060020a0316801515612b1557600080fd5b92915050565b6000600160a060020a0382161515612b3257600080fd5b50600160a060020a031660009081526003602052604090205490565b600c54600160a060020a03163314612b6557600080fd5b600c54604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600c805473ffffffffffffffffffffffffffffffffffffffff19169055565b33612bea816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600083815260166020526040902054600260001961010060018416150201909116041515612c62576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b600083815260166020526040902060020154821015612cf1576040805160e560020a62461bcd02815260206004820152603d60248201527f43616e27742073657420746865206d6178207175616e74697479206c6573732060448201527f7468616e207468652063757272656e7420746f74616c206d696e746564000000606482015290519081900360840190fd5b5060009182526016602052604090912060030155565b6000612d11614559565b600083815260166020526040902060040154670de0b6b3a7640000028115156128e257fe5b600c54600160a060020a03163314612d4d57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614dd7565b60136020526000908152604090205481565b33612dba816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515612e1a576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600f805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600c54600160a060020a031681565b60166020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015612ef05780601f10612ec557610100808354040283529160200191612ef0565b820191906000526020600020905b815481529060010190602001808311612ed357829003601f168201915b50505050600183015460028401546003850154600490950154939460ff9092169390925085565b33612f45816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b811515612f9c576040805160e560020a62461bcd02815260206004820152601060248201527f426173652055524920696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b612fa860108484615756565b50505050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b601a5481565b6000612b15826040805190810160405280600981526020016000805160206157ff833981519152815250611e41565b600080808080600160a060020a038c1615156130aa576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b60008811156131215760008b815260146020526040902054600160a060020a03161515613121576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b60008a815260166020526040902054600260001961010060018416150201909116041515613199576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008a81526016602052604090206001015460ff161515613204576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b600e54604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051600160a060020a039092169163dd62ed3e916044808201926020929091908290030181600087803b15801561327057600080fd5b505af1158015613284573d6000803e3d6000fd5b505050506040513d602081101561329a57600080fd5b5051888801111561331b576040805160e560020a62461bcd02815260206004820152603c60248201527f4d75737420686176652070726f7669646564206869676820656e6f756768206160448201527f6c6f77616e636520746f20526164696361726420636f6e747261637400000000606482015290519081900360840190fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b15801561338157600080fd5b505af1158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b50518888011115613452576040805160e560020a62461bcd02815260206004820152604960248201527f4d757374206861766520656e6f75676820746f6b656e2062616c616e6365206f60448201527f662064616920746f2070617920666f7220646f6e6174696f6e20616e6420676960648201527f667420616d6f756e740000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b60008a81526016602052604081206003015411156134fe5760008a81526016602052604090206003810154600290910154106134fe576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008a81526016602052604081206004015411156135cd5760008a81526016602052604090206004015488880110156135cd576040805160e560020a62461bcd02815260206004820152604f60248201527f54686520746f74616c206461692073656e74207769746820746865207472616e60448201527f73616374696f6e206973206c657373207468616e20746865206d696e2070726960648201527f6365206f662074686520746f6b656e0000000000000000000000000000000000608482015290519081900360a40190fd5b85156136d2576012543414613678576040805160e560020a62461bcd02815260206004820152604760248201527f4120636c61696d61626c65206c696e6b207761732067656e657261746564206260448201527f7574206e6f7420656e6f75676820657068656d6572616c20657468657220776160648201527f732073656e742100000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038d1660008181526013602052604080822093909355601254925160019750309650919280156108fc02929091818181858888f193505050501580156136cc573d6000803e3d6000fd5b506136da565b600293508b92505b6101006040519081016040528033600160a060020a031681526020018a815260200160011515815260200188815260200189815260200185600381111561371d57fe5b815260208082018d905260409182018e9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192613782926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156137d257fe5b021790555060c0820151600682015560e09091015160079091015560008a8152601660209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526138909387939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b820191906000526020600020905b81548152906001019060200180831161386957829003601f168201915b5050505050614ea9565b60008b8152601660205260408120600201805460010190559092508811156139d4575060008a815260146020908152604080832054600e5482517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0392831660248201819052604482018e90529351939591909216936323b872dd93606480850194929391928390030190829087803b15801561393b57600080fd5b505af115801561394f573d6000803e3d6000fd5b505050506040513d602081101561396557600080fd5b505115156139bd576040805160e560020a62461bcd02815260206004820152601c60248201527f53656e64696e6720746f2062656e65666163746f72206661696c656400000000604482015290519081900360640190fd5b601c546139d0908963ffffffff614ee116565b601c555b6000871115613aeb57600e54604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018b9052915191909216916323b872dd9160648083019260209291908290030181600087803b158015613a5257600080fd5b505af1158015613a66573d6000803e3d6000fd5b505050506040513d6020811015613a7c57600080fd5b50511515613ad4576040805160e560020a62461bcd02815260206004820152601b60248201527f53656e64696e6720746f20726563697069656e74206661696c65640000000000604482015290519081900360640190fd5b601b54613ae7908863ffffffff614ee116565b601b555b898b84600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338660018d8f8c6040518087600160a060020a0316600160a060020a0316815260200186815260200185151515158152602001848152602001838152602001826003811115613b6357fe5b60ff168152602001965050505050505060405180910390a45060019b9a5050505050505050505050565b600160a060020a038216331415613ba357600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b613c1c848484611eb4565b613c2884848484614eee565b1515612fa857600080fd5b6000808080600160a060020a038b161515613c98576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b6000871115613d0f5760008a815260146020526040902054600160a060020a03161515613d0f576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b600089815260166020526040902054600260001961010060018416150201909116041515613d87576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008981526016602052604090206001015460ff161515613df2576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b8415613efb57601254878701013414613ea1576040805160e560020a62461bcd02815260206004820152604c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e74202b204560648201527f7068656d6572616c206665650000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038c1660008181526013602052604080822093909355601254925160019650309550919280156108fc02929091818181858888f19350505050158015613ef5573d6000803e3d6000fd5b50613f82565b8686013414613f7a576040805160e560020a62461bcd02815260206004820152603c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e7400000000606482015290519081900360840190fd5b600292508a91505b600089815260166020526040812060030154111561402e57600089815260166020526040902060038101546002909101541061402e576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008981526016602052604081206004015411156140cc57346140508a612d07565b11156140cc576040805160e560020a62461bcd02815260206004820152603160248201527f4d7573742073656e64206174206c6561737420746865206d696e696d756d206160448201527f6d6f756e7420746f206275792063617264000000000000000000000000000000606482015290519081900360840190fd5b6101006040519081016040528033600160a060020a0316815260200189815260200160001515815260200187815260200188815260200184600381111561410f57fe5b815260208082018c905260409182018d9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192614174926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156141c457fe5b021790555060c0820151600682015560e0909101516007909101556000898152601660209081526040918290208054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815261424d9386939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b60008a8152601660205260408120600201805460010190559091508711156142cb5760008a815260146020526040808220549051600160a060020a039091169189156108fc02918a91818181858888f193505050501580156142b3573d6000803e3d6000fd5b50601a546142c7908863ffffffff614ee116565b601a555b6000861115614329576019546142e7908763ffffffff614ee116565b60195584151561432957604051600160a060020a0383169087156108fc029088906000818181858888f19350505050158015614327573d6000803e3d6000fd5b505b888a83600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338560008c8e8b6040518087600160a060020a0316600160a060020a03168152602001868152602001851515151581526020018481526020018381526020018260038111156143a157fe5b60ff168152602001965050505050505060405180910390a45060019a9950505050505050505050565b60606143d582612a33565b151561442b576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60108054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152612b1593909290918301828280156144b85780601f1061448d576101008083540402835291602001916144b8565b820191906000526020600020905b81548152906001019060200180831161449b57829003601f168201915b5050506000868152600b60209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381529450925083018282801561454f5780601f106145245761010080835404028352916020019161454f565b820191906000526020600020905b81548152906001019060200180831161453257829003601f168201915b5050505050615070565b600f54604080517f57de26a40000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916357de26a491600480830192602092919082900301818787803b1580156145b857600080fd5b505af11580156145cc573d6000803e3d6000fd5b505050506040513d60208110156145e257600080fd5b5051905090565b600c54600090600160a060020a0316331461460357600080fd5b5060005b815181101561184a57614630828281518110151561462157fe5b90602001906020020151612d36565b600101614607565b33614666816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b6000838152601660205260409020546002600019610100600184161502019091160415156146de576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b50600091825260166020526040909120600101805460ff1916911515919091179055565b601c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c54600160a060020a0316331461474d57600080fd5b61239c816150a5565b60606017805480602002602001604051908101604052809291908181526020018280548015611180576020028201919060005260206000209081548152602001906001019080831161116c575050505050905090565b60195481565b600060606000806000806000806147c7615660565b6147d08a612a33565b1515614826576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60008a815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f81018690048602830186019096528582529194929385810193919291908301828280156148da5780601f106148af576101008083540402835291602001916148da565b820191906000526020600020905b8154815290600101906020018083116148bd57829003601f168201915b5050509183525050600282015460ff9081161515602083015260038084015460408401526004840154606084015260058401546080909301929091169081111561492057fe5b600381111561492b57fe5b8152602001600682015481526020016007820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518696509850985098509850985098509850985050919395975091939597565b3061499682612af1565b600160a060020a031614614a1a576040805160e560020a62461bcd02815260206004820152603d60248201527f5468652063617264206d757374206265206f776e65642062792074686520636f60448201527f6e747261637420666f7220697420746f20626520696e20657363726f77000000606482015290519081900360840190fd5b614a243082614b07565b614a2e3082614b76565b614a388282614c7d565b6040518190600160a060020a0384169030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a45050565b614a7e8282614a89565b151561184a57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b600080614ab483612af1565b905080600160a060020a031684600160a060020a03161480614aef575083600160a060020a0316614ae48461170f565b600160a060020a0316145b80614aff5750614aff8185614708565b949350505050565b81600160a060020a0316614b1a82612af1565b600160a060020a031614614b2d57600080fd5b600081815260026020526040902054600160a060020a03161561184a576000908152600260205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b6000806000614b858585615123565b600084815260086020908152604080832054600160a060020a0389168452600790925290912054909350614bc090600163ffffffff6151b916565b600160a060020a038616600090815260076020526040902080549193509083908110614be857fe5b90600052602060002001549050806007600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614c2857fe5b6000918252602080832090910192909255600160a060020a0387168152600790915260409020805490614c5f9060001983016157c4565b50600093845260086020526040808520859055908452909220555050565b6000614c8983836151cb565b50600160a060020a039091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b614d3082600d836040518082805190602001908083835b60208310614cfc5780518252601f199092019160209182019101614cdd565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061525b565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b83811015614d99578181015183820152602001614d81565b50505050905090810190601f168015614dc65780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b614e4182600d836040518082805190602001908083835b60208310614e0d5780518252601f199092019160209182019101614dee565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061527d565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b7004898260405180806020018281038252838181518152602001915080519060200190808383600083811015614d99578181015183820152602001614d81565b601154600090614eb984826152a2565b614ec381846152f1565b601154614ed790600163ffffffff614ee116565b6011559392505050565b81810182811015612b1557fe5b600080614f0385600160a060020a0316615324565b1515614f125760019150615067565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614fa5578181015183820152602001614f8d565b50505050905090810190601f168015614fd25780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050506040513d602081101561501e57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b604080516020818101835260008083528351808301855281815284519283019094528152606092611ead92869286929061532c565b600160a060020a03811615156150ba57600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81600160a060020a031661513682612af1565b600160a060020a03161461514957600080fd5b600160a060020a03821660009081526003602052604090205461517390600163ffffffff6151b916565b600160a060020a03909216600090815260036020908152604080832094909455918152600190915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000828211156151c557fe5b50900390565b600081815260016020526040902054600160a060020a0316156151ed57600080fd5b6000818152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038816908117909155845260039091529091205461523b91614ee1565b600160a060020a0390921660009081526003602052604090209190915550565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6152ac8282615605565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b6152fa82612a33565b151561530557600080fd5b6000828152600b602090815260409091208251612844928401906156d8565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f191660200182016040528015615385578160200160208202803883390190505b50935083925060009150600090505b885181101561540a5788818151811015156153ab57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156153d257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615394565b5060005b875181101561548457878181518110151561542557fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561544c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161540e565b5060005b86518110156154fe57868181518110151561549f57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156154c657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615488565b5060005b855181101561557857858181518110151561551957fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561554057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615502565b5060005b84518110156155f257848181518110151561559357fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156155ba57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161557c565b50909d9c50505050505050505050505050565b600160a060020a038216151561561a57600080fd5b6156248282614c7d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60408051610100810182526000808252606060208301819052928201819052918101829052608081018290529060a0820190815260200160008152602001600081525090565b6080604051908101604052806000600160a060020a031681526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061571957805160ff1916838001178555615746565b82800160010185558215615746579182015b8281111561574657825182559160200191906001019061572b565b506157529291506157e4565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106157975782800160ff19823516178555615746565b82800160010185558215615746579182015b828111156157465782358255916020019190600101906157a9565b815481835581811115612844576000838152602090206128449181019083015b61118891905b8082111561575257600081556001016157ea560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a72305820610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e390029

Deployed Bytecode

0x6080604052600436106102df5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a781146102e457806303cfe12d1461032f578063040e0d311461039457806304f3c40e146103b757806306fdde03146103d85780630701fd6b14610462578063081812fc14610547578063095ea7b31461057b5780630988ca8c1461059f578063128ee16114610606578063150b7a021461077b57806318160ddd1461081c57806318b919e91461084357806319fa8f50146108585780631db1b4fd1461086d578063217fe6c61461088557806323b872dd146108ec57806324953eaa14610916578063254e6f261461096b578063286dd3f51461098c5780632f745c59146109ad57806337073a87146109d15780633b3a1a7a14610ab65780633bac8f9014610acb5780633eeb8d1714610b3657806342842e0e14610b4b57806342966c6814610b755780634b745f9014610b8d5780634d02fef714610ba25780634d7bb88114610bba5780634e99b80014610bd55780634f558e7914610bea5780634f6ccce714610c025780635a3f267214610c1a5780636352211e14610c3b57806370a0823114610c53578063715018a614610c74578063757000f714610c89578063757f015514610ca45780637b9417c814610cbc57806388f0e36414610cdd57806389ae3b1f14610cfe5780638da5cb5b14610d1f5780638dc1076814610d345780638ef79e9114610de457806395d89b4114610e045780639b10acdc14610e195780639b19251a14610e2e578063a10b79bc14610e4f578063a22cb46514610ebd578063b88d4fde14610ee3578063c28ae87614610f52578063c87b56dd14610fc0578063ca7c4dba14610fd8578063e2ec6ec314610fed578063e60a955d14611042578063e7ac2a521461105f578063e985e9c514611074578063f2fde38b1461109b578063f7ad51ce146110bc578063f9256de1146110d1578063fc314e31146110e6575b600080fd5b3480156102f057600080fd5b5061031b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19600435166110fe565b604080519115158252519081900360200190f35b34801561033b57600080fd5b50610344611132565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610380578181015183820152602001610368565b505050509050019250505060405180910390f35b3480156103a057600080fd5b506103b5600160a060020a036004351661118b565b005b3480156103c357600080fd5b5061031b600160a060020a0360043516611249565b3480156103e457600080fd5b506103ed6115a3565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046e57600080fd5b5061047a600435611630565b6040518089600160a060020a0316600160a060020a0316815260200180602001881515151581526020018781526020018681526020018560038111156104bc57fe5b60ff168152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b838110156105055781810151838201526020016104ed565b50505050905090810190601f1680156105325780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b34801561055357600080fd5b5061055f60043561170f565b60408051600160a060020a039092168252519081900360200190f35b34801561058757600080fd5b506103b5600160a060020a036004351660243561172a565b3480156105ab57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526103b5958335600160a060020a03169536956044949193909101919081908401838280828437509497506117e09650505050505050565b34801561061257600080fd5b5061061e60043561184e565b6040518085600160a060020a0316600160a060020a03168152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561067b578181015183820152602001610663565b50505050905090810190601f1680156106a85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156106db5781810151838201526020016106c3565b50505050905090810190601f1680156107085780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561073b578181015183820152602001610723565b50505050905090810190601f1680156107685780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34801561078757600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526107ea94600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750611a249650505050505050565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199092168252519081900360200190f35b34801561082857600080fd5b50610831611a4d565b60408051918252519081900360200190f35b34801561084f57600080fd5b506103ed611a53565b34801561086457600080fd5b506107ea611a78565b34801561087957600080fd5b5061061e600435611a9c565b34801561089157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e419650505050505050565b3480156108f857600080fd5b506103b5600160a060020a0360043581169060243516604435611eb4565b34801561092257600080fd5b50604080516020600480358082013583810280860185019096528085526103b595369593946024949385019291829185019084908082843750949750611f579650505050505050565b34801561097757600080fd5b5061031b600160a060020a0360043516611fa6565b34801561099857600080fd5b506103b5600160a060020a0360043516612358565b3480156109b957600080fd5b50610831600160a060020a036004351660243561239f565b3480156109dd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261031b9482359460248035600160a060020a03169536959460649492019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506123ec9650505050505050565b348015610ac257600080fd5b5061083161269d565b348015610ad757600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b9583359536956044949193909101919081908401838280828437509497505050508235151593505050602081013590604001356126a3565b348015610b4257600080fd5b50610831612822565b348015610b5757600080fd5b506103b5600160a060020a0360043581169060243516604435612828565b348015610b8157600080fd5b506103b5600435612849565b348015610b9957600080fd5b506108316128be565b348015610bae57600080fd5b506108316004356128c4565b348015610bc657600080fd5b506103b56004356024356128e9565b348015610be157600080fd5b506103ed6129a5565b348015610bf657600080fd5b5061031b600435612a33565b348015610c0e57600080fd5b50610831600435612a50565b348015610c2657600080fd5b50610344600160a060020a0360043516612a85565b348015610c4757600080fd5b5061055f600435612af1565b348015610c5f57600080fd5b50610831600160a060020a0360043516612b1b565b348015610c8057600080fd5b506103b5612b4e565b348015610c9557600080fd5b506103b5600435602435612bbc565b348015610cb057600080fd5b50610831600435612d07565b348015610cc857600080fd5b506103b5600160a060020a0360043516612d36565b348015610ce957600080fd5b50610831600160a060020a0360043516612d7a565b348015610d0a57600080fd5b506103b5600160a060020a0360043516612d8c565b348015610d2b57600080fd5b5061055f612e4a565b348015610d4057600080fd5b50610d4c600435612e59565b604051808060200186151515158152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b83811015610da5578181015183820152602001610d8d565b50505050905090810190601f168015610dd25780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610df057600080fd5b506103b56004803560248101910135612f17565b348015610e1057600080fd5b506103ed612fae565b348015610e2557600080fd5b5061083161300f565b348015610e3a57600080fd5b5061031b600160a060020a0360043516613015565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a0381351694602480359560443595369560849493019181908401838280828437509497505084359550505060208301359260400135151591506130449050565b348015610ec957600080fd5b506103b5600160a060020a03600435166024351515613b8d565b348015610eef57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526103b594600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750613c119650505050505050565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a038135169460248035956044359536956084949301918190840183828082843750949750508435955050506020830135926040013515159150613c339050565b348015610fcc57600080fd5b506103ed6004356143ca565b348015610fe457600080fd5b50610831614559565b348015610ff957600080fd5b50604080516020600480358082013583810280860185019096528085526103b5953695939460249493850192918291850190849080828437509497506145e99650505050505050565b34801561104e57600080fd5b506103b56004356024351515614638565b34801561106b57600080fd5b50610831614702565b34801561108057600080fd5b5061031b600160a060020a0360043581169060243516614708565b3480156110a757600080fd5b506103b5600160a060020a0360043516614736565b3480156110c857600080fd5b50610344614756565b3480156110dd57600080fd5b506108316147ac565b3480156110f257600080fd5b5061047a6004356147b2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b6060601580548060200260200160405190810160405280929190818152602001828054801561118057602002820191906000526020600020905b81548152602001906001019080831161116c575b505050505090505b90565b336111b9816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515611219576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b3360008181526013602052604081205490919082811515611300576040805160e560020a62461bcd02815260206004820152604660248201527f5468652063616c6c696e67206164647265737320646f6573206e6f742068617660448201527f6520616e20657068656d6572616c2063617264206173736f636961746564207760648201527f6974682069740000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561132457fe5b1461139f576040805160e560020a62461bcd02815260206004820152602760248201527f43616e206f6e6c7920636c61696d20612067696674207468617420697320756e60448201527f636c61696d656400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660021790556113b8858361498c565b60008160030154111561152f57600281015460ff16156114f457600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561144757600080fd5b505af115801561145b573d6000803e3d6000fd5b505050506040513d602081101561147157600080fd5b505115156114ef576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b61152f565b6003810154604051600160a060020a0387169180156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b80546003820154600283015460408051868152600160a060020a038a811660208301528183019490945260ff909216151560608301525192821692918616917f8944759db4d9e17454f6653113d7eb5bbd79f48e6ee8daef92bfce7bc5d5b1569181900360800190a3506001949350505050565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b820191906000526020600020905b81548152906001019060200180831161161257509395945050505050565b6018602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156116da5780601f106116af576101008083540402835291602001916116da565b820191906000526020600020905b8154815290600101906020018083116116bd57829003601f168201915b5050505060028301546003840154600485015460058601546006870154600790970154959660ff948516969395509193169188565b600090815260026020526040902054600160a060020a031690565b600061173582612af1565b9050600160a060020a03838116908216141561175057600080fd5b33600160a060020a038216148061176c575061176c8133614708565b151561177757600080fd5b600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61184a82600d836040518082805190602001908083835b602083106118165780518252601f1990920191602091820191016117f7565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a74565b5050565b6014602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156118f85780601f106118cd576101008083540402835291602001916118f8565b820191906000526020600020905b8154815290600101906020018083116118db57829003601f168201915b50505060028085018054604080516020601f600019610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561198a5780601f1061195f5761010080835404028352916020019161198a565b820191906000526020600020905b81548152906001019060200180831161196d57829003601f168201915b5050505060038301805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152949594935090830182828015611a1a5780601f106119ef57610100808354040283529160200191611a1a565b820191906000526020600020905b8154815290600101906020018083116119fd57829003601f168201915b5050505050905084565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60095490565b60408051808201909152600981526000805160206157ff833981519152602082015281565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60006060806060611aab615660565b611ab36156a6565b611abc87612a33565b1515611b12576040805160e560020a62461bcd02815260206004820152600f60248201527f43617264206d7573742065786973740000000000000000000000000000000000604482015290519081900360640190fd5b600087815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f8101869004860283018601909652858252919492938581019391929190830182828015611bc65780601f10611b9b57610100808354040283529160200191611bc6565b820191906000526020600020905b815481529060010190602001808311611ba957829003601f168201915b5050509183525050600282015460ff90811615156020830152600380840154604084015260048401546060840152600584015460809093019290911690811115611c0c57fe5b6003811115611c1757fe5b8152600682015460208083019190915260079092015460409182015260e083015160009081526014835281902081516080810183528154600160a060020a03168152600180830180548551600261010094831615949094026000190190911692909204601f8101879004870283018701909552848252959750909491938581019391929190830182828015611ced5780601f10611cc257610100808354040283529160200191611ced565b820191906000526020600020905b815481529060010190602001808311611cd057829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611d7f5780601f10611d5457610100808354040283529160200191611d7f565b820191906000526020600020905b815481529060010190602001808311611d6257829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611e135780601f10611de857610100808354040283529160200191611e13565b820191906000526020600020905b815481529060010190602001808311611df657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000611ead83600d846040518082805190602001908083835b60208310611e795780518252601f199092019160209182019101611e5a565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a89565b9392505050565b611ebe3382614aa8565b1515611ec957600080fd5b600160a060020a0383161515611ede57600080fd5b600160a060020a0382161515611ef357600080fd5b611efd8382614b07565b611f078382614b76565b611f118282614c7d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600c54600090600160a060020a03163314611f7157600080fd5b5060005b815181101561184a57611f9e8282815181101515611f8f57fe5b90602001906020020151612358565b600101611f75565b600160a060020a03811660009081526013602052604081205481811515612063576040805160e560020a62461bcd02815260206004820152604760248201527f43616e206f6e6c792063616c6c20746869732066756e6374696f6e206f6e206160448201527f6e2061646472657373207468617420776173207573656420617320616e20657060648201527f68656d6572616c00000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561208757fe5b14612102576040805160e560020a62461bcd02815260206004820152603460248201527f63616e206f6e6c792063616e63656c206769667473207468617420617265207560448201527f6e636c61696d656420286465706f736974656429000000000000000000000000606482015290519081900360840190fd5b8054600160a060020a03163314612189576040805160e560020a62461bcd02815260206004820152602d60248201527f6f6e6c792074686520676966746572206f662074686520636172642063616e2060448201527f63616e63656c2061206769667400000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660039081179091558101546000101561230457600281015460ff16156122d257600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481019290925251600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d602081101561224f57600080fd5b505115156122cd576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b612304565b6003810154604051339180156108fc02916000818181858888f19350505050158015612302573d6000803e3d6000fd5b505b61230e338361498c565b6040805183815290513391600160a060020a038716917f93be937d7f02e2964b3a79b3a26d9a782f74bf10449a0c34c03cf59c6dab85339181900360200190a35060019392505050565b600c54600160a060020a0316331461236f57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614cc6565b50565b60006123aa83612b1b565b82106123b557600080fd5b600160a060020a03831660009081526007602052604090208054839081106123d957fe5b9060005260206000200154905092915050565b60003361241c816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a038616151561247c576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b845115156124d4576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b8351151561252c576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b82511515612584576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b60408051608081018252600160a060020a03888116825260208083018981528385018990526060840188905260008c815260148352949094208351815473ffffffffffffffffffffffffffffffffffffffff1916931692909217825592518051929391926125f892600185019201906156d8565b50604082015180516126149160028401916020909101906156d8565b50606082015180516126309160038401916020909101906156d8565b50506015805460018101825560009182527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475018990556040518992507f5f4aa3ef0a4bf82c0f10f704eb578f57422b27f40709f8a4aca4694b6bda8ab39190a25060019695505050505050565b60115481565b6000336126d3816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b8551151561272b576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420746f6b656e20555249000000000000000000000000000000604482015290519081900360640190fd5b6040805160a081018252878152861515602080830191909152600082840181905260608301889052608083018790528a81526016825292909220815180519293919261277a92849201906156d8565b5060208201516001828101805460ff19169215159290921790915560408084015160028401556060840151600384015560809093015160049092019190915560178054918201815560009081527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15909101899055905188917fee4df2a71cd5144f989eafc284d855a4cc517ca03f21c5270ed8e2e9dcc3d29c91a25060019695505050505050565b601b5481565b6128448383836020604051908101604052806000815250613c11565b505050565b6040805160e560020a62461bcd028152602060048201526024808201527f526164692e4361726473206172652063656e736f72736869702072657369737460448201527f616e742100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60125481565b6000670de0b6b3a76400006128d7614559565b83028115156128e257fe5b0492915050565b33612917816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b60008381526016602052604090205460026000196101006001841615020190911604151561298f576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b5060009182526016602052604090912060040155565b6010805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612a2b5780601f10612a0057610100808354040283529160200191612a2b565b820191906000526020600020905b815481529060010190602001808311612a0e57829003601f168201915b505050505081565b600090815260016020526040902054600160a060020a0316151590565b6000612a5a611a4d565b8210612a6557600080fd5b6009805483908110612a7357fe5b90600052602060002001549050919050565b600160a060020a038116600090815260076020908152604091829020805483518184028101840190945280845260609392830182828015612ae557602002820191906000526020600020905b815481526020019060010190808311612ad1575b50505050509050919050565b600081815260016020526040812054600160a060020a0316801515612b1557600080fd5b92915050565b6000600160a060020a0382161515612b3257600080fd5b50600160a060020a031660009081526003602052604090205490565b600c54600160a060020a03163314612b6557600080fd5b600c54604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600c805473ffffffffffffffffffffffffffffffffffffffff19169055565b33612bea816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600083815260166020526040902054600260001961010060018416150201909116041515612c62576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b600083815260166020526040902060020154821015612cf1576040805160e560020a62461bcd02815260206004820152603d60248201527f43616e27742073657420746865206d6178207175616e74697479206c6573732060448201527f7468616e207468652063757272656e7420746f74616c206d696e746564000000606482015290519081900360840190fd5b5060009182526016602052604090912060030155565b6000612d11614559565b600083815260166020526040902060040154670de0b6b3a7640000028115156128e257fe5b600c54600160a060020a03163314612d4d57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614dd7565b60136020526000908152604090205481565b33612dba816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515612e1a576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600f805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600c54600160a060020a031681565b60166020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015612ef05780601f10612ec557610100808354040283529160200191612ef0565b820191906000526020600020905b815481529060010190602001808311612ed357829003601f168201915b50505050600183015460028401546003850154600490950154939460ff9092169390925085565b33612f45816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b811515612f9c576040805160e560020a62461bcd02815260206004820152601060248201527f426173652055524920696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b612fa860108484615756565b50505050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b601a5481565b6000612b15826040805190810160405280600981526020016000805160206157ff833981519152815250611e41565b600080808080600160a060020a038c1615156130aa576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b60008811156131215760008b815260146020526040902054600160a060020a03161515613121576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b60008a815260166020526040902054600260001961010060018416150201909116041515613199576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008a81526016602052604090206001015460ff161515613204576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b600e54604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051600160a060020a039092169163dd62ed3e916044808201926020929091908290030181600087803b15801561327057600080fd5b505af1158015613284573d6000803e3d6000fd5b505050506040513d602081101561329a57600080fd5b5051888801111561331b576040805160e560020a62461bcd02815260206004820152603c60248201527f4d75737420686176652070726f7669646564206869676820656e6f756768206160448201527f6c6f77616e636520746f20526164696361726420636f6e747261637400000000606482015290519081900360840190fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b15801561338157600080fd5b505af1158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b50518888011115613452576040805160e560020a62461bcd02815260206004820152604960248201527f4d757374206861766520656e6f75676820746f6b656e2062616c616e6365206f60448201527f662064616920746f2070617920666f7220646f6e6174696f6e20616e6420676960648201527f667420616d6f756e740000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b60008a81526016602052604081206003015411156134fe5760008a81526016602052604090206003810154600290910154106134fe576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008a81526016602052604081206004015411156135cd5760008a81526016602052604090206004015488880110156135cd576040805160e560020a62461bcd02815260206004820152604f60248201527f54686520746f74616c206461692073656e74207769746820746865207472616e60448201527f73616374696f6e206973206c657373207468616e20746865206d696e2070726960648201527f6365206f662074686520746f6b656e0000000000000000000000000000000000608482015290519081900360a40190fd5b85156136d2576012543414613678576040805160e560020a62461bcd02815260206004820152604760248201527f4120636c61696d61626c65206c696e6b207761732067656e657261746564206260448201527f7574206e6f7420656e6f75676820657068656d6572616c20657468657220776160648201527f732073656e742100000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038d1660008181526013602052604080822093909355601254925160019750309650919280156108fc02929091818181858888f193505050501580156136cc573d6000803e3d6000fd5b506136da565b600293508b92505b6101006040519081016040528033600160a060020a031681526020018a815260200160011515815260200188815260200189815260200185600381111561371d57fe5b815260208082018d905260409182018e9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192613782926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156137d257fe5b021790555060c0820151600682015560e09091015160079091015560008a8152601660209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526138909387939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b820191906000526020600020905b81548152906001019060200180831161386957829003601f168201915b5050505050614ea9565b60008b8152601660205260408120600201805460010190559092508811156139d4575060008a815260146020908152604080832054600e5482517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0392831660248201819052604482018e90529351939591909216936323b872dd93606480850194929391928390030190829087803b15801561393b57600080fd5b505af115801561394f573d6000803e3d6000fd5b505050506040513d602081101561396557600080fd5b505115156139bd576040805160e560020a62461bcd02815260206004820152601c60248201527f53656e64696e6720746f2062656e65666163746f72206661696c656400000000604482015290519081900360640190fd5b601c546139d0908963ffffffff614ee116565b601c555b6000871115613aeb57600e54604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018b9052915191909216916323b872dd9160648083019260209291908290030181600087803b158015613a5257600080fd5b505af1158015613a66573d6000803e3d6000fd5b505050506040513d6020811015613a7c57600080fd5b50511515613ad4576040805160e560020a62461bcd02815260206004820152601b60248201527f53656e64696e6720746f20726563697069656e74206661696c65640000000000604482015290519081900360640190fd5b601b54613ae7908863ffffffff614ee116565b601b555b898b84600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338660018d8f8c6040518087600160a060020a0316600160a060020a0316815260200186815260200185151515158152602001848152602001838152602001826003811115613b6357fe5b60ff168152602001965050505050505060405180910390a45060019b9a5050505050505050505050565b600160a060020a038216331415613ba357600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b613c1c848484611eb4565b613c2884848484614eee565b1515612fa857600080fd5b6000808080600160a060020a038b161515613c98576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b6000871115613d0f5760008a815260146020526040902054600160a060020a03161515613d0f576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b600089815260166020526040902054600260001961010060018416150201909116041515613d87576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008981526016602052604090206001015460ff161515613df2576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b8415613efb57601254878701013414613ea1576040805160e560020a62461bcd02815260206004820152604c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e74202b204560648201527f7068656d6572616c206665650000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038c1660008181526013602052604080822093909355601254925160019650309550919280156108fc02929091818181858888f19350505050158015613ef5573d6000803e3d6000fd5b50613f82565b8686013414613f7a576040805160e560020a62461bcd02815260206004820152603c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e7400000000606482015290519081900360840190fd5b600292508a91505b600089815260166020526040812060030154111561402e57600089815260166020526040902060038101546002909101541061402e576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008981526016602052604081206004015411156140cc57346140508a612d07565b11156140cc576040805160e560020a62461bcd02815260206004820152603160248201527f4d7573742073656e64206174206c6561737420746865206d696e696d756d206160448201527f6d6f756e7420746f206275792063617264000000000000000000000000000000606482015290519081900360840190fd5b6101006040519081016040528033600160a060020a0316815260200189815260200160001515815260200187815260200188815260200184600381111561410f57fe5b815260208082018c905260409182018d9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192614174926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156141c457fe5b021790555060c0820151600682015560e0909101516007909101556000898152601660209081526040918290208054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815261424d9386939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b60008a8152601660205260408120600201805460010190559091508711156142cb5760008a815260146020526040808220549051600160a060020a039091169189156108fc02918a91818181858888f193505050501580156142b3573d6000803e3d6000fd5b50601a546142c7908863ffffffff614ee116565b601a555b6000861115614329576019546142e7908763ffffffff614ee116565b60195584151561432957604051600160a060020a0383169087156108fc029088906000818181858888f19350505050158015614327573d6000803e3d6000fd5b505b888a83600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338560008c8e8b6040518087600160a060020a0316600160a060020a03168152602001868152602001851515151581526020018481526020018381526020018260038111156143a157fe5b60ff168152602001965050505050505060405180910390a45060019a9950505050505050505050565b60606143d582612a33565b151561442b576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60108054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152612b1593909290918301828280156144b85780601f1061448d576101008083540402835291602001916144b8565b820191906000526020600020905b81548152906001019060200180831161449b57829003601f168201915b5050506000868152600b60209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381529450925083018282801561454f5780601f106145245761010080835404028352916020019161454f565b820191906000526020600020905b81548152906001019060200180831161453257829003601f168201915b5050505050615070565b600f54604080517f57de26a40000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916357de26a491600480830192602092919082900301818787803b1580156145b857600080fd5b505af11580156145cc573d6000803e3d6000fd5b505050506040513d60208110156145e257600080fd5b5051905090565b600c54600090600160a060020a0316331461460357600080fd5b5060005b815181101561184a57614630828281518110151561462157fe5b90602001906020020151612d36565b600101614607565b33614666816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b6000838152601660205260409020546002600019610100600184161502019091160415156146de576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b50600091825260166020526040909120600101805460ff1916911515919091179055565b601c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c54600160a060020a0316331461474d57600080fd5b61239c816150a5565b60606017805480602002602001604051908101604052809291908181526020018280548015611180576020028201919060005260206000209081548152602001906001019080831161116c575050505050905090565b60195481565b600060606000806000806000806147c7615660565b6147d08a612a33565b1515614826576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60008a815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f81018690048602830186019096528582529194929385810193919291908301828280156148da5780601f106148af576101008083540402835291602001916148da565b820191906000526020600020905b8154815290600101906020018083116148bd57829003601f168201915b5050509183525050600282015460ff9081161515602083015260038084015460408401526004840154606084015260058401546080909301929091169081111561492057fe5b600381111561492b57fe5b8152602001600682015481526020016007820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518696509850985098509850985098509850985050919395975091939597565b3061499682612af1565b600160a060020a031614614a1a576040805160e560020a62461bcd02815260206004820152603d60248201527f5468652063617264206d757374206265206f776e65642062792074686520636f60448201527f6e747261637420666f7220697420746f20626520696e20657363726f77000000606482015290519081900360840190fd5b614a243082614b07565b614a2e3082614b76565b614a388282614c7d565b6040518190600160a060020a0384169030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a45050565b614a7e8282614a89565b151561184a57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b600080614ab483612af1565b905080600160a060020a031684600160a060020a03161480614aef575083600160a060020a0316614ae48461170f565b600160a060020a0316145b80614aff5750614aff8185614708565b949350505050565b81600160a060020a0316614b1a82612af1565b600160a060020a031614614b2d57600080fd5b600081815260026020526040902054600160a060020a03161561184a576000908152600260205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b6000806000614b858585615123565b600084815260086020908152604080832054600160a060020a0389168452600790925290912054909350614bc090600163ffffffff6151b916565b600160a060020a038616600090815260076020526040902080549193509083908110614be857fe5b90600052602060002001549050806007600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614c2857fe5b6000918252602080832090910192909255600160a060020a0387168152600790915260409020805490614c5f9060001983016157c4565b50600093845260086020526040808520859055908452909220555050565b6000614c8983836151cb565b50600160a060020a039091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b614d3082600d836040518082805190602001908083835b60208310614cfc5780518252601f199092019160209182019101614cdd565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061525b565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b83811015614d99578181015183820152602001614d81565b50505050905090810190601f168015614dc65780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b614e4182600d836040518082805190602001908083835b60208310614e0d5780518252601f199092019160209182019101614dee565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061527d565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b7004898260405180806020018281038252838181518152602001915080519060200190808383600083811015614d99578181015183820152602001614d81565b601154600090614eb984826152a2565b614ec381846152f1565b601154614ed790600163ffffffff614ee116565b6011559392505050565b81810182811015612b1557fe5b600080614f0385600160a060020a0316615324565b1515614f125760019150615067565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614fa5578181015183820152602001614f8d565b50505050905090810190601f168015614fd25780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050506040513d602081101561501e57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b604080516020818101835260008083528351808301855281815284519283019094528152606092611ead92869286929061532c565b600160a060020a03811615156150ba57600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81600160a060020a031661513682612af1565b600160a060020a03161461514957600080fd5b600160a060020a03821660009081526003602052604090205461517390600163ffffffff6151b916565b600160a060020a03909216600090815260036020908152604080832094909455918152600190915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000828211156151c557fe5b50900390565b600081815260016020526040902054600160a060020a0316156151ed57600080fd5b6000818152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038816908117909155845260039091529091205461523b91614ee1565b600160a060020a0390921660009081526003602052604090209190915550565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6152ac8282615605565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b6152fa82612a33565b151561530557600080fd5b6000828152600b602090815260409091208251612844928401906156d8565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f191660200182016040528015615385578160200160208202803883390190505b50935083925060009150600090505b885181101561540a5788818151811015156153ab57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156153d257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615394565b5060005b875181101561548457878181518110151561542557fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561544c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161540e565b5060005b86518110156154fe57868181518110151561549f57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156154c657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615488565b5060005b855181101561557857858181518110151561551957fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561554057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615502565b5060005b84518110156155f257848181518110151561559357fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156155ba57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161557c565b50909d9c50505050505050505050505050565b600160a060020a038216151561561a57600080fd5b6156248282614c7d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60408051610100810182526000808252606060208301819052928201819052918101829052608081018290529060a0820190815260200160008152602001600081525090565b6080604051908101604052806000600160a060020a031681526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061571957805160ff1916838001178555615746565b82800160010185558215615746579182015b8281111561574657825182559160200191906001019061572b565b506157529291506157e4565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106157975782800160ff19823516178555615746565b82800160010185558215615746579182015b828111156157465782358255916020019190600101906157a9565b815481835581811115612844576000838152602090206128449181019083015b61118891905b8082111561575257600081556001016157ea560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a72305820610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e390029

Swarm Source

bzzr://610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e39
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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