ETH Price: $2,643.39 (+1.06%)

Token

Azimuth Points (AZP)
 

Overview

Max Total Supply

0 AZP

Holders

0

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
0 AZP
0x4aac01e3d31c7281e5a330701c783d3ac2c6162b
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:
Ecliptic

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

//  the azimuth logic contract
//  https://azimuth.network

pragma solidity 0.4.24;

////////////////////////////////////////////////////////////////////////////////
//  Imports
////////////////////////////////////////////////////////////////////////////////

// OpenZeppelin's 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;
  }
}

// Azimuth's SafeMath8.sol

/**
 * @title SafeMath8
 * @dev Math operations for uint8 with safety checks that throw on error
 */
library SafeMath8 {
  function mul(uint8 a, uint8 b) internal pure returns (uint8) {
    uint8 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

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

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

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

// Azimuth's SafeMath16.sol

/**
 * @title SafeMath16
 * @dev Math operations for uint16 with safety checks that throw on error
 */
library SafeMath16 {
  function mul(uint16 a, uint16 b) internal pure returns (uint16) {
    uint16 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

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

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

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

// OpenZeppelin's 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;
  }
}

// OpenZeppelin's 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);
}

// OpenZeppelin's 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;
  }
}

// OpenZeppelin's 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;
}

// OpenZeppelin's 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 {
}

// OpenZeppelin's 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);
}

// OpenZeppelin's 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;
  }

}

// Azimuth's Azimuth.sol

//  Azimuth: point state data contract
//
//    This contract is used for storing all data related to Azimuth points
//    and their ownership. Consider this contract the Azimuth ledger.
//
//    It also contains permissions data, which ties in to ERC721
//    functionality. Operators of an address are allowed to transfer
//    ownership of all points owned by their associated address
//    (ERC721's approveAll()). A transfer proxy is allowed to transfer
//    ownership of a single point (ERC721's approve()).
//    Separate from ERC721 are managers, assigned per point. They are
//    allowed to perform "low-impact" operations on the owner's points,
//    like configuring public keys and making escape requests.
//
//    Since data stores are difficult to upgrade, this contract contains
//    as little actual business logic as possible. Instead, the data stored
//    herein can only be modified by this contract's owner, which can be
//    changed and is thus upgradable/replaceable.
//
//    This contract will be owned by the Ecliptic contract.
//
contract Azimuth is Ownable
{
//
//  Events
//

  //  OwnerChanged: :point is now owned by :owner
  //
  event OwnerChanged(uint32 indexed point, address indexed owner);

  //  Activated: :point is now active
  //
  event Activated(uint32 indexed point);

  //  Spawned: :prefix has spawned :child
  //
  event Spawned(uint32 indexed prefix, uint32 indexed child);

  //  EscapeRequested: :point has requested a new :sponsor
  //
  event EscapeRequested(uint32 indexed point, uint32 indexed sponsor);

  //  EscapeCanceled: :point's :sponsor request was canceled or rejected
  //
  event EscapeCanceled(uint32 indexed point, uint32 indexed sponsor);

  //  EscapeAccepted: :point confirmed with a new :sponsor
  //
  event EscapeAccepted(uint32 indexed point, uint32 indexed sponsor);

  //  LostSponsor: :point's :sponsor is now refusing it service
  //
  event LostSponsor(uint32 indexed point, uint32 indexed sponsor);

  //  ChangedKeys: :point has new network public keys
  //
  event ChangedKeys( uint32 indexed point,
                     bytes32 encryptionKey,
                     bytes32 authenticationKey,
                     uint32 cryptoSuiteVersion,
                     uint32 keyRevisionNumber );

  //  BrokeContinuity: :point has a new continuity number, :number
  //
  event BrokeContinuity(uint32 indexed point, uint32 number);

  //  ChangedSpawnProxy: :spawnProxy can now spawn using :point
  //
  event ChangedSpawnProxy(uint32 indexed point, address indexed spawnProxy);

  //  ChangedTransferProxy: :transferProxy can now transfer ownership of :point
  //
  event ChangedTransferProxy( uint32 indexed point,
                              address indexed transferProxy );

  //  ChangedManagementProxy: :managementProxy can now manage :point
  //
  event ChangedManagementProxy( uint32 indexed point,
                                address indexed managementProxy );

  //  ChangedVotingProxy: :votingProxy can now vote using :point
  //
  event ChangedVotingProxy(uint32 indexed point, address indexed votingProxy);

  //  ChangedDns: dnsDomains have been updated
  //
  event ChangedDns(string primary, string secondary, string tertiary);

//
//  Structures
//

  //  Size: kinds of points registered on-chain
  //
  //    NOTE: the order matters, because of Solidity enum numbering
  //
  enum Size
  {
    Galaxy, // = 0
    Star,   // = 1
    Planet  // = 2
  }

  //  Point: state of a point
  //
  //    While the ordering of the struct members is semantically chaotic,
  //    they are ordered to tightly pack them into Ethereum's 32-byte storage
  //    slots, which reduces gas costs for some function calls.
  //    The comment ticks indicate assumed slot boundaries.
  //
  struct Point
  {
    //  encryptionKey: (curve25519) encryption public key, or 0 for none
    //
    bytes32 encryptionKey;
  //
    //  authenticationKey: (ed25519) authentication public key, or 0 for none
    //
    bytes32 authenticationKey;
  //
    //  spawned: for stars and galaxies, all :active children
    //
    uint32[] spawned;
  //
    //  hasSponsor: true if the sponsor still supports the point
    //
    bool hasSponsor;

    //  active: whether point can be linked
    //
    //    false: point belongs to prefix, cannot be configured or linked
    //    true: point no longer belongs to prefix, can be configured and linked
    //
    bool active;

    //  escapeRequested: true if the point has requested to change sponsors
    //
    bool escapeRequested;

    //  sponsor: the point that supports this one on the network, or,
    //           if :hasSponsor is false, the last point that supported it.
    //           (by default, the point's half-width prefix)
    //
    uint32 sponsor;

    //  escapeRequestedTo: if :escapeRequested is true, new sponsor requested
    //
    uint32 escapeRequestedTo;

    //  cryptoSuiteVersion: version of the crypto suite used for the pubkeys
    //
    uint32 cryptoSuiteVersion;

    //  keyRevisionNumber: incremented every time the public keys change
    //
    uint32 keyRevisionNumber;

    //  continuityNumber: incremented to indicate network-side state loss
    //
    uint32 continuityNumber;
  }

  //  Deed: permissions for a point
  //
  struct Deed
  {
    //  owner: address that owns this point
    //
    address owner;

    //  managementProxy: 0, or another address with the right to perform
    //                   low-impact, managerial operations on this point
    //
    address managementProxy;

    //  spawnProxy: 0, or another address with the right to spawn children
    //              of this point
    //
    address spawnProxy;

    //  votingProxy: 0, or another address with the right to vote as this point
    //
    address votingProxy;

    //  transferProxy: 0, or another address with the right to transfer
    //                 ownership of this point
    //
    address transferProxy;
  }

//
//  General state
//

  //  points: per point, general network-relevant point state
  //
  mapping(uint32 => Point) public points;

  //  rights: per point, on-chain ownership and permissions
  //
  mapping(uint32 => Deed) public rights;

  //  operators: per owner, per address, has the right to transfer ownership
  //             of all the owner's points (ERC721)
  //
  mapping(address => mapping(address => bool)) public operators;

  //  dnsDomains: base domains for contacting galaxies
  //
  //    dnsDomains[0] is primary, the others are used as fallbacks
  //
  string[3] public dnsDomains;

//
//  Lookups
//

  //  sponsoring: per point, the points they are sponsoring
  //
  mapping(uint32 => uint32[]) public sponsoring;

  //  sponsoringIndexes: per point, per point, (index + 1) in
  //                     the sponsoring array
  //
  mapping(uint32 => mapping(uint32 => uint256)) public sponsoringIndexes;

  //  escapeRequests: per point, the points they have open escape requests from
  //
  mapping(uint32 => uint32[]) public escapeRequests;

  //  escapeRequestsIndexes: per point, per point, (index + 1) in
  //                         the escapeRequests array
  //
  mapping(uint32 => mapping(uint32 => uint256)) public escapeRequestsIndexes;

  //  pointsOwnedBy: per address, the points they own
  //
  mapping(address => uint32[]) public pointsOwnedBy;

  //  pointOwnerIndexes: per owner, per point, (index + 1) in
  //                     the pointsOwnedBy array
  //
  //    We delete owners by moving the last entry in the array to the
  //    newly emptied slot, which is (n - 1) where n is the value of
  //    pointOwnerIndexes[owner][point].
  //
  mapping(address => mapping(uint32 => uint256)) public pointOwnerIndexes;

  //  managerFor: per address, the points they are the management proxy for
  //
  mapping(address => uint32[]) public managerFor;

  //  managerForIndexes: per address, per point, (index + 1) in
  //                     the managerFor array
  //
  mapping(address => mapping(uint32 => uint256)) public managerForIndexes;

  //  spawningFor: per address, the points they can spawn with
  //
  mapping(address => uint32[]) public spawningFor;

  //  spawningForIndexes: per address, per point, (index + 1) in
  //                      the spawningFor array
  //
  mapping(address => mapping(uint32 => uint256)) public spawningForIndexes;

  //  votingFor: per address, the points they can vote with
  //
  mapping(address => uint32[]) public votingFor;

  //  votingForIndexes: per address, per point, (index + 1) in
  //                    the votingFor array
  //
  mapping(address => mapping(uint32 => uint256)) public votingForIndexes;

  //  transferringFor: per address, the points they can transfer
  //
  mapping(address => uint32[]) public transferringFor;

  //  transferringForIndexes: per address, per point, (index + 1) in
  //                          the transferringFor array
  //
  mapping(address => mapping(uint32 => uint256)) public transferringForIndexes;

//
//  Logic
//

  //  constructor(): configure default dns domains
  //
  constructor()
    public
  {
    setDnsDomains("example.com", "example.com", "example.com");
  }

  //  setDnsDomains(): set the base domains used for contacting galaxies
  //
  //    Note: since a string is really just a byte[], and Solidity can't
  //    work with two-dimensional arrays yet, we pass in the three
  //    domains as individual strings.
  //
  function setDnsDomains(string _primary, string _secondary, string _tertiary)
    onlyOwner
    public
  {
    dnsDomains[0] = _primary;
    dnsDomains[1] = _secondary;
    dnsDomains[2] = _tertiary;
    emit ChangedDns(_primary, _secondary, _tertiary);
  }

  //
  //  Point reading
  //

    //  isActive(): return true if _point is active
    //
    function isActive(uint32 _point)
      view
      external
      returns (bool equals)
    {
      return points[_point].active;
    }

    //  getKeys(): returns the public keys and their details, as currently
    //             registered for _point
    //
    function getKeys(uint32 _point)
      view
      external
      returns (bytes32 crypt, bytes32 auth, uint32 suite, uint32 revision)
    {
      Point storage point = points[_point];
      return (point.encryptionKey,
              point.authenticationKey,
              point.cryptoSuiteVersion,
              point.keyRevisionNumber);
    }

    //  getKeyRevisionNumber(): gets the revision number of _point's current
    //                          public keys
    //
    function getKeyRevisionNumber(uint32 _point)
      view
      external
      returns (uint32 revision)
    {
      return points[_point].keyRevisionNumber;
    }

    //  hasBeenLinked(): returns true if the point has ever been assigned keys
    //
    function hasBeenLinked(uint32 _point)
      view
      external
      returns (bool result)
    {
      return ( points[_point].keyRevisionNumber > 0 );
    }

    //  isLive(): returns true if _point currently has keys properly configured
    //
    function isLive(uint32 _point)
      view
      external
      returns (bool result)
    {
      Point storage point = points[_point];
      return ( point.encryptionKey != 0 &&
               point.authenticationKey != 0 &&
               point.cryptoSuiteVersion != 0 );
    }

    //  getContinuityNumber(): returns _point's current continuity number
    //
    function getContinuityNumber(uint32 _point)
      view
      external
      returns (uint32 continuityNumber)
    {
      return points[_point].continuityNumber;
    }

    //  getSpawnCount(): return the number of children spawned by _point
    //
    function getSpawnCount(uint32 _point)
      view
      external
      returns (uint32 spawnCount)
    {
      uint256 len = points[_point].spawned.length;
      assert(len < 2**32);
      return uint32(len);
    }

    //  getSpawned(): return array of points created under _point
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getSpawned(uint32 _point)
      view
      external
      returns (uint32[] spawned)
    {
      return points[_point].spawned;
    }

    //  hasSponsor(): returns true if _point's sponsor is providing it service
    //
    function hasSponsor(uint32 _point)
      view
      external
      returns (bool has)
    {
      return points[_point].hasSponsor;
    }

    //  getSponsor(): returns _point's current (or most recent) sponsor
    //
    function getSponsor(uint32 _point)
      view
      external
      returns (uint32 sponsor)
    {
      return points[_point].sponsor;
    }

    //  isSponsor(): returns true if _sponsor is currently providing service
    //               to _point
    //
    function isSponsor(uint32 _point, uint32 _sponsor)
      view
      external
      returns (bool result)
    {
      Point storage point = points[_point];
      return ( point.hasSponsor &&
               (point.sponsor == _sponsor) );
    }

    //  getSponsoringCount(): returns the number of points _sponsor is
    //                        providing service to
    //
    function getSponsoringCount(uint32 _sponsor)
      view
      external
      returns (uint256 count)
    {
      return sponsoring[_sponsor].length;
    }

    //  getSponsoring(): returns a list of points _sponsor is providing
    //                   service to
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getSponsoring(uint32 _sponsor)
      view
      external
      returns (uint32[] sponsees)
    {
      return sponsoring[_sponsor];
    }

    //  escaping

    //  isEscaping(): returns true if _point has an outstanding escape request
    //
    function isEscaping(uint32 _point)
      view
      external
      returns (bool escaping)
    {
      return points[_point].escapeRequested;
    }

    //  getEscapeRequest(): returns _point's current escape request
    //
    //    the returned escape request is only valid as long as isEscaping()
    //    returns true
    //
    function getEscapeRequest(uint32 _point)
      view
      external
      returns (uint32 escape)
    {
      return points[_point].escapeRequestedTo;
    }

    //  isRequestingEscapeTo(): returns true if _point has an outstanding
    //                          escape request targetting _sponsor
    //
    function isRequestingEscapeTo(uint32 _point, uint32 _sponsor)
      view
      public
      returns (bool equals)
    {
      Point storage point = points[_point];
      return (point.escapeRequested && (point.escapeRequestedTo == _sponsor));
    }

    //  getEscapeRequestsCount(): returns the number of points _sponsor
    //                            is providing service to
    //
    function getEscapeRequestsCount(uint32 _sponsor)
      view
      external
      returns (uint256 count)
    {
      return escapeRequests[_sponsor].length;
    }

    //  getEscapeRequests(): get the points _sponsor has received escape
    //                       requests from
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getEscapeRequests(uint32 _sponsor)
      view
      external
      returns (uint32[] requests)
    {
      return escapeRequests[_sponsor];
    }

  //
  //  Point writing
  //

    //  activatePoint(): activate a point, register it as spawned by its prefix
    //
    function activatePoint(uint32 _point)
      onlyOwner
      external
    {
      //  make a point active, setting its sponsor to its prefix
      //
      Point storage point = points[_point];
      require(!point.active);
      point.active = true;
      registerSponsor(_point, true, getPrefix(_point));
      emit Activated(_point);
    }

    //  setKeys(): set network public keys of _point to _encryptionKey and
    //            _authenticationKey, with the specified _cryptoSuiteVersion
    //
    function setKeys(uint32 _point,
                     bytes32 _encryptionKey,
                     bytes32 _authenticationKey,
                     uint32 _cryptoSuiteVersion)
      onlyOwner
      external
    {
      Point storage point = points[_point];
      if ( point.encryptionKey == _encryptionKey &&
           point.authenticationKey == _authenticationKey &&
           point.cryptoSuiteVersion == _cryptoSuiteVersion )
      {
        return;
      }

      point.encryptionKey = _encryptionKey;
      point.authenticationKey = _authenticationKey;
      point.cryptoSuiteVersion = _cryptoSuiteVersion;
      point.keyRevisionNumber++;

      emit ChangedKeys(_point,
                       _encryptionKey,
                       _authenticationKey,
                       _cryptoSuiteVersion,
                       point.keyRevisionNumber);
    }

    //  incrementContinuityNumber(): break continuity for _point
    //
    function incrementContinuityNumber(uint32 _point)
      onlyOwner
      external
    {
      Point storage point = points[_point];
      point.continuityNumber++;
      emit BrokeContinuity(_point, point.continuityNumber);
    }

    //  registerSpawn(): add a point to its prefix's list of spawned points
    //
    function registerSpawned(uint32 _point)
      onlyOwner
      external
    {
      //  if a point is its own prefix (a galaxy) then don't register it
      //
      uint32 prefix = getPrefix(_point);
      if (prefix == _point)
      {
        return;
      }

      //  register a new spawned point for the prefix
      //
      points[prefix].spawned.push(_point);
      emit Spawned(prefix, _point);
    }

    //  loseSponsor(): indicates that _point's sponsor is no longer providing
    //                 it service
    //
    function loseSponsor(uint32 _point)
      onlyOwner
      external
    {
      Point storage point = points[_point];
      if (!point.hasSponsor)
      {
        return;
      }
      registerSponsor(_point, false, point.sponsor);
      emit LostSponsor(_point, point.sponsor);
    }

    //  setEscapeRequest(): for _point, start an escape request to _sponsor
    //
    function setEscapeRequest(uint32 _point, uint32 _sponsor)
      onlyOwner
      external
    {
      if (isRequestingEscapeTo(_point, _sponsor))
      {
        return;
      }
      registerEscapeRequest(_point, true, _sponsor);
      emit EscapeRequested(_point, _sponsor);
    }

    //  cancelEscape(): for _point, stop the current escape request, if any
    //
    function cancelEscape(uint32 _point)
      onlyOwner
      external
    {
      Point storage point = points[_point];
      if (!point.escapeRequested)
      {
        return;
      }
      uint32 request = point.escapeRequestedTo;
      registerEscapeRequest(_point, false, 0);
      emit EscapeCanceled(_point, request);
    }

    //  doEscape(): perform the requested escape
    //
    function doEscape(uint32 _point)
      onlyOwner
      external
    {
      Point storage point = points[_point];
      require(point.escapeRequested);
      registerSponsor(_point, true, point.escapeRequestedTo);
      registerEscapeRequest(_point, false, 0);
      emit EscapeAccepted(_point, point.sponsor);
    }

  //
  //  Point utils
  //

    //  getPrefix(): compute prefix ("parent") of _point
    //
    function getPrefix(uint32 _point)
      pure
      public
      returns (uint16 prefix)
    {
      if (_point < 0x10000)
      {
        return uint16(_point % 0x100);
      }
      return uint16(_point % 0x10000);
    }

    //  getPointSize(): return the size of _point
    //
    function getPointSize(uint32 _point)
      external
      pure
      returns (Size _size)
    {
      if (_point < 0x100) return Size.Galaxy;
      if (_point < 0x10000) return Size.Star;
      return Size.Planet;
    }

    //  internal use

    //  registerSponsor(): set the sponsorship state of _point and update the
    //                     reverse lookup for sponsors
    //
    function registerSponsor(uint32 _point, bool _hasSponsor, uint32 _sponsor)
      internal
    {
      Point storage point = points[_point];
      bool had = point.hasSponsor;
      uint32 prev = point.sponsor;

      //  if we didn't have a sponsor, and won't get one,
      //  or if we get the sponsor we already have,
      //  nothing will change, so jump out early.
      //
      if ( (!had && !_hasSponsor) ||
           (had && _hasSponsor && prev == _sponsor) )
      {
        return;
      }

      //  if the point used to have a different sponsor, do some gymnastics
      //  to keep the reverse lookup gapless.  delete the point from the old
      //  sponsor's list, then fill that gap with the list tail.
      //
      if (had)
      {
        //  i: current index in previous sponsor's list of sponsored points
        //
        uint256 i = sponsoringIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :sponsoringIndexes reference
        //
        uint32[] storage prevSponsoring = sponsoring[prev];
        uint256 last = prevSponsoring.length - 1;
        uint32 moved = prevSponsoring[last];
        prevSponsoring[i] = moved;
        sponsoringIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevSponsoring[last]);
        prevSponsoring.length = last;
        sponsoringIndexes[prev][_point] = 0;
      }

      if (_hasSponsor)
      {
        uint32[] storage newSponsoring = sponsoring[_sponsor];
        newSponsoring.push(_point);
        sponsoringIndexes[_sponsor][_point] = newSponsoring.length;
      }

      point.sponsor = _sponsor;
      point.hasSponsor = _hasSponsor;
    }

    //  registerEscapeRequest(): set the escape state of _point and update the
    //                           reverse lookup for sponsors
    //
    function registerEscapeRequest( uint32 _point,
                                    bool _isEscaping, uint32 _sponsor )
      internal
    {
      Point storage point = points[_point];
      bool was = point.escapeRequested;
      uint32 prev = point.escapeRequestedTo;

      //  if we weren't escaping, and won't be,
      //  or if we were escaping, and the new target is the same,
      //  nothing will change, so jump out early.
      //
      if ( (!was && !_isEscaping) ||
           (was && _isEscaping && prev == _sponsor) )
      {
        return;
      }

      //  if the point used to have a different request, do some gymnastics
      //  to keep the reverse lookup gapless.  delete the point from the old
      //  sponsor's list, then fill that gap with the list tail.
      //
      if (was)
      {
        //  i: current index in previous sponsor's list of sponsored points
        //
        uint256 i = escapeRequestsIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :escapeRequestsIndexes reference
        //
        uint32[] storage prevRequests = escapeRequests[prev];
        uint256 last = prevRequests.length - 1;
        uint32 moved = prevRequests[last];
        prevRequests[i] = moved;
        escapeRequestsIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevRequests[last]);
        prevRequests.length = last;
        escapeRequestsIndexes[prev][_point] = 0;
      }

      if (_isEscaping)
      {
        uint32[] storage newRequests = escapeRequests[_sponsor];
        newRequests.push(_point);
        escapeRequestsIndexes[_sponsor][_point] = newRequests.length;
      }

      point.escapeRequestedTo = _sponsor;
      point.escapeRequested = _isEscaping;
    }

  //
  //  Deed reading
  //

    //  owner

    //  getOwner(): return owner of _point
    //
    function getOwner(uint32 _point)
      view
      external
      returns (address owner)
    {
      return rights[_point].owner;
    }

    //  isOwner(): true if _point is owned by _address
    //
    function isOwner(uint32 _point, address _address)
      view
      external
      returns (bool result)
    {
      return (rights[_point].owner == _address);
    }

    //  getOwnedPointCount(): return length of array of points that _whose owns
    //
    function getOwnedPointCount(address _whose)
      view
      external
      returns (uint256 count)
    {
      return pointsOwnedBy[_whose].length;
    }

    //  getOwnedPoints(): return array of points that _whose owns
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getOwnedPoints(address _whose)
      view
      external
      returns (uint32[] ownedPoints)
    {
      return pointsOwnedBy[_whose];
    }

    //  getOwnedPointAtIndex(): get point at _index from array of points that
    //                         _whose owns
    //
    function getOwnedPointAtIndex(address _whose, uint256 _index)
      view
      external
      returns (uint32 point)
    {
      uint32[] storage owned = pointsOwnedBy[_whose];
      require(_index < owned.length);
      return owned[_index];
    }

    //  management proxy

    //  getManagementProxy(): returns _point's current management proxy
    //
    function getManagementProxy(uint32 _point)
      view
      external
      returns (address manager)
    {
      return rights[_point].managementProxy;
    }

    //  isManagementProxy(): returns true if _proxy is _point's management proxy
    //
    function isManagementProxy(uint32 _point, address _proxy)
      view
      external
      returns (bool result)
    {
      return (rights[_point].managementProxy == _proxy);
    }

    //  canManage(): true if _who is the owner or manager of _point
    //
    function canManage(uint32 _point, address _who)
      view
      external
      returns (bool result)
    {
      Deed storage deed = rights[_point];
      return ( (0x0 != _who) &&
               ( (_who == deed.owner) ||
                 (_who == deed.managementProxy) ) );
    }

    //  getManagerForCount(): returns the amount of points _proxy can manage
    //
    function getManagerForCount(address _proxy)
      view
      external
      returns (uint256 count)
    {
      return managerFor[_proxy].length;
    }

    //  getManagerFor(): returns the points _proxy can manage
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getManagerFor(address _proxy)
      view
      external
      returns (uint32[] mfor)
    {
      return managerFor[_proxy];
    }

    //  spawn proxy

    //  getSpawnProxy(): returns _point's current spawn proxy
    //
    function getSpawnProxy(uint32 _point)
      view
      external
      returns (address spawnProxy)
    {
      return rights[_point].spawnProxy;
    }

    //  isSpawnProxy(): returns true if _proxy is _point's spawn proxy
    //
    function isSpawnProxy(uint32 _point, address _proxy)
      view
      external
      returns (bool result)
    {
      return (rights[_point].spawnProxy == _proxy);
    }

    //  canSpawnAs(): true if _who is the owner or spawn proxy of _point
    //
    function canSpawnAs(uint32 _point, address _who)
      view
      external
      returns (bool result)
    {
      Deed storage deed = rights[_point];
      return ( (0x0 != _who) &&
               ( (_who == deed.owner) ||
                 (_who == deed.spawnProxy) ) );
    }

    //  getSpawningForCount(): returns the amount of points _proxy
    //                         can spawn with
    //
    function getSpawningForCount(address _proxy)
      view
      external
      returns (uint256 count)
    {
      return spawningFor[_proxy].length;
    }

    //  getSpawningFor(): get the points _proxy can spawn with
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getSpawningFor(address _proxy)
      view
      external
      returns (uint32[] sfor)
    {
      return spawningFor[_proxy];
    }

    //  voting proxy

    //  getVotingProxy(): returns _point's current voting proxy
    //
    function getVotingProxy(uint32 _point)
      view
      external
      returns (address voter)
    {
      return rights[_point].votingProxy;
    }

    //  isVotingProxy(): returns true if _proxy is _point's voting proxy
    //
    function isVotingProxy(uint32 _point, address _proxy)
      view
      external
      returns (bool result)
    {
      return (rights[_point].votingProxy == _proxy);
    }

    //  canVoteAs(): true if _who is the owner of _point,
    //               or the voting proxy of _point's owner
    //
    function canVoteAs(uint32 _point, address _who)
      view
      external
      returns (bool result)
    {
      Deed storage deed = rights[_point];
      return ( (0x0 != _who) &&
               ( (_who == deed.owner) ||
                 (_who == deed.votingProxy) ) );
    }

    //  getVotingForCount(): returns the amount of points _proxy can vote as
    //
    function getVotingForCount(address _proxy)
      view
      external
      returns (uint256 count)
    {
      return votingFor[_proxy].length;
    }

    //  getVotingFor(): returns the points _proxy can vote as
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getVotingFor(address _proxy)
      view
      external
      returns (uint32[] vfor)
    {
      return votingFor[_proxy];
    }

    //  transfer proxy

    //  getTransferProxy(): returns _point's current transfer proxy
    //
    function getTransferProxy(uint32 _point)
      view
      external
      returns (address transferProxy)
    {
      return rights[_point].transferProxy;
    }

    //  isTransferProxy(): returns true if _proxy is _point's transfer proxy
    //
    function isTransferProxy(uint32 _point, address _proxy)
      view
      external
      returns (bool result)
    {
      return (rights[_point].transferProxy == _proxy);
    }

    //  canTransfer(): true if _who is the owner or transfer proxy of _point,
    //                 or is an operator for _point's current owner
    //
    function canTransfer(uint32 _point, address _who)
      view
      external
      returns (bool result)
    {
      Deed storage deed = rights[_point];
      return ( (0x0 != _who) &&
               ( (_who == deed.owner) ||
                 (_who == deed.transferProxy) ||
                 operators[deed.owner][_who] ) );
    }

    //  getTransferringForCount(): returns the amount of points _proxy
    //                             can transfer
    //
    function getTransferringForCount(address _proxy)
      view
      external
      returns (uint256 count)
    {
      return transferringFor[_proxy].length;
    }

    //  getTransferringFor(): get the points _proxy can transfer
    //
    //    Note: only useful for clients, as Solidity does not currently
    //    support returning dynamic arrays.
    //
    function getTransferringFor(address _proxy)
      view
      external
      returns (uint32[] tfor)
    {
      return transferringFor[_proxy];
    }

    //  isOperator(): returns true if _operator is allowed to transfer
    //                ownership of _owner's points
    //
    function isOperator(address _owner, address _operator)
      view
      external
      returns (bool result)
    {
      return operators[_owner][_operator];
    }

  //
  //  Deed writing
  //

    //  setOwner(): set owner of _point to _owner
    //
    //    Note: setOwner() only implements the minimal data storage
    //    logic for a transfer; the full transfer is implemented in
    //    Ecliptic.
    //
    //    Note: _owner must not be the zero address.
    //
    function setOwner(uint32 _point, address _owner)
      onlyOwner
      external
    {
      //  prevent burning of points by making zero the owner
      //
      require(0x0 != _owner);

      //  prev: previous owner, if any
      //
      address prev = rights[_point].owner;

      if (prev == _owner)
      {
        return;
      }

      //  if the point used to have a different owner, do some gymnastics to
      //  keep the list of owned points gapless.  delete this point from the
      //  list, then fill that gap with the list tail.
      //
      if (0x0 != prev)
      {
        //  i: current index in previous owner's list of owned points
        //
        uint256 i = pointOwnerIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :pointOwnerIndexes reference
        //
        uint32[] storage owner = pointsOwnedBy[prev];
        uint256 last = owner.length - 1;
        uint32 moved = owner[last];
        owner[i] = moved;
        pointOwnerIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(owner[last]);
        owner.length = last;
        pointOwnerIndexes[prev][_point] = 0;
      }

      //  update the owner list and the owner's index list
      //
      rights[_point].owner = _owner;
      pointsOwnedBy[_owner].push(_point);
      pointOwnerIndexes[_owner][_point] = pointsOwnedBy[_owner].length;
      emit OwnerChanged(_point, _owner);
    }

    //  setManagementProxy(): makes _proxy _point's management proxy
    //
    function setManagementProxy(uint32 _point, address _proxy)
      onlyOwner
      external
    {
      Deed storage deed = rights[_point];
      address prev = deed.managementProxy;
      if (prev == _proxy)
      {
        return;
      }

      //  if the point used to have a different manager, do some gymnastics
      //  to keep the reverse lookup gapless.  delete the point from the
      //  old manager's list, then fill that gap with the list tail.
      //
      if (0x0 != prev)
      {
        //  i: current index in previous manager's list of managed points
        //
        uint256 i = managerForIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :managerForIndexes reference
        //
        uint32[] storage prevMfor = managerFor[prev];
        uint256 last = prevMfor.length - 1;
        uint32 moved = prevMfor[last];
        prevMfor[i] = moved;
        managerForIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevMfor[last]);
        prevMfor.length = last;
        managerForIndexes[prev][_point] = 0;
      }

      if (0x0 != _proxy)
      {
        uint32[] storage mfor = managerFor[_proxy];
        mfor.push(_point);
        managerForIndexes[_proxy][_point] = mfor.length;
      }

      deed.managementProxy = _proxy;
      emit ChangedManagementProxy(_point, _proxy);
    }

    //  setSpawnProxy(): makes _proxy _point's spawn proxy
    //
    function setSpawnProxy(uint32 _point, address _proxy)
      onlyOwner
      external
    {
      Deed storage deed = rights[_point];
      address prev = deed.spawnProxy;
      if (prev == _proxy)
      {
        return;
      }

      //  if the point used to have a different spawn proxy, do some
      //  gymnastics to keep the reverse lookup gapless.  delete the point
      //  from the old proxy's list, then fill that gap with the list tail.
      //
      if (0x0 != prev)
      {
        //  i: current index in previous proxy's list of spawning points
        //
        uint256 i = spawningForIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :spawningForIndexes reference
        //
        uint32[] storage prevSfor = spawningFor[prev];
        uint256 last = prevSfor.length - 1;
        uint32 moved = prevSfor[last];
        prevSfor[i] = moved;
        spawningForIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevSfor[last]);
        prevSfor.length = last;
        spawningForIndexes[prev][_point] = 0;
      }

      if (0x0 != _proxy)
      {
        uint32[] storage sfor = spawningFor[_proxy];
        sfor.push(_point);
        spawningForIndexes[_proxy][_point] = sfor.length;
      }

      deed.spawnProxy = _proxy;
      emit ChangedSpawnProxy(_point, _proxy);
    }

    //  setVotingProxy(): makes _proxy _point's voting proxy
    //
    function setVotingProxy(uint32 _point, address _proxy)
      onlyOwner
      external
    {
      Deed storage deed = rights[_point];
      address prev = deed.votingProxy;
      if (prev == _proxy)
      {
        return;
      }

      //  if the point used to have a different voter, do some gymnastics
      //  to keep the reverse lookup gapless.  delete the point from the
      //  old voter's list, then fill that gap with the list tail.
      //
      if (0x0 != prev)
      {
        //  i: current index in previous voter's list of points it was
        //     voting for
        //
        uint256 i = votingForIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :votingForIndexes reference
        //
        uint32[] storage prevVfor = votingFor[prev];
        uint256 last = prevVfor.length - 1;
        uint32 moved = prevVfor[last];
        prevVfor[i] = moved;
        votingForIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevVfor[last]);
        prevVfor.length = last;
        votingForIndexes[prev][_point] = 0;
      }

      if (0x0 != _proxy)
      {
        uint32[] storage vfor = votingFor[_proxy];
        vfor.push(_point);
        votingForIndexes[_proxy][_point] = vfor.length;
      }

      deed.votingProxy = _proxy;
      emit ChangedVotingProxy(_point, _proxy);
    }

    //  setManagementProxy(): makes _proxy _point's transfer proxy
    //
    function setTransferProxy(uint32 _point, address _proxy)
      onlyOwner
      external
    {
      Deed storage deed = rights[_point];
      address prev = deed.transferProxy;
      if (prev == _proxy)
      {
        return;
      }

      //  if the point used to have a different transfer proxy, do some
      //  gymnastics to keep the reverse lookup gapless.  delete the point
      //  from the old proxy's list, then fill that gap with the list tail.
      //
      if (0x0 != prev)
      {
        //  i: current index in previous proxy's list of transferable points
        //
        uint256 i = transferringForIndexes[prev][_point];

        //  we store index + 1, because 0 is the solidity default value
        //
        assert(i > 0);
        i--;

        //  copy the last item in the list into the now-unused slot,
        //  making sure to update its :transferringForIndexes reference
        //
        uint32[] storage prevTfor = transferringFor[prev];
        uint256 last = prevTfor.length - 1;
        uint32 moved = prevTfor[last];
        prevTfor[i] = moved;
        transferringForIndexes[prev][moved] = i + 1;

        //  delete the last item
        //
        delete(prevTfor[last]);
        prevTfor.length = last;
        transferringForIndexes[prev][_point] = 0;
      }

      if (0x0 != _proxy)
      {
        uint32[] storage tfor = transferringFor[_proxy];
        tfor.push(_point);
        transferringForIndexes[_proxy][_point] = tfor.length;
      }

      deed.transferProxy = _proxy;
      emit ChangedTransferProxy(_point, _proxy);
    }

    //  setOperator(): dis/allow _operator to transfer ownership of all points
    //                 owned by _owner
    //
    //    operators are part of the ERC721 standard
    //
    function setOperator(address _owner, address _operator, bool _approved)
      onlyOwner
      external
    {
      operators[_owner][_operator] = _approved;
    }
}

// Azimuth's ReadsAzimuth.sol

//  ReadsAzimuth: referring to and testing against the Azimuth
//                data contract
//
//    To avoid needless repetition, this contract provides common
//    checks and operations using the Azimuth contract.
//
contract ReadsAzimuth
{
  //  azimuth: points data storage contract.
  //
  Azimuth public azimuth;

  //  constructor(): set the Azimuth data contract's address
  //
  constructor(Azimuth _azimuth)
    public
  {
    azimuth = _azimuth;
  }

  //  activePointOwner(): require that :msg.sender is the owner of _point,
  //                      and that _point is active
  //
  modifier activePointOwner(uint32 _point)
  {
    require( azimuth.isOwner(_point, msg.sender) &&
             azimuth.isActive(_point) );
    _;
  }

  //  activePointManager(): require that :msg.sender can manage _point,
  //                        and that _point is active
  //
  modifier activePointManager(uint32 _point)
  {
    require( azimuth.canManage(_point, msg.sender) &&
             azimuth.isActive(_point) );
    _;
  }
}

// Azimuth's Polls.sol

//  Polls: proposals & votes data contract
//
//    This contract is used for storing all data related to the proposals
//    of the senate (galaxy owners) and their votes on those proposals.
//    It keeps track of votes and uses them to calculate whether a majority
//    is in favor of a proposal.
//
//    Every galaxy can only vote on a proposal exactly once. Votes cannot
//    be changed. If a proposal fails to achieve majority within its
//    duration, it can be restarted after its cooldown period has passed.
//
//    The requirements for a proposal to achieve majority are as follows:
//    - At least 1/4 of the currently active voters (rounded down) must have
//      voted in favor of the proposal,
//    - More than half of the votes cast must be in favor of the proposal,
//      and this can no longer change, either because
//      - the poll duration has passed, or
//      - not enough voters remain to take away the in-favor majority.
//    As soon as these conditions are met, no further interaction with
//    the proposal is possible. Achieving majority is permanent.
//
//    Since data stores are difficult to upgrade, all of the logic unrelated
//    to the voting itself (that is, determining who is eligible to vote)
//    is expected to be implemented by this contract's owner.
//
//    This contract will be owned by the Ecliptic contract.
//
contract Polls is Ownable
{
  using SafeMath for uint256;
  using SafeMath16 for uint16;
  using SafeMath8 for uint8;

  //  UpgradePollStarted: a poll on :proposal has opened
  //
  event UpgradePollStarted(address proposal);

  //  DocumentPollStarted: a poll on :proposal has opened
  //
  event DocumentPollStarted(bytes32 proposal);

  //  UpgradeMajority: :proposal has achieved majority
  //
  event UpgradeMajority(address proposal);

  //  DocumentMajority: :proposal has achieved majority
  //
  event DocumentMajority(bytes32 proposal);

  //  Poll: full poll state
  //
  struct Poll
  {
    //  start: the timestamp at which the poll was started
    //
    uint256 start;

    //  voted: per galaxy, whether they have voted on this poll
    //
    bool[256] voted;

    //  yesVotes: amount of votes in favor of the proposal
    //
    uint16 yesVotes;

    //  noVotes: amount of votes against the proposal
    //
    uint16 noVotes;

    //  duration: amount of time during which the poll can be voted on
    //
    uint256 duration;

    //  cooldown: amount of time before the (non-majority) poll can be reopened
    //
    uint256 cooldown;
  }

  //  pollDuration: duration set for new polls. see also Poll.duration above
  //
  uint256 public pollDuration;

  //  pollCooldown: cooldown set for new polls. see also Poll.cooldown above
  //
  uint256 public pollCooldown;

  //  totalVoters: amount of active galaxies
  //
  uint16 public totalVoters;

  //  upgradeProposals: list of all upgrades ever proposed
  //
  //    this allows clients to discover the existence of polls.
  //    from there, they can do liveness checks on the polls themselves.
  //
  address[] public upgradeProposals;

  //  upgradePolls: per address, poll held to determine if that address
  //                will become the new ecliptic
  //
  mapping(address => Poll) public upgradePolls;

  //  upgradeHasAchievedMajority: per address, whether that address
  //                              has ever achieved majority
  //
  //    If we did not store this, we would have to look at old poll data
  //    to see whether or not a proposal has ever achieved majority.
  //    Since the outcome of a poll is calculated based on :totalVoters,
  //    which may not be consistent across time, we need to store outcomes
  //    explicitly instead of re-calculating them. This allows us to always
  //    tell with certainty whether or not a majority was achieved,
  //    regardless of the current :totalVoters.
  //
  mapping(address => bool) public upgradeHasAchievedMajority;

  //  documentProposals: list of all documents ever proposed
  //
  //    this allows clients to discover the existence of polls.
  //    from there, they can do liveness checks on the polls themselves.
  //
  bytes32[] public documentProposals;

  //  documentPolls: per hash, poll held to determine if the corresponding
  //                 document is accepted by the galactic senate
  //
  mapping(bytes32 => Poll) public documentPolls;

  //  documentHasAchievedMajority: per hash, whether that hash has ever
  //                               achieved majority
  //
  //    the note for upgradeHasAchievedMajority above applies here as well
  //
  mapping(bytes32 => bool) public documentHasAchievedMajority;

  //  documentMajorities: all hashes that have achieved majority
  //
  bytes32[] public documentMajorities;

  //  constructor(): initial contract configuration
  //
  constructor(uint256 _pollDuration, uint256 _pollCooldown)
    public
  {
    reconfigure(_pollDuration, _pollCooldown);
  }

  //  reconfigure(): change poll duration and cooldown
  //
  function reconfigure(uint256 _pollDuration, uint256 _pollCooldown)
    public
    onlyOwner
  {
    require( (5 days <= _pollDuration) && (_pollDuration <= 90 days) &&
             (5 days <= _pollCooldown) && (_pollCooldown <= 90 days) );
    pollDuration = _pollDuration;
    pollCooldown = _pollCooldown;
  }

  //  incrementTotalVoters(): increase the amount of registered voters
  //
  function incrementTotalVoters()
    external
    onlyOwner
  {
    require(totalVoters < 256);
    totalVoters = totalVoters.add(1);
  }

  //  getAllUpgradeProposals(): return array of all upgrade proposals ever made
  //
  //    Note: only useful for clients, as Solidity does not currently
  //    support returning dynamic arrays.
  //
  function getUpgradeProposals()
    external
    view
    returns (address[] proposals)
  {
    return upgradeProposals;
  }

  //  getUpgradeProposalCount(): get the number of unique proposed upgrades
  //
  function getUpgradeProposalCount()
    external
    view
    returns (uint256 count)
  {
    return upgradeProposals.length;
  }

  //  getAllDocumentProposals(): return array of all upgrade proposals ever made
  //
  //    Note: only useful for clients, as Solidity does not currently
  //    support returning dynamic arrays.
  //
  function getDocumentProposals()
    external
    view
    returns (bytes32[] proposals)
  {
    return documentProposals;
  }

  //  getDocumentProposalCount(): get the number of unique proposed upgrades
  //
  function getDocumentProposalCount()
    external
    view
    returns (uint256 count)
  {
    return documentProposals.length;
  }

  //  getDocumentMajorities(): return array of all document majorities
  //
  //    Note: only useful for clients, as Solidity does not currently
  //    support returning dynamic arrays.
  //
  function getDocumentMajorities()
    external
    view
    returns (bytes32[] majorities)
  {
    return documentMajorities;
  }

  //  hasVotedOnUpgradePoll(): returns true if _galaxy has voted
  //                           on the _proposal
  //
  function hasVotedOnUpgradePoll(uint8 _galaxy, address _proposal)
    external
    view
    returns (bool result)
  {
    return upgradePolls[_proposal].voted[_galaxy];
  }

  //  hasVotedOnDocumentPoll(): returns true if _galaxy has voted
  //                            on the _proposal
  //
  function hasVotedOnDocumentPoll(uint8 _galaxy, bytes32 _proposal)
    external
    view
    returns (bool result)
  {
    return documentPolls[_proposal].voted[_galaxy];
  }

  //  startUpgradePoll(): open a poll on making _proposal the new ecliptic
  //
  function startUpgradePoll(address _proposal)
    external
    onlyOwner
  {
    //  _proposal must not have achieved majority before
    //
    require(!upgradeHasAchievedMajority[_proposal]);

    Poll storage poll = upgradePolls[_proposal];

    //  if the proposal is being made for the first time, register it.
    //
    if (0 == poll.start)
    {
      upgradeProposals.push(_proposal);
    }

    startPoll(poll);
    emit UpgradePollStarted(_proposal);
  }

  //  startDocumentPoll(): open a poll on accepting the document
  //                       whose hash is _proposal
  //
  function startDocumentPoll(bytes32 _proposal)
    external
    onlyOwner
  {
    //  _proposal must not have achieved majority before
    //
    require(!documentHasAchievedMajority[_proposal]);

    Poll storage poll = documentPolls[_proposal];

    //  if the proposal is being made for the first time, register it.
    //
    if (0 == poll.start)
    {
      documentProposals.push(_proposal);
    }

    startPoll(poll);
    emit DocumentPollStarted(_proposal);
  }

  //  startPoll(): open a new poll, or re-open an old one
  //
  function startPoll(Poll storage _poll)
    internal
  {
    //  check that the poll has cooled down enough to be started again
    //
    //    for completely new polls, the values used will be zero
    //
    require( block.timestamp > ( _poll.start.add(
                                 _poll.duration.add(
                                 _poll.cooldown )) ) );

    //  set started poll state
    //
    _poll.start = block.timestamp;
    delete _poll.voted;
    _poll.yesVotes = 0;
    _poll.noVotes = 0;
    _poll.duration = pollDuration;
    _poll.cooldown = pollCooldown;
  }

  //  castUpgradeVote(): as galaxy _as, cast a vote on the _proposal
  //
  //    _vote is true when in favor of the proposal, false otherwise
  //
  function castUpgradeVote(uint8 _as, address _proposal, bool _vote)
    external
    onlyOwner
    returns (bool majority)
  {
    Poll storage poll = upgradePolls[_proposal];
    processVote(poll, _as, _vote);
    return updateUpgradePoll(_proposal);
  }

  //  castDocumentVote(): as galaxy _as, cast a vote on the _proposal
  //
  //    _vote is true when in favor of the proposal, false otherwise
  //
  function castDocumentVote(uint8 _as, bytes32 _proposal, bool _vote)
    external
    onlyOwner
    returns (bool majority)
  {
    Poll storage poll = documentPolls[_proposal];
    processVote(poll, _as, _vote);
    return updateDocumentPoll(_proposal);
  }

  //  processVote(): record a vote from _as on the _poll
  //
  function processVote(Poll storage _poll, uint8 _as, bool _vote)
    internal
  {
    //  assist symbolic execution tools
    //
    assert(block.timestamp >= _poll.start);

    require( //  may only vote once
             //
             !_poll.voted[_as] &&
             //
             //  may only vote when the poll is open
             //
             (block.timestamp < _poll.start.add(_poll.duration)) );

    //  update poll state to account for the new vote
    //
    _poll.voted[_as] = true;
    if (_vote)
    {
      _poll.yesVotes = _poll.yesVotes.add(1);
    }
    else
    {
      _poll.noVotes = _poll.noVotes.add(1);
    }
  }

  //  updateUpgradePoll(): check whether the _proposal has achieved
  //                            majority, updating state, sending an event,
  //                            and returning true if it has
  //
  function updateUpgradePoll(address _proposal)
    public
    onlyOwner
    returns (bool majority)
  {
    //  _proposal must not have achieved majority before
    //
    require(!upgradeHasAchievedMajority[_proposal]);

    //  check for majority in the poll
    //
    Poll storage poll = upgradePolls[_proposal];
    majority = checkPollMajority(poll);

    //  if majority was achieved, update the state and send an event
    //
    if (majority)
    {
      upgradeHasAchievedMajority[_proposal] = true;
      emit UpgradeMajority(_proposal);
    }
    return majority;
  }

  //  updateDocumentPoll(): check whether the _proposal has achieved majority,
  //                        updating the state and sending an event if it has
  //
  //    this can be called by anyone, because the ecliptic does not
  //    need to be aware of the result
  //
  function updateDocumentPoll(bytes32 _proposal)
    public
    returns (bool majority)
  {
    //  _proposal must not have achieved majority before
    //
    require(!documentHasAchievedMajority[_proposal]);

    //  check for majority in the poll
    //
    Poll storage poll = documentPolls[_proposal];
    majority = checkPollMajority(poll);

    //  if majority was achieved, update state and send an event
    //
    if (majority)
    {
      documentHasAchievedMajority[_proposal] = true;
      documentMajorities.push(_proposal);
      emit DocumentMajority(_proposal);
    }
    return majority;
  }

  //  checkPollMajority(): returns true if the majority is in favor of
  //                       the subject of the poll
  //
  function checkPollMajority(Poll _poll)
    internal
    view
    returns (bool majority)
  {
    return ( //  poll must have at least the minimum required yes-votes
             //
             (_poll.yesVotes >= (totalVoters / 4)) &&
             //
             //  and have a majority...
             //
             (_poll.yesVotes > _poll.noVotes) &&
             //
             //  ...that is indisputable
             //
             ( //  either because the poll has ended
               //
               (block.timestamp > _poll.start.add(_poll.duration)) ||
               //
               //  or there are more yes votes than there can be no votes
               //
               ( _poll.yesVotes > totalVoters.sub(_poll.yesVotes) ) ) );
  }
}

// Azimuth's Claims.sol

//  Claims: simple identity management
//
//    This contract allows points to document claims about their owner.
//    Most commonly, these are about identity, with a claim's protocol
//    defining the context or platform of the claim, and its dossier
//    containing proof of its validity.
//    Points are limited to a maximum of 16 claims.
//
//    For existing claims, the dossier can be updated, or the claim can
//    be removed entirely. It is recommended to remove any claims associated
//    with a point when it is about to be transferred to a new owner.
//    For convenience, the owner of the Azimuth contract (the Ecliptic)
//    is allowed to clear claims for any point, allowing it to do this for
//    you on-transfer.
//
contract Claims is ReadsAzimuth
{
  //  ClaimAdded: a claim was added by :by
  //
  event ClaimAdded( uint32 indexed by,
                    string _protocol,
                    string _claim,
                    bytes _dossier );

  //  ClaimRemoved: a claim was removed by :by
  //
  event ClaimRemoved(uint32 indexed by, string _protocol, string _claim);

  //  maxClaims: the amount of claims that can be registered per point
  //
  uint8 constant maxClaims = 16;

  //  Claim: claim details
  //
  struct Claim
  {
    //  protocol: context of the claim
    //
    string protocol;

    //  claim: the claim itself
    //
    string claim;

    //  dossier: data relating to the claim, as proof
    //
    bytes dossier;
  }

  //  per point, list of claims
  //
  mapping(uint32 => Claim[maxClaims]) public claims;

  //  constructor(): register the azimuth contract.
  //
  constructor(Azimuth _azimuth)
    ReadsAzimuth(_azimuth)
    public
  {
    //
  }

  //  addClaim(): register a claim as _point
  //
  function addClaim(uint32 _point,
                    string _protocol,
                    string _claim,
                    bytes _dossier)
    external
    activePointManager(_point)
  {
    //  cur: index + 1 of the claim if it already exists, 0 otherwise
    //
    uint8 cur = findClaim(_point, _protocol, _claim);

    //  if the claim doesn't yet exist, store it in state
    //
    if (cur == 0)
    {
      //  if there are no empty slots left, this throws
      //
      uint8 empty = findEmptySlot(_point);
      claims[_point][empty] = Claim(_protocol, _claim, _dossier);
    }
    //
    //  if the claim has been made before, update the version in state
    //
    else
    {
      claims[_point][cur-1] = Claim(_protocol, _claim, _dossier);
    }
    emit ClaimAdded(_point, _protocol, _claim, _dossier);
  }

  //  removeClaim(): unregister a claim as _point
  //
  function removeClaim(uint32 _point, string _protocol, string _claim)
    external
    activePointManager(_point)
  {
    //  i: current index + 1 in _point's list of claims
    //
    uint256 i = findClaim(_point, _protocol, _claim);

    //  we store index + 1, because 0 is the eth default value
    //  can only delete an existing claim
    //
    require(i > 0);
    i--;

    //  clear out the claim
    //
    delete claims[_point][i];

    emit ClaimRemoved(_point, _protocol, _claim);
  }

  //  clearClaims(): unregister all of _point's claims
  //
  //    can also be called by the ecliptic during point transfer
  //
  function clearClaims(uint32 _point)
    external
  {
    //  both point owner and ecliptic may do this
    //
    //    We do not necessarily need to check for _point's active flag here,
    //    since inactive points cannot have claims set. Doing the check
    //    anyway would make this function slightly harder to think about due
    //    to its relation to Ecliptic's transferPoint().
    //
    require( azimuth.canManage(_point, msg.sender) ||
             ( msg.sender == azimuth.owner() ) );

    Claim[maxClaims] storage currClaims = claims[_point];

    //  clear out all claims
    //
    for (uint8 i = 0; i < maxClaims; i++)
    {
      delete currClaims[i];
    }
  }

  //  findClaim(): find the index of the specified claim
  //
  //    returns 0 if not found, index + 1 otherwise
  //
  function findClaim(uint32 _whose, string _protocol, string _claim)
    public
    view
    returns (uint8 index)
  {
    //  we use hashes of the string because solidity can't do string
    //  comparison yet
    //
    bytes32 protocolHash = keccak256(bytes(_protocol));
    bytes32 claimHash = keccak256(bytes(_claim));
    Claim[maxClaims] storage theirClaims = claims[_whose];
    for (uint8 i = 0; i < maxClaims; i++)
    {
      Claim storage thisClaim = theirClaims[i];
      if ( ( protocolHash == keccak256(bytes(thisClaim.protocol)) ) &&
           ( claimHash == keccak256(bytes(thisClaim.claim)) ) )
      {
        return i+1;
      }
    }
    return 0;
  }

  //  findEmptySlot(): find the index of the first empty claim slot
  //
  //    returns the index of the slot, throws if there are no empty slots
  //
  function findEmptySlot(uint32 _whose)
    internal
    view
    returns (uint8 index)
  {
    Claim[maxClaims] storage theirClaims = claims[_whose];
    for (uint8 i = 0; i < maxClaims; i++)
    {
      Claim storage thisClaim = theirClaims[i];
      if ( (0 == bytes(thisClaim.protocol).length) &&
           (0 == bytes(thisClaim.claim).length) )
      {
        return i;
      }
    }
    revert();
  }
}

// Azimuth's EclipticBase.sol

//  EclipticBase: upgradable ecliptic
//
//    This contract implements the upgrade logic for the Ecliptic.
//    Newer versions of the Ecliptic are expected to provide at least
//    the onUpgrade() function. If they don't, upgrading to them will
//    fail.
//
//    Note that even though this contract doesn't specify any required
//    interface members aside from upgrade() and onUpgrade(), contracts
//    and clients may still rely on the presence of certain functions
//    provided by the Ecliptic proper. Keep this in mind when writing
//    new versions of it.
//
contract EclipticBase is Ownable, ReadsAzimuth
{
  //  Upgraded: _to is the new canonical Ecliptic
  //
  event Upgraded(address to);

  //  polls: senate voting contract
  //
  Polls public polls;

  //  previousEcliptic: address of the previous ecliptic this
  //                    instance expects to upgrade from, stored and
  //                    checked for to prevent unexpected upgrade paths
  //
  address public previousEcliptic;

  constructor( address _previous,
               Azimuth _azimuth,
               Polls _polls )
    ReadsAzimuth(_azimuth)
    internal
  {
    previousEcliptic = _previous;
    polls = _polls;
  }

  //  onUpgrade(): called by previous ecliptic when upgrading
  //
  //    in future ecliptics, this might perform more logic than
  //    just simple checks and verifications.
  //    when overriding this, make sure to call this original as well.
  //
  function onUpgrade()
    external
  {
    //  make sure this is the expected upgrade path,
    //  and that we have gotten the ownership we require
    //
    require( msg.sender == previousEcliptic &&
             this == azimuth.owner() &&
             this == polls.owner() );
  }

  //  upgrade(): transfer ownership of the ecliptic data to the new
  //             ecliptic contract, notify it, then self-destruct.
  //
  //    Note: any eth that have somehow ended up in this contract
  //          are also sent to the new ecliptic.
  //
  function upgrade(EclipticBase _new)
    internal
  {
    //  transfer ownership of the data contracts
    //
    azimuth.transferOwnership(_new);
    polls.transferOwnership(_new);

    //  trigger upgrade logic on the target contract
    //
    _new.onUpgrade();

    //  emit event and destroy this contract
    //
    emit Upgraded(_new);
    selfdestruct(_new);
  }
}

////////////////////////////////////////////////////////////////////////////////
//  Ecliptic
////////////////////////////////////////////////////////////////////////////////

//  Ecliptic: logic for interacting with the Azimuth ledger
//
//    This contract is the point of entry for all operations on the Azimuth
//    ledger as stored in the Azimuth data contract. The functions herein
//    are responsible for performing all necessary business logic.
//    Examples of such logic include verifying permissions of the caller
//    and ensuring a requested change is actually valid.
//    Point owners can always operate on their own points. Ethereum addresses
//    can also perform specific operations if they've been given the
//    appropriate permissions. (For example, managers for general management,
//    spawn proxies for spawning child points, etc.)
//
//    This contract uses external contracts (Azimuth, Polls) for data storage
//    so that it itself can easily be replaced in case its logic needs to
//    be changed. In other words, it can be upgraded. It does this by passing
//    ownership of the data contracts to a new Ecliptic contract.
//
//    Because of this, it is advised for clients to not store this contract's
//    address directly, but rather ask the Azimuth contract for its owner
//    attribute to ensure transactions get sent to the latest Ecliptic.
//    Alternatively, the ENS name ecliptic.eth will resolve to the latest
//    Ecliptic as well.
//
//    Upgrading happens based on polls held by the senate (galaxy owners).
//    Through this contract, the senate can submit proposals, opening polls
//    for the senate to cast votes on. These proposals can be either hashes
//    of documents or addresses of new Ecliptics.
//    If an ecliptic proposal gains majority, this contract will transfer
//    ownership of the data storage contracts to that address, so that it may
//    operate on the data they contain. This contract will selfdestruct at
//    the end of the upgrade process.
//
//    This contract implements the ERC721 interface for non-fungible tokens,
//    allowing points to be managed using generic clients that support the
//    standard. It also implements ERC165 to allow this to be discovered.
//
contract Ecliptic is EclipticBase, SupportsInterfaceWithLookup, ERC721Metadata
{
  using SafeMath for uint256;
  using AddressUtils for address;

  //  Transfer: This emits when ownership of any NFT changes by any mechanism.
  //            This event emits when NFTs are created (`from` == 0) and
  //            destroyed (`to` == 0). At the time of any transfer, the
  //            approved address for that NFT (if any) is reset to none.
  //
  event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);

  //  Approval: This emits when the approved address for an NFT is changed or
  //            reaffirmed. The zero address indicates there is no approved
  //            address. When a Transfer event emits, this also indicates that
  //            the approved address for that NFT (if any) is reset to none.
  //
  event Approval(address indexed _owner, address indexed _approved,
                 uint256 _tokenId);

  //  ApprovalForAll: This emits when an operator is enabled or disabled for an
  //                  owner. The operator can manage all NFTs of the owner.
  //
  event ApprovalForAll(address indexed _owner, address indexed _operator,
                       bool _approved);

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

  //  claims: contract reference, for clearing claims on-transfer
  //
  Claims public claims;

  //  constructor(): set data contract addresses and signal interface support
  //
  //    Note: during first deploy, ownership of these data contracts must
  //    be manually transferred to this contract.
  //
  constructor(address _previous,
              Azimuth _azimuth,
              Polls _polls,
              Claims _claims)
    EclipticBase(_previous, _azimuth, _polls)
    public
  {
    claims = _claims;

    //  register supported interfaces for ERC165
    //
    _registerInterface(0x80ac58cd); // ERC721
    _registerInterface(0x5b5e139f); // ERC721Metadata
    _registerInterface(0x7f5828d0); // ERC173 (ownership)
  }

  //
  //  ERC721 interface
  //

    //  balanceOf(): get the amount of points owned by _owner
    //
    function balanceOf(address _owner)
      public
      view
      returns (uint256 balance)
    {
      require(0x0 != _owner);
      return azimuth.getOwnedPointCount(_owner);
    }

    //  ownerOf(): get the current owner of point _tokenId
    //
    function ownerOf(uint256 _tokenId)
      public
      view
      validPointId(_tokenId)
      returns (address owner)
    {
      uint32 id = uint32(_tokenId);

      //  this will throw if the owner is the zero address,
      //  active points always have a valid owner.
      //
      require(azimuth.isActive(id));

      return azimuth.getOwner(id);
    }

    //  exists(): returns true if point _tokenId is active
    //
    function exists(uint256 _tokenId)
      public
      view
      returns (bool doesExist)
    {
      return ( (_tokenId < 0x100000000) &&
               azimuth.isActive(uint32(_tokenId)) );
    }

    //  safeTransferFrom(): transfer point _tokenId from _from to _to
    //
    function safeTransferFrom(address _from, address _to, uint256 _tokenId)
      public
    {
      //  transfer with empty data
      //
      safeTransferFrom(_from, _to, _tokenId, "");
    }

    //  safeTransferFrom(): transfer point _tokenId from _from to _to,
    //                      and call recipient if it's a contract
    //
    function safeTransferFrom(address _from, address _to, uint256 _tokenId,
                              bytes _data)
      public
    {
      //  perform raw transfer
      //
      transferFrom(_from, _to, _tokenId);

      //  do the callback last to avoid re-entrancy
      //
      if (_to.isContract())
      {
        bytes4 retval = ERC721Receiver(_to)
                        .onERC721Received(msg.sender, _from, _tokenId, _data);
        //
        //  standard return idiom to confirm contract semantics
        //
        require(retval == erc721Received);
      }
    }

    //  transferFrom(): transfer point _tokenId from _from to _to,
    //                  WITHOUT notifying recipient contract
    //
    function transferFrom(address _from, address _to, uint256 _tokenId)
      public
      validPointId(_tokenId)
    {
      uint32 id = uint32(_tokenId);
      require(azimuth.isOwner(id, _from));

      //  the ERC721 operator/approved address (if any) is
      //  accounted for in transferPoint()
      //
      transferPoint(id, _to, true);
    }

    //  approve(): allow _approved to transfer ownership of point
    //             _tokenId
    //
    function approve(address _approved, uint256 _tokenId)
      public
      validPointId(_tokenId)
    {
      setTransferProxy(uint32(_tokenId), _approved);
    }

    //  setApprovalForAll(): allow or disallow _operator to
    //                       transfer ownership of ALL points
    //                       owned by :msg.sender
    //
    function setApprovalForAll(address _operator, bool _approved)
      public
    {
      require(0x0 != _operator);
      azimuth.setOperator(msg.sender, _operator, _approved);
      emit ApprovalForAll(msg.sender, _operator, _approved);
    }

    //  getApproved(): get the approved address for point _tokenId
    //
    function getApproved(uint256 _tokenId)
      public
      view
      validPointId(_tokenId)
      returns (address approved)
    {
      //NOTE  redundant, transfer proxy cannot be set for
      //      inactive points
      //
      require(azimuth.isActive(uint32(_tokenId)));
      return azimuth.getTransferProxy(uint32(_tokenId));
    }

    //  isApprovedForAll(): returns true if _operator is an
    //                      operator for _owner
    //
    function isApprovedForAll(address _owner, address _operator)
      public
      view
      returns (bool result)
    {
      return azimuth.isOperator(_owner, _operator);
    }

  //
  //  ERC721Metadata interface
  //

    //  name(): returns the name of a collection of points
    //
    function name()
      external
      view
      returns (string)
    {
      return "Azimuth Points";
    }

    //  symbol(): returns an abbreviates name for points
    //
    function symbol()
      external
      view
      returns (string)
    {
      return "AZP";
    }

    //  tokenURI(): returns a URL to an ERC-721 standard JSON file
    //
    function tokenURI(uint256 _tokenId)
      public
      view
      validPointId(_tokenId)
      returns (string _tokenURI)
    {
      _tokenURI = "https://azimuth.network/erc721/0000000000.json";
      bytes memory _tokenURIBytes = bytes(_tokenURI);
      _tokenURIBytes[31] = byte(48+(_tokenId / 1000000000) % 10);
      _tokenURIBytes[32] = byte(48+(_tokenId / 100000000) % 10);
      _tokenURIBytes[33] = byte(48+(_tokenId / 10000000) % 10);
      _tokenURIBytes[34] = byte(48+(_tokenId / 1000000) % 10);
      _tokenURIBytes[35] = byte(48+(_tokenId / 100000) % 10);
      _tokenURIBytes[36] = byte(48+(_tokenId / 10000) % 10);
      _tokenURIBytes[37] = byte(48+(_tokenId / 1000) % 10);
      _tokenURIBytes[38] = byte(48+(_tokenId / 100) % 10);
      _tokenURIBytes[39] = byte(48+(_tokenId / 10) % 10);
      _tokenURIBytes[40] = byte(48+(_tokenId / 1) % 10);
    }

  //
  //  Points interface
  //

    //  configureKeys(): configure _point with network public keys
    //                   _encryptionKey, _authenticationKey,
    //                   and corresponding _cryptoSuiteVersion,
    //                   incrementing the point's continuity number if needed
    //
    function configureKeys(uint32 _point,
                           bytes32 _encryptionKey,
                           bytes32 _authenticationKey,
                           uint32 _cryptoSuiteVersion,
                           bool _discontinuous)
      external
      activePointManager(_point)
    {
      if (_discontinuous)
      {
        azimuth.incrementContinuityNumber(_point);
      }
      azimuth.setKeys(_point,
                      _encryptionKey,
                      _authenticationKey,
                      _cryptoSuiteVersion);
    }

    //  spawn(): spawn _point, then either give, or allow _target to take,
    //           ownership of _point
    //
    //    if _target is the :msg.sender, _targets owns the _point right away.
    //    otherwise, _target becomes the transfer proxy of _point.
    //
    //    Requirements:
    //    - _point must not be active
    //    - _point must not be a planet with a galaxy prefix
    //    - _point's prefix must be linked and under its spawn limit
    //    - :msg.sender must be either the owner of _point's prefix,
    //      or an authorized spawn proxy for it
    //
    function spawn(uint32 _point, address _target)
      external
    {
      //  only currently unowned (and thus also inactive) points can be spawned
      //
      require(azimuth.isOwner(_point, 0x0));

      //  prefix: half-width prefix of _point
      //
      uint16 prefix = azimuth.getPrefix(_point);

      //  only allow spawning of points of the size directly below the prefix
      //
      //    this is possible because of how the address space works,
      //    but supporting it introduces complexity through broken assumptions.
      //
      //    example:
      //    0x0000.0000 - galaxy zero
      //    0x0000.0100 - the first star of galaxy zero
      //    0x0001.0100 - the first planet of the first star
      //    0x0001.0000 - the first planet of galaxy zero
      //
      require( (uint8(azimuth.getPointSize(prefix)) + 1) ==
               uint8(azimuth.getPointSize(_point)) );

      //  prefix point must be linked and able to spawn
      //
      require( (azimuth.hasBeenLinked(prefix)) &&
               ( azimuth.getSpawnCount(prefix) <
                 getSpawnLimit(prefix, block.timestamp) ) );

      //  the owner of a prefix can always spawn its children;
      //  other addresses need explicit permission (the role
      //  of "spawnProxy" in the Azimuth contract)
      //
      require( azimuth.canSpawnAs(prefix, msg.sender) );

      //  if the caller is spawning the point to themselves,
      //  assume it knows what it's doing and resolve right away
      //
      if (msg.sender == _target)
      {
        doSpawn(_point, _target, true, 0x0);
      }
      //
      //  when sending to a "foreign" address, enforce a withdraw pattern
      //  making the _point prefix's owner the _point owner in the mean time
      //
      else
      {
        doSpawn(_point, _target, false, azimuth.getOwner(prefix));
      }
    }

    //  doSpawn(): actual spawning logic, used in spawn(). creates _point,
    //             making the _target its owner if _direct, or making the
    //             _holder the owner and the _target the transfer proxy
    //             if not _direct.
    //
    function doSpawn( uint32 _point,
                      address _target,
                      bool _direct,
                      address _holder )
      internal
    {
      //  register the spawn for _point's prefix, incrementing spawn count
      //
      azimuth.registerSpawned(_point);

      //  if the spawn is _direct, assume _target knows what they're doing
      //  and resolve right away
      //
      if (_direct)
      {
        //  make the point active and set its new owner
        //
        azimuth.activatePoint(_point);
        azimuth.setOwner(_point, _target);

        emit Transfer(0x0, _target, uint256(_point));
      }
      //
      //  when spawning indirectly, enforce a withdraw pattern by approving
      //  the _target for transfer of the _point instead.
      //  we make the _holder the owner of this _point in the mean time,
      //  so that it may cancel the transfer (un-approve) if _target flakes.
      //  we don't make _point active yet, because it still doesn't really
      //  belong to anyone.
      //
      else
      {
        //  have _holder hold on to the _point while _target gets to transfer
        //  ownership of it
        //
        azimuth.setOwner(_point, _holder);
        azimuth.setTransferProxy(_point, _target);

        emit Transfer(0x0, _holder, uint256(_point));
        emit Approval(_holder, _target, uint256(_point));
      }
    }

    //  transferPoint(): transfer _point to _target, clearing all permissions
    //                   data and keys if _reset is true
    //
    //    Note: the _reset flag is useful when transferring the point to
    //    a recipient who doesn't trust the previous owner.
    //
    //    Requirements:
    //    - :msg.sender must be either _point's current owner, authorized
    //      to transfer _point, or authorized to transfer the current
    //      owner's points (as in ERC721's operator)
    //    - _target must not be the zero address
    //
    function transferPoint(uint32 _point, address _target, bool _reset)
      public
    {
      //  transfer is legitimate if the caller is the current owner, or
      //  an operator for the current owner, or the _point's transfer proxy
      //
      require(azimuth.canTransfer(_point, msg.sender));

      //  if the point wasn't active yet, that means transferring it
      //  is part of the "spawn" flow, so we need to activate it
      //
      if ( !azimuth.isActive(_point) )
      {
        azimuth.activatePoint(_point);
      }

      //  if the owner would actually change, change it
      //
      //    the only time this deliberately wouldn't be the case is when a
      //    prefix owner wants to activate a spawned but untransferred child.
      //
      if ( !azimuth.isOwner(_point, _target) )
      {
        //  remember the previous owner, to be included in the Transfer event
        //
        address old = azimuth.getOwner(_point);

        azimuth.setOwner(_point, _target);

        //  according to ERC721, the approved address (here, transfer proxy)
        //  gets cleared during every Transfer event
        //
        azimuth.setTransferProxy(_point, 0);

        emit Transfer(old, _target, uint256(_point));
      }

      //  reset sensitive data
      //  used when transferring the point to a new owner
      //
      if ( _reset )
      {
        //  clear the network public keys and break continuity,
        //  but only if the point has already been linked
        //
        if ( azimuth.hasBeenLinked(_point) )
        {
          azimuth.incrementContinuityNumber(_point);
          azimuth.setKeys(_point, 0, 0, 0);
        }

        //  clear management proxy
        //
        azimuth.setManagementProxy(_point, 0);

        //  clear voting proxy
        //
        azimuth.setVotingProxy(_point, 0);

        //  clear transfer proxy
        //
        //    in most cases this is done above, during the ownership transfer,
        //    but we might not hit that and still be expected to reset the
        //    transfer proxy.
        //    doing it a second time is a no-op in Azimuth.
        //
        azimuth.setTransferProxy(_point, 0);

        //  clear spawning proxy
        //
        azimuth.setSpawnProxy(_point, 0);

        //  clear claims
        //
        claims.clearClaims(_point);
      }
    }

    //  escape(): request escape as _point to _sponsor
    //
    //    if an escape request is already active, this overwrites
    //    the existing request
    //
    //    Requirements:
    //    - :msg.sender must be the owner or manager of _point,
    //    - _point must be able to escape to _sponsor as per to canEscapeTo()
    //
    function escape(uint32 _point, uint32 _sponsor)
      external
      activePointManager(_point)
    {
      require(canEscapeTo(_point, _sponsor));
      azimuth.setEscapeRequest(_point, _sponsor);
    }

    //  cancelEscape(): cancel the currently set escape for _point
    //
    function cancelEscape(uint32 _point)
      external
      activePointManager(_point)
    {
      azimuth.cancelEscape(_point);
    }

    //  adopt(): as the relevant sponsor, accept the _point
    //
    //    Requirements:
    //    - :msg.sender must be the owner or management proxy
    //      of _point's requested sponsor
    //
    function adopt(uint32 _point)
      external
    {
      require( azimuth.isEscaping(_point) &&
               azimuth.canManage( azimuth.getEscapeRequest(_point),
                                  msg.sender ) );

      //  _sponsor becomes _point's sponsor
      //  its escape request is reset to "not escaping"
      //
      azimuth.doEscape(_point);
    }

    //  reject(): as the relevant sponsor, deny the _point's request
    //
    //    Requirements:
    //    - :msg.sender must be the owner or management proxy
    //      of _point's requested sponsor
    //
    function reject(uint32 _point)
      external
    {
      require( azimuth.isEscaping(_point) &&
               azimuth.canManage( azimuth.getEscapeRequest(_point),
                                  msg.sender ) );

      //  reset the _point's escape request to "not escaping"
      //
      azimuth.cancelEscape(_point);
    }

    //  detach(): as the _sponsor, stop sponsoring the _point
    //
    //    Requirements:
    //    - :msg.sender must be the owner or management proxy
    //      of _point's current sponsor
    //
    function detach(uint32 _point)
      external
    {
      require( azimuth.hasSponsor(_point) &&
               azimuth.canManage(azimuth.getSponsor(_point), msg.sender) );

      //  signal that its sponsor no longer supports _point
      //
      azimuth.loseSponsor(_point);
    }

  //
  //  Point rules
  //

    //  getSpawnLimit(): returns the total number of children the _point
    //                   is allowed to spawn at _time.
    //
    function getSpawnLimit(uint32 _point, uint256 _time)
      public
      view
      returns (uint32 limit)
    {
      Azimuth.Size size = azimuth.getPointSize(_point);

      if ( size == Azimuth.Size.Galaxy )
      {
        return 255;
      }
      else if ( size == Azimuth.Size.Star )
      {
        //  in 2019, stars may spawn at most 1024 planets. this limit doubles
        //  for every subsequent year.
        //
        //    Note: 1546300800 corresponds to 2019-01-01
        //
        uint256 yearsSince2019 = (_time - 1546300800) / 365 days;
        if (yearsSince2019 < 6)
        {
          limit = uint32( 1024 * (2 ** yearsSince2019) );
        }
        else
        {
          limit = 65535;
        }
        return limit;
      }
      else  //  size == Azimuth.Size.Planet
      {
        //  planets can create moons, but moons aren't on the chain
        //
        return 0;
      }
    }

    //  canEscapeTo(): true if _point could try to escape to _sponsor
    //
    function canEscapeTo(uint32 _point, uint32 _sponsor)
      public
      view
      returns (bool canEscape)
    {
      //  can't escape to a sponsor that hasn't been linked
      //
      if ( !azimuth.hasBeenLinked(_sponsor) ) return false;

      //  Can only escape to a point one size higher than ourselves,
      //  except in the special case where the escaping point hasn't
      //  been linked yet -- in that case we may escape to points of
      //  the same size, to support lightweight invitation chains.
      //
      //  The use case for lightweight invitations is that a planet
      //  owner should be able to invite their friends onto an
      //  Azimuth network in a two-party transaction, without a new
      //  star relationship.
      //  The lightweight invitation process works by escaping your
      //  own active (but never linked) point to one of your own
      //  points, then transferring the point to your friend.
      //
      //  These planets can, in turn, sponsor other unlinked planets,
      //  so the "planet sponsorship chain" can grow to arbitrary
      //  length. Most users, especially deep down the chain, will
      //  want to improve their performance by switching to direct
      //  star sponsors eventually.
      //
      Azimuth.Size pointSize = azimuth.getPointSize(_point);
      Azimuth.Size sponsorSize = azimuth.getPointSize(_sponsor);
      return ( //  normal hierarchical escape structure
               //
               ( (uint8(sponsorSize) + 1) == uint8(pointSize) ) ||
               //
               //  special peer escape
               //
               ( (sponsorSize == pointSize) &&
                 //
                 //  peer escape is only for points that haven't been linked
                 //  yet, because it's only for lightweight invitation chains
                 //
                 !azimuth.hasBeenLinked(_point) ) );
    }

  //
  //  Permission management
  //

    //  setManagementProxy(): configure the management proxy for _point
    //
    //    The management proxy may perform "reversible" operations on
    //    behalf of the owner. This includes public key configuration and
    //    operations relating to sponsorship.
    //
    function setManagementProxy(uint32 _point, address _manager)
      external
      activePointOwner(_point)
    {
      azimuth.setManagementProxy(_point, _manager);
    }

    //  setSpawnProxy(): give _spawnProxy the right to spawn points
    //                   with the prefix _prefix
    //
    function setSpawnProxy(uint16 _prefix, address _spawnProxy)
      external
      activePointOwner(_prefix)
    {
      azimuth.setSpawnProxy(_prefix, _spawnProxy);
    }

    //  setVotingProxy(): configure the voting proxy for _galaxy
    //
    //    the voting proxy is allowed to start polls and cast votes
    //    on the point's behalf.
    //
    function setVotingProxy(uint8 _galaxy, address _voter)
      external
      activePointOwner(_galaxy)
    {
      azimuth.setVotingProxy(_galaxy, _voter);
    }

    //  setTransferProxy(): give _transferProxy the right to transfer _point
    //
    //    Requirements:
    //    - :msg.sender must be either _point's current owner,
    //      or be an operator for the current owner
    //
    function setTransferProxy(uint32 _point, address _transferProxy)
      public
    {
      //  owner: owner of _point
      //
      address owner = azimuth.getOwner(_point);

      //  caller must be :owner, or an operator designated by the owner.
      //
      require((owner == msg.sender) || azimuth.isOperator(owner, msg.sender));

      //  set transfer proxy field in Azimuth contract
      //
      azimuth.setTransferProxy(_point, _transferProxy);

      //  emit Approval event
      //
      emit Approval(owner, _transferProxy, uint256(_point));
    }

  //
  //  Poll actions
  //

    //  startUpgradePoll(): as _galaxy, start a poll for the ecliptic
    //                      upgrade _proposal
    //
    //    Requirements:
    //    - :msg.sender must be the owner or voting proxy of _galaxy,
    //    - the _proposal must expect to be upgraded from this specific
    //      contract, as indicated by its previousEcliptic attribute
    //
    function startUpgradePoll(uint8 _galaxy, EclipticBase _proposal)
      external
      activePointVoter(_galaxy)
    {
      //  ensure that the upgrade target expects this contract as the source
      //
      require(_proposal.previousEcliptic() == address(this));
      polls.startUpgradePoll(_proposal);
    }

    //  startDocumentPoll(): as _galaxy, start a poll for the _proposal
    //
    //    the _proposal argument is the keccak-256 hash of any arbitrary
    //    document or string of text
    //
    function startDocumentPoll(uint8 _galaxy, bytes32 _proposal)
      external
      activePointVoter(_galaxy)
    {
      polls.startDocumentPoll(_proposal);
    }

    //  castUpgradeVote(): as _galaxy, cast a _vote on the ecliptic
    //                     upgrade _proposal
    //
    //    _vote is true when in favor of the proposal, false otherwise
    //
    //    If this vote results in a majority for the _proposal, it will
    //    be upgraded to immediately.
    //
    function castUpgradeVote(uint8 _galaxy,
                              EclipticBase _proposal,
                              bool _vote)
      external
      activePointVoter(_galaxy)
    {
      //  majority: true if the vote resulted in a majority, false otherwise
      //
      bool majority = polls.castUpgradeVote(_galaxy, _proposal, _vote);

      //  if a majority is in favor of the upgrade, it happens as defined
      //  in the ecliptic base contract
      //
      if (majority)
      {
        upgrade(_proposal);
      }
    }

    //  castDocumentVote(): as _galaxy, cast a _vote on the _proposal
    //
    //    _vote is true when in favor of the proposal, false otherwise
    //
    function castDocumentVote(uint8 _galaxy, bytes32 _proposal, bool _vote)
      external
      activePointVoter(_galaxy)
    {
      polls.castDocumentVote(_galaxy, _proposal, _vote);
    }

    //  updateUpgradePoll(): check whether the _proposal has achieved
    //                      majority, upgrading to it if it has
    //
    function updateUpgradePoll(EclipticBase _proposal)
      external
    {
      //  majority: true if the poll ended in a majority, false otherwise
      //
      bool majority = polls.updateUpgradePoll(_proposal);

      //  if a majority is in favor of the upgrade, it happens as defined
      //  in the ecliptic base contract
      //
      if (majority)
      {
        upgrade(_proposal);
      }
    }

    //  updateDocumentPoll(): check whether the _proposal has achieved majority
    //
    //    Note: the polls contract publicly exposes the function this calls,
    //    but we offer it in the ecliptic interface as a convenience
    //
    function updateDocumentPoll(bytes32 _proposal)
      external
    {
      polls.updateDocumentPoll(_proposal);
    }

  //
  //  Contract owner operations
  //

    //  createGalaxy(): grant _target ownership of the _galaxy and register
    //                  it for voting
    //
    function createGalaxy(uint8 _galaxy, address _target)
      external
      onlyOwner
    {
      //  only currently unowned (and thus also inactive) galaxies can be
      //  created, and only to non-zero addresses
      //
      require( azimuth.isOwner(_galaxy, 0x0) &&
               0x0 != _target );

      //  new galaxy means a new registered voter
      //
      polls.incrementTotalVoters();

      //  if the caller is sending the galaxy to themselves,
      //  assume it knows what it's doing and resolve right away
      //
      if (msg.sender == _target)
      {
        doSpawn(_galaxy, _target, true, 0x0);
      }
      //
      //  when sending to a "foreign" address, enforce a withdraw pattern,
      //  making the caller the owner in the mean time
      //
      else
      {
        doSpawn(_galaxy, _target, false, msg.sender);
      }
    }

    function setDnsDomains(string _primary, string _secondary, string _tertiary)
      external
      onlyOwner
    {
      azimuth.setDnsDomains(_primary, _secondary, _tertiary);
    }

  //
  //  Function modifiers for this contract
  //

    //  validPointId(): require that _id is a valid point
    //
    modifier validPointId(uint256 _id)
    {
      require(_id < 0x100000000);
      _;
    }

    //  activePointVoter(): require that :msg.sender can vote as _point,
    //                      and that _point is active
    //
    modifier activePointVoter(uint32 _point)
    {
      require( azimuth.canVoteAs(_point, msg.sender) &&
               azimuth.isActive(_point) );
      _;
    }
}

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":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"bytes32"}],"name":"startDocumentPoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"detach","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"approved","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_approved","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposal","type":"bytes32"}],"name":"updateDocumentPoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"onUpgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_target","type":"address"},{"name":"_reset","type":"bool"}],"name":"transferPoint","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"_galaxy","type":"uint8"},{"name":"_target","type":"address"}],"name":"createGalaxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_transferProxy","type":"address"}],"name":"setTransferProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","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":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_encryptionKey","type":"bytes32"},{"name":"_authenticationKey","type":"bytes32"},{"name":"_cryptoSuiteVersion","type":"uint32"},{"name":"_discontinuous","type":"bool"}],"name":"configureKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_point","type":"uint32"},{"name":"_sponsor","type":"uint32"}],"name":"canEscapeTo","outputs":[{"name":"canEscape","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"doesExist","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"address"},{"name":"_vote","type":"bool"}],"name":"castUpgradeVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposal","type":"address"}],"name":"updateUpgradePoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"bytes32"},{"name":"_vote","type":"bool"}],"name":"castDocumentVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_manager","type":"address"}],"name":"setManagementProxy","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":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"address"}],"name":"startUpgradePoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_target","type":"address"}],"name":"spawn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_voter","type":"address"}],"name":"setVotingProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_prefix","type":"uint16"},{"name":"_spawnProxy","type":"address"}],"name":"setSpawnProxy","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":"_primary","type":"string"},{"name":"_secondary","type":"string"},{"name":"_tertiary","type":"string"}],"name":"setDnsDomains","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"reject","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_sponsor","type":"uint32"}],"name":"escape","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"adopt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"cancelEscape","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"_tokenURI","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"azimuth","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"claims","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"polls","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"result","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"previousEcliptic","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_point","type":"uint32"},{"name":"_time","type":"uint256"}],"name":"getSpawnLimit","outputs":[{"name":"limit","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_previous","type":"address"},{"name":"_azimuth","type":"address"},{"name":"_polls","type":"address"},{"name":"_claims","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":false,"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"},{"anonymous":false,"inputs":[{"indexed":false,"name":"to","type":"address"}],"name":"Upgraded","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"}]

60806040523480156200001157600080fd5b5060405160808062004be683398101604090815281516020830151918301516060909301516000805433600160a060020a031991821617909155600180548216600160a060020a038087169190911790915560038054831682861617905560028054909216908616179055909290620000b37f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000174810204565b60058054600160a060020a031916600160a060020a038316179055620001027f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000174810204565b620001367f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000174810204565b6200016a7f7f5828d00000000000000000000000000000000000000000000000000000000064010000000062000174810204565b50505050620001e1565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620001a457600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600460205260409020805460ff19166001179055565b6149f580620001f16000396000f30060806040526004361061020b5763ffffffff60e060020a60003504166301ffc9a7811461021057806305bbf5db1461024657806306fdde0314610266578063073a7804146102f0578063081812fc1461030e578063095ea7b314610342578063172a735c146103665780631824a46b1461037e57806319fa8f50146103935780631e79a85b146103c557806323b872dd146103f457806326295b521461041e5780632c7ba5641461044557806342842e0e1461046f5780634447e48c146104995780634a013296146104ca5780634f558e79146104ee57806351de5541146105065780635623715b146105325780636352211e146105535780636eb582241461056b57806370a082311461058e578063715018a6146105c15780638866bb2c146105d65780638da5cb5b1461060057806395d89b41146106155780639e988d131461062a578063a0d3253f14610651578063a22cb4651461067b578063a60e8bd6146106a1578063ae326221146106c8578063b88d4fde146106f0578063bac55edd1461075f578063bbe21ca514610797578063bf5772b9146107b5578063c1b9d98b146107d9578063c6d761d4146107f7578063c87b56dd14610815578063d40ffacb1461082d578063dcc59b6f14610842578063e64853c414610857578063e985e9c51461086c578063ed969f6814610893578063ef20bff8146108a8578063f2fde38b146108e2575b600080fd5b34801561021c57600080fd5b50610232600160e060020a031960043516610903565b604080519115158252519081900360200190f35b34801561025257600080fd5b5061026460ff60043516602435610922565b005b34801561027257600080fd5b5061027b610ac1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102b557818101518382015260200161029d565b50505050905090810190601f1680156102e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102fc57600080fd5b5061026463ffffffff60043516610af8565b34801561031a57600080fd5b50610326600435610d39565b60408051600160a060020a039092168252519081900360200190f35b34801561034e57600080fd5b50610264600160a060020a0360043516602435610e79565b34801561037257600080fd5b50610264600435610e9a565b34801561038a57600080fd5b50610264610f2b565b34801561039f57600080fd5b506103a861106a565b60408051600160e060020a03199092168252519081900360200190f35b3480156103d157600080fd5b5061026463ffffffff60043516600160a060020a0360243516604435151561108e565b34801561040057600080fd5b50610264600160a060020a03600435811690602435166044356118d3565b34801561042a57600080fd5b5061026460ff60043516600160a060020a036024351661198b565b34801561045157600080fd5b5061026463ffffffff60043516600160a060020a0360243516611af0565b34801561047b57600080fd5b50610264600160a060020a0360043581169060243516604435611ced565b3480156104a557600080fd5b5061026463ffffffff6004358116906024359060443590606435166084351515611d09565b3480156104d657600080fd5b5061023263ffffffff60043581169060243516611f66565b3480156104fa57600080fd5b506102326004356121dd565b34801561051257600080fd5b5061026460ff60043516600160a060020a03602435166044351515612277565b34801561053e57600080fd5b50610264600160a060020a0360043516612448565b34801561055f57600080fd5b506103266004356124f0565b34801561057757600080fd5b5061026460ff60043516602435604435151561261f565b34801561059a57600080fd5b506105af600160a060020a03600435166127e5565b60408051918252519081900360200190f35b3480156105cd57600080fd5b50610264612864565b3480156105e257600080fd5b5061026463ffffffff60043516600160a060020a03602435166128d0565b34801561060c57600080fd5b50610326612a5f565b34801561062157600080fd5b5061027b612a6e565b34801561063657600080fd5b5061026460ff60043516600160a060020a0360243516612aa5565b34801561065d57600080fd5b5061026463ffffffff60043516600160a060020a0360243516612caf565b34801561068757600080fd5b50610264600160a060020a036004351660243515156131af565b3480156106ad57600080fd5b5061026460ff60043516600160a060020a0360243516613297565b3480156106d457600080fd5b5061026461ffff60043516600160a060020a0360243516613423565b3480156106fc57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261026494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506135b19650505050505050565b34801561076b57600080fd5b50610264602460048035828101929082013591813580830192908201359160443591820191013561371b565b3480156107a357600080fd5b5061026463ffffffff600435166137f4565b3480156107c157600080fd5b5061026463ffffffff60043581169060243516613a1a565b3480156107e557600080fd5b5061026463ffffffff60043516613bd4565b34801561080357600080fd5b5061026463ffffffff60043516613dfa565b34801561082157600080fd5b5061027b600435613fab565b34801561083957600080fd5b5061032661425e565b34801561084e57600080fd5b5061032661426d565b34801561086357600080fd5b5061032661427c565b34801561087857600080fd5b50610232600160a060020a036004358116906024351661428b565b34801561089f57600080fd5b506103266142fe565b3480156108b457600080fd5b506108c963ffffffff6004351660243561430d565b6040805163ffffffff9092168252519081900360200190f35b3480156108ee57600080fd5b50610264600160a060020a0360043516614403565b600160e060020a03191660009081526004602052604090205460ff1690565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561097d57600080fd5b505af1158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b50518015610a3357506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b505050506040513d6020811015610a3057600080fd5b50515b1515610a3e57600080fd5b600254604080517f9a33aff9000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a0390921691639a33aff99160248082019260009290919082900301818387803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b50505050505050565b60408051808201909152600e81527f417a696d75746820506f696e7473000000000000000000000000000000000000602082015290565b600154604080517f77eb4c5000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a03909216916377eb4c50916024808201926020929091908290030181600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d6020811015610b8e57600080fd5b50518015610ca85750600154604080517f439f7d3c00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163439f7d3c916024808201926020929091908290030181600087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b50515b1515610cb357600080fd5b600154604080517fbc562b9e00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163bc562b9e9160248082019260009290919082900301818387803b158015610d1e57600080fd5b505af1158015610d32573d6000803e3d6000fd5b5050505050565b6000816401000000008110610d4d57600080fd5b6001546040805160e060020a635e19b30502815263ffffffff861660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610dda57600080fd5b600154604080517f24541f7800000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a03909216916324541f78916024808201926020929091908290030181600087803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b505050506040513d6020811015610e7057600080fd5b50519392505050565b806401000000008110610e8b57600080fd5b610e958284611af0565b505050565b600254604080517f172a735c000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163172a735c916024808201926020929091908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b600354600160a060020a031633148015610fcb5750600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f9357600080fd5b505af1158015610fa7573d6000803e3d6000fd5b505050506040513d6020811015610fbd57600080fd5b5051600160a060020a031630145b801561105d5750600260009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b5051600160a060020a031630145b151561106857600080fd5b565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600154604080517f728aa85700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201523360248201529051600092600160a060020a03169163728aa85791604480830192602092919082900301818787803b1580156110ff57600080fd5b505af1158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b5051151561113657600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561118c57600080fd5b505af11580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b5051151561124257600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b505050505b6001546040805160e060020a63caf590f902815263ffffffff87166004820152600160a060020a0386811660248301529151919092169163caf590f99160448083019260209291908290030181600087803b1580156112a057600080fd5b505af11580156112b4573d6000803e3d6000fd5b505050506040513d60208110156112ca57600080fd5b5051151561149b576001546040805160e160020a63310d91f102815263ffffffff871660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b15801561132857600080fd5b505af115801561133c573d6000803e3d6000fd5b505050506040513d602081101561135257600080fd5b5051600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff88166004820152600160a060020a038781166024830152915193945091169163ddc359509160448082019260009290919082900301818387803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a038088169450851692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b81156118cd576001546040805160e060020a636d09887b02815263ffffffff871660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156114f757600080fd5b505af115801561150b573d6000803e3d6000fd5b505050506040513d602081101561152157600080fd5b50511561164157600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b15801561159357600080fd5b505af11580156115a7573d6000803e3d6000fd5b5050600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff8916600482015260006024820181905260448201819052606482018190529151600160a060020a03909316945063f9b87d4093506084808201939182900301818387803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b505050505b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526000602482018190529151600160a060020a0390931692638866bb2c9260448084019391929182900301818387803b1580156116b257600080fd5b505af11580156116c6573d6000803e3d6000fd5b5050600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a03909316945063a297c1d893506044808201939182900301818387803b15801561173957600080fd5b505af115801561174d573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b5050600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632a19642c93506044808201939182900301818387803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b5050600554604080517feaae46e500000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a03909216935063eaae46e5925060248082019260009290919082900301818387803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505b50505050565b60008164010000000081106118e757600080fd5b6001546040805160e060020a63caf590f902815263ffffffff86166004820152600160a060020a0388811660248301529151869550919092169163caf590f99160448083019260209291908290030181600087803b15801561194857600080fd5b505af115801561195c573d6000803e3d6000fd5b505050506040513d602081101561197257600080fd5b5051151561197f57600080fd5b610d328285600161108e565b600054600160a060020a031633146119a257600080fd5b6001546040805160e060020a63caf590f902815260ff851660048201526000602482018190529151600160a060020a039093169263caf590f992604480840193602093929083900390910190829087803b1580156119ff57600080fd5b505af1158015611a13573d6000803e3d6000fd5b505050506040513d6020811015611a2957600080fd5b50518015611a3f5750600160a060020a03811615155b1515611a4a57600080fd5b600260009054906101000a9004600160a060020a0316600160a060020a031663246d41a96040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611a9d57600080fd5b505af1158015611ab1573d6000803e3d6000fd5b50505050600160a060020a038116331415611adc57611ad78260ff168260016000614426565b611aec565b611aec8260ff1682600033614426565b5050565b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050506040513d6020811015611b6f57600080fd5b50519050600160a060020a038116331480611c205750600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523360248301529151919092169163b6363cf29160448083019260209291908290030181600087803b158015611bf357600080fd5b505af1158015611c07573d6000803e3d6000fd5b505050506040513d6020811015611c1d57600080fd5b50515b1515611c2b57600080fd5b6001546040805160e260020a630b1ee95902815263ffffffff86166004820152600160a060020a03858116602483015291519190921691632c7ba56491604480830192600092919082900301818387803b158015611c8857600080fd5b505af1158015611c9c573d6000803e3d6000fd5b50506040805163ffffffff871681529051600160a060020a038087169450851692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a3505050565b610e9583838360206040519081016040528060008152506135b1565b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8816600482015233602482015290518792600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015611d7a57600080fd5b505af1158015611d8e573d6000803e3d6000fd5b505050506040513d6020811015611da457600080fd5b50518015611e3057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015611e0357600080fd5b505af1158015611e17573d6000803e3d6000fd5b505050506040513d6020811015611e2d57600080fd5b50515b1515611e3b57600080fd5b8115611ec557600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b158015611eac57600080fd5b505af1158015611ec0573d6000803e3d6000fd5b505050505b600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff808a1660048301526024820189905260448201889052861660648201529051600160a060020a039092169163f9b87d409160848082019260009290919082900301818387803b158015611f4657600080fd5b505af1158015611f5a573d6000803e3d6000fd5b50505050505050505050565b6001546040805160e060020a636d09887b02815263ffffffff84166004820152905160009283928392600160a060020a0390921691636d09887b9160248082019260209290919082900301818787803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d6020811015611fec57600080fd5b50511515611ffd57600092506121d5565b6001546040805160e060020a639397640502815263ffffffff881660048201529051600160a060020a03909216916393976405916024808201926020929091908290030181600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d602081101561207d57600080fd5b50516001546040805160e060020a639397640502815263ffffffff881660048201529051929450600160a060020a03909116916393976405916024808201926020929091908290030181600087803b1580156120d857600080fd5b505af11580156120ec573d6000803e3d6000fd5b505050506040513d602081101561210257600080fd5b5051905081600281111561211257fe5b60ff1681600281111561212157fe5b60010160ff1614806121d2575081600281111561213a57fe5b81600281111561214657fe5b1480156121d257506001546040805160e060020a636d09887b02815263ffffffff881660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156121a457600080fd5b505af11580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b5051155b92505b505092915050565b60006401000000008210801561227157506001546040805160e060020a635e19b30502815263ffffffff851660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b505050506040513d602081101561226e57600080fd5b50515b92915050565b6001546040805160e060020a63b65afedd02815260ff8616600482018190523360248301529151600093600160a060020a03169163b65afedd91604480830192602092919082900301818887803b1580156122d157600080fd5b505af11580156122e5573d6000803e3d6000fd5b505050506040513d60208110156122fb57600080fd5b5051801561238757506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505050506040513d602081101561238457600080fd5b50515b151561239257600080fd5b600254604080517f51de554100000000000000000000000000000000000000000000000000000000815260ff88166004820152600160a060020a0387811660248301528615156044830152915191909216916351de55419160648083019260209291908290030181600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b505050506040513d602081101561243557600080fd5b505191508115610d3257610d32846147a7565b600254604080517f5623715b000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691635623715b9160248082019260209290919082900301818787803b1580156124b357600080fd5b505af11580156124c7573d6000803e3d6000fd5b505050506040513d60208110156124dd57600080fd5b505190508015611aec57611aec826147a7565b60008082640100000000811061250557600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051869450600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561255e57600080fd5b505af1158015612572573d6000803e3d6000fd5b505050506040513d602081101561258857600080fd5b5051151561259557600080fd5b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d602081101561261557600080fd5b5051949350505050565b6001546040805160e060020a63b65afedd02815260ff86166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561267a57600080fd5b505af115801561268e573d6000803e3d6000fd5b505050506040513d60208110156126a457600080fd5b5051801561273057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561270357600080fd5b505af1158015612717573d6000803e3d6000fd5b505050506040513d602081101561272d57600080fd5b50515b151561273b57600080fd5b600254604080517f6eb5822400000000000000000000000000000000000000000000000000000000815260ff871660048201526024810186905284151560448201529051600160a060020a0390921691636eb58224916064808201926020929091908290030181600087803b1580156127b357600080fd5b505af11580156127c7573d6000803e3d6000fd5b505050506040513d60208110156127dd57600080fd5b505050505050565b6000600160a060020a03821615156127fc57600080fd5b600154604080517f12afbc78000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916312afbc789160248083019260209291908290030181600087803b15801561224457600080fd5b600054600160a060020a0316331461287b57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001546040805160e060020a63caf590f902815263ffffffff8516600482015233602482015290518492600160a060020a03169163caf590f99160448083019260209291908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b505180156129e157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b1580156129b457600080fd5b505af11580156129c8573d6000803e3d6000fd5b505050506040513d60208110156129de57600080fd5b50515b15156129ec57600080fd5b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff86166004820152600160a060020a03858116602483015291519190921691638866bb2c91604480830192600092919082900301818387803b158015610aa457600080fd5b600054600160a060020a031681565b60408051808201909152600381527f415a500000000000000000000000000000000000000000000000000000000000602082015290565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b158015612b0057600080fd5b505af1158015612b14573d6000803e3d6000fd5b505050506040513d6020811015612b2a57600080fd5b50518015612bb657506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015612b8957600080fd5b505af1158015612b9d573d6000803e3d6000fd5b505050506040513d6020811015612bb357600080fd5b50515b1515612bc157600080fd5b30600160a060020a031682600160a060020a031663ed969f686040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612c0957600080fd5b505af1158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b5051600160a060020a031614612c4857600080fd5b600254604080517fe31f3e0c000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163e31f3e0c91602480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815263ffffffff8516600482015260006024820181905291519192600160a060020a03169163caf590f99160448082019260209290919082900301818787803b158015612d0d57600080fd5b505af1158015612d21573d6000803e3d6000fd5b505050506040513d6020811015612d3757600080fd5b50511515612d4457600080fd5b600154604080517fe4a358d700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a039092169163e4a358d7916024808201926020929091908290030181600087803b158015612db057600080fd5b505af1158015612dc4573d6000803e3d6000fd5b505050506040513d6020811015612dda57600080fd5b50516001546040805160e060020a639397640502815263ffffffff871660048201529051929350600160a060020a03909116916393976405916024808201926020929091908290030181600087803b158015612e3557600080fd5b505af1158015612e49573d6000803e3d6000fd5b505050506040513d6020811015612e5f57600080fd5b50516002811115612e6c57fe5b6001546040805160e060020a639397640502815261ffff85166004820152905160ff9390931692600160a060020a03909216916393976405916024808201926020929091908290030181600087803b158015612ec757600080fd5b505af1158015612edb573d6000803e3d6000fd5b505050506040513d6020811015612ef157600080fd5b50516002811115612efe57fe5b60010160ff16141515612f1057600080fd5b6001546040805160e060020a636d09887b02815261ffff841660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b158015612f6457600080fd5b505af1158015612f78573d6000803e3d6000fd5b505050506040513d6020811015612f8e57600080fd5b5051801561304d5750612fa58161ffff164261430d565b600154604080517f293a916900000000000000000000000000000000000000000000000000000000815261ffff85166004820152905163ffffffff9390931692600160a060020a039092169163293a9169916024808201926020929091908290030181600087803b15801561301957600080fd5b505af115801561302d573d6000803e3d6000fd5b505050506040513d602081101561304357600080fd5b505163ffffffff16105b151561305857600080fd5b600154604080517f8a27bf5900000000000000000000000000000000000000000000000000000000815261ffff841660048201523360248201529051600160a060020a0390921691638a27bf59916044808201926020929091908290030181600087803b1580156130c857600080fd5b505af11580156130dc573d6000803e3d6000fd5b505050506040513d60208110156130f257600080fd5b505115156130ff57600080fd5b33600160a060020a03831614156131235761311e838360016000614426565b610e95565b6001546040805160e160020a63310d91f102815261ffff841660048201529051610e959286928692600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050506040513d60208110156131a857600080fd5b5051614426565b600160a060020a03821615156131c457600080fd5b600154604080517fbc735d90000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03858116602483015284151560448301529151919092169163bc735d9091606480830192600092919082900301818387803b15801561323957600080fd5b505af115801561324d573d6000803e3d6000fd5b50506040805184151581529051600160a060020a03861693503392507f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6001546040805160e060020a63caf590f902815260ff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b1580156132f257600080fd5b505af1158015613306573d6000803e3d6000fd5b505050506040513d602081101561331c57600080fd5b505180156133a857506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561337b57600080fd5b505af115801561338f573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b50515b15156133b357600080fd5b600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815260ff86166004820152600160a060020a0385811660248301529151919092169163a297c1d891604480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815261ffff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b15801561347f57600080fd5b505af1158015613493573d6000803e3d6000fd5b505050506040513d60208110156134a957600080fd5b5051801561353557506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050506040513d602081101561353257600080fd5b50515b151561354057600080fd5b600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815261ffff86166004820152600160a060020a03858116602483015291519190921691632a19642c91604480830192600092919082900301818387803b158015610aa457600080fd5b60006135be8585856118d3565b6135d084600160a060020a0316614944565b15610d32576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038881166024850152604484018790526080606485019081528651608486015286519189169463150b7a0294938b938a938a93909160a490910190602085019080838360005b83811015613668578181015183820152602001613650565b50505050905090810190601f1680156136955780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156136b757600080fd5b505af11580156136cb573d6000803e3d6000fd5b505050506040513d60208110156136e157600080fd5b50519050600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014610d3257600080fd5b600054600160a060020a0316331461373257600080fd5b6001546040517fbac55edd00000000000000000000000000000000000000000000000000000000815260606004820190815260648201889052600160a060020a039092169163bac55edd918991899189918991899189918190602481019060448101906084018a8a80828437909101858103845288815260200190508888808284379091018581038352868152602001905086868082843782019150509950505050505050505050600060405180830381600087803b158015611f4657600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b15801561386057600080fd5b505af1158015613874573d6000803e3d6000fd5b505050506040513d602081101561388a57600080fd5b505180156139a45750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b15801561390757600080fd5b505af115801561391b573d6000803e3d6000fd5b505050506040513d602081101561393157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050506040513d60208110156139a157600080fd5b50515b15156139af57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8516600482015233602482015290518492600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050506040513d6020811015613ab557600080fd5b50518015613b4157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613b1457600080fd5b505af1158015613b28573d6000803e3d6000fd5b505050506040513d6020811015613b3e57600080fd5b50515b1515613b4c57600080fd5b613b568383611f66565b1515613b6157600080fd5b600154604080517fa634585900000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152851660248201529051600160a060020a039092169163a63458599160448082019260009290919082900301818387803b158015610aa457600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b158015613c4057600080fd5b505af1158015613c54573d6000803e3d6000fd5b505050506040513d6020811015613c6a57600080fd5b50518015613d845750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b505050506040513d6020811015613d1157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015613d5757600080fd5b505af1158015613d6b573d6000803e3d6000fd5b505050506040513d6020811015613d8157600080fd5b50515b1515613d8f57600080fd5b600154604080517f1306318000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163130631809160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8416600482015233602482015290518392600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613e6b57600080fd5b505af1158015613e7f573d6000803e3d6000fd5b505050506040513d6020811015613e9557600080fd5b50518015613f2157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613ef457600080fd5b505af1158015613f08573d6000803e3d6000fd5b505050506040513d6020811015613f1e57600080fd5b50515b1515613f2c57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff851660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015613f9757600080fd5b505af11580156127dd573d6000803e3d6000fd5b606080826401000000008110613fc057600080fd5b60408051606081018252602e81527f68747470733a2f2f617a696d7574682e6e6574776f726b2f6572633732312f3060208201527f3030303030303030302e6a736f6e0000000000000000000000000000000000009181019190915292508291507fff00000000000000000000000000000000000000000000000000000000000000600a633b9aca0086040660300160f860020a0216600081901a603f84015350600a6305f5e10085040660300160f860020a0282602081518110151561408357fe5b906020010190600160f860020a031916908160001a905350600a6298968085040660300160f860020a028260218151811015156140bc57fe5b906020010190600160f860020a031916908160001a905350600a620f424085040660300160f860020a028260228151811015156140f557fe5b906020010190600160f860020a031916908160001a905350600a620186a085040660300160f860020a0282602381518110151561412e57fe5b906020010190600160f860020a031916908160001a905350600a61271085040660300160f860020a0282602481518110151561416657fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602581518110151561419e57fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a028260268151811015156141d557fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602781518110151561420b57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602881518110151561423f57fe5b906020010190600160f860020a031916908160001a9053505050919050565b600154600160a060020a031681565b600554600160a060020a031681565b600254600160a060020a031681565b600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163b6363cf29160448082019260209290919082900301818787803b158015610e4657600080fd5b600354600160a060020a031681565b6001546040805160e060020a639397640502815263ffffffff85166004820152905160009283928392600160a060020a039092169163939764059160248082019260209290919082900301818787803b15801561436957600080fd5b505af115801561437d573d6000803e3d6000fd5b505050506040513d602081101561439357600080fd5b5051915060008260028111156143a557fe5b14156143b45760ff92506121d5565b60018260028111156143c257fe5b14156143fa57506301e13380635c2aad7f1984010460068110156143ef578060020a6104000292506143f5565b61ffff92505b6121d5565b600092506121d5565b600054600160a060020a0316331461441a57600080fd5b6144238161494c565b50565b600154604080517fc17ad9d800000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163c17ad9d89160248082019260009290919082900301818387803b15801561449157600080fd5b505af11580156144a5573d6000803e3d6000fd5b50505050811561460957600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561451a57600080fd5b505af115801561452e573d6000803e3d6000fd5b5050600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff89166004820152600160a060020a038881166024830152915191909216935063ddc359509250604480830192600092919082900301818387803b1580156145a557600080fd5b505af11580156145b9573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36118cd565b600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff87166004820152600160a060020a0384811660248301529151919092169163ddc3595091604480830192600092919082900301818387803b15801561467c57600080fd5b505af1158015614690573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff89166004820152600160a060020a0388811660248301529151919092169350632c7ba5649250604480830192600092919082900301818387803b1580156146f157600080fd5b505af1158015614705573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0385169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a382600160a060020a031681600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258663ffffffff166040518082815260200191505060405180910390a350505050565b600154604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163f2fde38b91602480830192600092919082900301818387803b15801561480e57600080fd5b505af1158015614822573d6000803e3d6000fd5b5050600254604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216935063f2fde38b9250602480830192600092919082900301818387803b15801561488d57600080fd5b505af11580156148a1573d6000803e3d6000fd5b5050505080600160a060020a0316631824a46b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156148e357600080fd5b505af11580156148f7573d6000803e3d6000fd5b505060408051600160a060020a038516815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9350908190036020019150a180600160a060020a0316ff5b6000903b1190565b600160a060020a038116151561496157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582053db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad0029000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a

Deployed Bytecode

0x60806040526004361061020b5763ffffffff60e060020a60003504166301ffc9a7811461021057806305bbf5db1461024657806306fdde0314610266578063073a7804146102f0578063081812fc1461030e578063095ea7b314610342578063172a735c146103665780631824a46b1461037e57806319fa8f50146103935780631e79a85b146103c557806323b872dd146103f457806326295b521461041e5780632c7ba5641461044557806342842e0e1461046f5780634447e48c146104995780634a013296146104ca5780634f558e79146104ee57806351de5541146105065780635623715b146105325780636352211e146105535780636eb582241461056b57806370a082311461058e578063715018a6146105c15780638866bb2c146105d65780638da5cb5b1461060057806395d89b41146106155780639e988d131461062a578063a0d3253f14610651578063a22cb4651461067b578063a60e8bd6146106a1578063ae326221146106c8578063b88d4fde146106f0578063bac55edd1461075f578063bbe21ca514610797578063bf5772b9146107b5578063c1b9d98b146107d9578063c6d761d4146107f7578063c87b56dd14610815578063d40ffacb1461082d578063dcc59b6f14610842578063e64853c414610857578063e985e9c51461086c578063ed969f6814610893578063ef20bff8146108a8578063f2fde38b146108e2575b600080fd5b34801561021c57600080fd5b50610232600160e060020a031960043516610903565b604080519115158252519081900360200190f35b34801561025257600080fd5b5061026460ff60043516602435610922565b005b34801561027257600080fd5b5061027b610ac1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102b557818101518382015260200161029d565b50505050905090810190601f1680156102e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102fc57600080fd5b5061026463ffffffff60043516610af8565b34801561031a57600080fd5b50610326600435610d39565b60408051600160a060020a039092168252519081900360200190f35b34801561034e57600080fd5b50610264600160a060020a0360043516602435610e79565b34801561037257600080fd5b50610264600435610e9a565b34801561038a57600080fd5b50610264610f2b565b34801561039f57600080fd5b506103a861106a565b60408051600160e060020a03199092168252519081900360200190f35b3480156103d157600080fd5b5061026463ffffffff60043516600160a060020a0360243516604435151561108e565b34801561040057600080fd5b50610264600160a060020a03600435811690602435166044356118d3565b34801561042a57600080fd5b5061026460ff60043516600160a060020a036024351661198b565b34801561045157600080fd5b5061026463ffffffff60043516600160a060020a0360243516611af0565b34801561047b57600080fd5b50610264600160a060020a0360043581169060243516604435611ced565b3480156104a557600080fd5b5061026463ffffffff6004358116906024359060443590606435166084351515611d09565b3480156104d657600080fd5b5061023263ffffffff60043581169060243516611f66565b3480156104fa57600080fd5b506102326004356121dd565b34801561051257600080fd5b5061026460ff60043516600160a060020a03602435166044351515612277565b34801561053e57600080fd5b50610264600160a060020a0360043516612448565b34801561055f57600080fd5b506103266004356124f0565b34801561057757600080fd5b5061026460ff60043516602435604435151561261f565b34801561059a57600080fd5b506105af600160a060020a03600435166127e5565b60408051918252519081900360200190f35b3480156105cd57600080fd5b50610264612864565b3480156105e257600080fd5b5061026463ffffffff60043516600160a060020a03602435166128d0565b34801561060c57600080fd5b50610326612a5f565b34801561062157600080fd5b5061027b612a6e565b34801561063657600080fd5b5061026460ff60043516600160a060020a0360243516612aa5565b34801561065d57600080fd5b5061026463ffffffff60043516600160a060020a0360243516612caf565b34801561068757600080fd5b50610264600160a060020a036004351660243515156131af565b3480156106ad57600080fd5b5061026460ff60043516600160a060020a0360243516613297565b3480156106d457600080fd5b5061026461ffff60043516600160a060020a0360243516613423565b3480156106fc57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261026494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506135b19650505050505050565b34801561076b57600080fd5b50610264602460048035828101929082013591813580830192908201359160443591820191013561371b565b3480156107a357600080fd5b5061026463ffffffff600435166137f4565b3480156107c157600080fd5b5061026463ffffffff60043581169060243516613a1a565b3480156107e557600080fd5b5061026463ffffffff60043516613bd4565b34801561080357600080fd5b5061026463ffffffff60043516613dfa565b34801561082157600080fd5b5061027b600435613fab565b34801561083957600080fd5b5061032661425e565b34801561084e57600080fd5b5061032661426d565b34801561086357600080fd5b5061032661427c565b34801561087857600080fd5b50610232600160a060020a036004358116906024351661428b565b34801561089f57600080fd5b506103266142fe565b3480156108b457600080fd5b506108c963ffffffff6004351660243561430d565b6040805163ffffffff9092168252519081900360200190f35b3480156108ee57600080fd5b50610264600160a060020a0360043516614403565b600160e060020a03191660009081526004602052604090205460ff1690565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561097d57600080fd5b505af1158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b50518015610a3357506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b505050506040513d6020811015610a3057600080fd5b50515b1515610a3e57600080fd5b600254604080517f9a33aff9000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a0390921691639a33aff99160248082019260009290919082900301818387803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b50505050505050565b60408051808201909152600e81527f417a696d75746820506f696e7473000000000000000000000000000000000000602082015290565b600154604080517f77eb4c5000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a03909216916377eb4c50916024808201926020929091908290030181600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d6020811015610b8e57600080fd5b50518015610ca85750600154604080517f439f7d3c00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163439f7d3c916024808201926020929091908290030181600087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b50515b1515610cb357600080fd5b600154604080517fbc562b9e00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163bc562b9e9160248082019260009290919082900301818387803b158015610d1e57600080fd5b505af1158015610d32573d6000803e3d6000fd5b5050505050565b6000816401000000008110610d4d57600080fd5b6001546040805160e060020a635e19b30502815263ffffffff861660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610dda57600080fd5b600154604080517f24541f7800000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a03909216916324541f78916024808201926020929091908290030181600087803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b505050506040513d6020811015610e7057600080fd5b50519392505050565b806401000000008110610e8b57600080fd5b610e958284611af0565b505050565b600254604080517f172a735c000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163172a735c916024808201926020929091908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b600354600160a060020a031633148015610fcb5750600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f9357600080fd5b505af1158015610fa7573d6000803e3d6000fd5b505050506040513d6020811015610fbd57600080fd5b5051600160a060020a031630145b801561105d5750600260009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b5051600160a060020a031630145b151561106857600080fd5b565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600154604080517f728aa85700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201523360248201529051600092600160a060020a03169163728aa85791604480830192602092919082900301818787803b1580156110ff57600080fd5b505af1158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b5051151561113657600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561118c57600080fd5b505af11580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b5051151561124257600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b505050505b6001546040805160e060020a63caf590f902815263ffffffff87166004820152600160a060020a0386811660248301529151919092169163caf590f99160448083019260209291908290030181600087803b1580156112a057600080fd5b505af11580156112b4573d6000803e3d6000fd5b505050506040513d60208110156112ca57600080fd5b5051151561149b576001546040805160e160020a63310d91f102815263ffffffff871660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b15801561132857600080fd5b505af115801561133c573d6000803e3d6000fd5b505050506040513d602081101561135257600080fd5b5051600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff88166004820152600160a060020a038781166024830152915193945091169163ddc359509160448082019260009290919082900301818387803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a038088169450851692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b81156118cd576001546040805160e060020a636d09887b02815263ffffffff871660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156114f757600080fd5b505af115801561150b573d6000803e3d6000fd5b505050506040513d602081101561152157600080fd5b50511561164157600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b15801561159357600080fd5b505af11580156115a7573d6000803e3d6000fd5b5050600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff8916600482015260006024820181905260448201819052606482018190529151600160a060020a03909316945063f9b87d4093506084808201939182900301818387803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b505050505b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526000602482018190529151600160a060020a0390931692638866bb2c9260448084019391929182900301818387803b1580156116b257600080fd5b505af11580156116c6573d6000803e3d6000fd5b5050600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a03909316945063a297c1d893506044808201939182900301818387803b15801561173957600080fd5b505af115801561174d573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b5050600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632a19642c93506044808201939182900301818387803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b5050600554604080517feaae46e500000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a03909216935063eaae46e5925060248082019260009290919082900301818387803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505b50505050565b60008164010000000081106118e757600080fd5b6001546040805160e060020a63caf590f902815263ffffffff86166004820152600160a060020a0388811660248301529151869550919092169163caf590f99160448083019260209291908290030181600087803b15801561194857600080fd5b505af115801561195c573d6000803e3d6000fd5b505050506040513d602081101561197257600080fd5b5051151561197f57600080fd5b610d328285600161108e565b600054600160a060020a031633146119a257600080fd5b6001546040805160e060020a63caf590f902815260ff851660048201526000602482018190529151600160a060020a039093169263caf590f992604480840193602093929083900390910190829087803b1580156119ff57600080fd5b505af1158015611a13573d6000803e3d6000fd5b505050506040513d6020811015611a2957600080fd5b50518015611a3f5750600160a060020a03811615155b1515611a4a57600080fd5b600260009054906101000a9004600160a060020a0316600160a060020a031663246d41a96040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611a9d57600080fd5b505af1158015611ab1573d6000803e3d6000fd5b50505050600160a060020a038116331415611adc57611ad78260ff168260016000614426565b611aec565b611aec8260ff1682600033614426565b5050565b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050506040513d6020811015611b6f57600080fd5b50519050600160a060020a038116331480611c205750600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523360248301529151919092169163b6363cf29160448083019260209291908290030181600087803b158015611bf357600080fd5b505af1158015611c07573d6000803e3d6000fd5b505050506040513d6020811015611c1d57600080fd5b50515b1515611c2b57600080fd5b6001546040805160e260020a630b1ee95902815263ffffffff86166004820152600160a060020a03858116602483015291519190921691632c7ba56491604480830192600092919082900301818387803b158015611c8857600080fd5b505af1158015611c9c573d6000803e3d6000fd5b50506040805163ffffffff871681529051600160a060020a038087169450851692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a3505050565b610e9583838360206040519081016040528060008152506135b1565b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8816600482015233602482015290518792600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015611d7a57600080fd5b505af1158015611d8e573d6000803e3d6000fd5b505050506040513d6020811015611da457600080fd5b50518015611e3057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015611e0357600080fd5b505af1158015611e17573d6000803e3d6000fd5b505050506040513d6020811015611e2d57600080fd5b50515b1515611e3b57600080fd5b8115611ec557600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b158015611eac57600080fd5b505af1158015611ec0573d6000803e3d6000fd5b505050505b600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff808a1660048301526024820189905260448201889052861660648201529051600160a060020a039092169163f9b87d409160848082019260009290919082900301818387803b158015611f4657600080fd5b505af1158015611f5a573d6000803e3d6000fd5b50505050505050505050565b6001546040805160e060020a636d09887b02815263ffffffff84166004820152905160009283928392600160a060020a0390921691636d09887b9160248082019260209290919082900301818787803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d6020811015611fec57600080fd5b50511515611ffd57600092506121d5565b6001546040805160e060020a639397640502815263ffffffff881660048201529051600160a060020a03909216916393976405916024808201926020929091908290030181600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d602081101561207d57600080fd5b50516001546040805160e060020a639397640502815263ffffffff881660048201529051929450600160a060020a03909116916393976405916024808201926020929091908290030181600087803b1580156120d857600080fd5b505af11580156120ec573d6000803e3d6000fd5b505050506040513d602081101561210257600080fd5b5051905081600281111561211257fe5b60ff1681600281111561212157fe5b60010160ff1614806121d2575081600281111561213a57fe5b81600281111561214657fe5b1480156121d257506001546040805160e060020a636d09887b02815263ffffffff881660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156121a457600080fd5b505af11580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b5051155b92505b505092915050565b60006401000000008210801561227157506001546040805160e060020a635e19b30502815263ffffffff851660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b505050506040513d602081101561226e57600080fd5b50515b92915050565b6001546040805160e060020a63b65afedd02815260ff8616600482018190523360248301529151600093600160a060020a03169163b65afedd91604480830192602092919082900301818887803b1580156122d157600080fd5b505af11580156122e5573d6000803e3d6000fd5b505050506040513d60208110156122fb57600080fd5b5051801561238757506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505050506040513d602081101561238457600080fd5b50515b151561239257600080fd5b600254604080517f51de554100000000000000000000000000000000000000000000000000000000815260ff88166004820152600160a060020a0387811660248301528615156044830152915191909216916351de55419160648083019260209291908290030181600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b505050506040513d602081101561243557600080fd5b505191508115610d3257610d32846147a7565b600254604080517f5623715b000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691635623715b9160248082019260209290919082900301818787803b1580156124b357600080fd5b505af11580156124c7573d6000803e3d6000fd5b505050506040513d60208110156124dd57600080fd5b505190508015611aec57611aec826147a7565b60008082640100000000811061250557600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051869450600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561255e57600080fd5b505af1158015612572573d6000803e3d6000fd5b505050506040513d602081101561258857600080fd5b5051151561259557600080fd5b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d602081101561261557600080fd5b5051949350505050565b6001546040805160e060020a63b65afedd02815260ff86166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561267a57600080fd5b505af115801561268e573d6000803e3d6000fd5b505050506040513d60208110156126a457600080fd5b5051801561273057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561270357600080fd5b505af1158015612717573d6000803e3d6000fd5b505050506040513d602081101561272d57600080fd5b50515b151561273b57600080fd5b600254604080517f6eb5822400000000000000000000000000000000000000000000000000000000815260ff871660048201526024810186905284151560448201529051600160a060020a0390921691636eb58224916064808201926020929091908290030181600087803b1580156127b357600080fd5b505af11580156127c7573d6000803e3d6000fd5b505050506040513d60208110156127dd57600080fd5b505050505050565b6000600160a060020a03821615156127fc57600080fd5b600154604080517f12afbc78000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916312afbc789160248083019260209291908290030181600087803b15801561224457600080fd5b600054600160a060020a0316331461287b57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001546040805160e060020a63caf590f902815263ffffffff8516600482015233602482015290518492600160a060020a03169163caf590f99160448083019260209291908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b505180156129e157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b1580156129b457600080fd5b505af11580156129c8573d6000803e3d6000fd5b505050506040513d60208110156129de57600080fd5b50515b15156129ec57600080fd5b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff86166004820152600160a060020a03858116602483015291519190921691638866bb2c91604480830192600092919082900301818387803b158015610aa457600080fd5b600054600160a060020a031681565b60408051808201909152600381527f415a500000000000000000000000000000000000000000000000000000000000602082015290565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b158015612b0057600080fd5b505af1158015612b14573d6000803e3d6000fd5b505050506040513d6020811015612b2a57600080fd5b50518015612bb657506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015612b8957600080fd5b505af1158015612b9d573d6000803e3d6000fd5b505050506040513d6020811015612bb357600080fd5b50515b1515612bc157600080fd5b30600160a060020a031682600160a060020a031663ed969f686040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612c0957600080fd5b505af1158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b5051600160a060020a031614612c4857600080fd5b600254604080517fe31f3e0c000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163e31f3e0c91602480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815263ffffffff8516600482015260006024820181905291519192600160a060020a03169163caf590f99160448082019260209290919082900301818787803b158015612d0d57600080fd5b505af1158015612d21573d6000803e3d6000fd5b505050506040513d6020811015612d3757600080fd5b50511515612d4457600080fd5b600154604080517fe4a358d700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a039092169163e4a358d7916024808201926020929091908290030181600087803b158015612db057600080fd5b505af1158015612dc4573d6000803e3d6000fd5b505050506040513d6020811015612dda57600080fd5b50516001546040805160e060020a639397640502815263ffffffff871660048201529051929350600160a060020a03909116916393976405916024808201926020929091908290030181600087803b158015612e3557600080fd5b505af1158015612e49573d6000803e3d6000fd5b505050506040513d6020811015612e5f57600080fd5b50516002811115612e6c57fe5b6001546040805160e060020a639397640502815261ffff85166004820152905160ff9390931692600160a060020a03909216916393976405916024808201926020929091908290030181600087803b158015612ec757600080fd5b505af1158015612edb573d6000803e3d6000fd5b505050506040513d6020811015612ef157600080fd5b50516002811115612efe57fe5b60010160ff16141515612f1057600080fd5b6001546040805160e060020a636d09887b02815261ffff841660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b158015612f6457600080fd5b505af1158015612f78573d6000803e3d6000fd5b505050506040513d6020811015612f8e57600080fd5b5051801561304d5750612fa58161ffff164261430d565b600154604080517f293a916900000000000000000000000000000000000000000000000000000000815261ffff85166004820152905163ffffffff9390931692600160a060020a039092169163293a9169916024808201926020929091908290030181600087803b15801561301957600080fd5b505af115801561302d573d6000803e3d6000fd5b505050506040513d602081101561304357600080fd5b505163ffffffff16105b151561305857600080fd5b600154604080517f8a27bf5900000000000000000000000000000000000000000000000000000000815261ffff841660048201523360248201529051600160a060020a0390921691638a27bf59916044808201926020929091908290030181600087803b1580156130c857600080fd5b505af11580156130dc573d6000803e3d6000fd5b505050506040513d60208110156130f257600080fd5b505115156130ff57600080fd5b33600160a060020a03831614156131235761311e838360016000614426565b610e95565b6001546040805160e160020a63310d91f102815261ffff841660048201529051610e959286928692600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050506040513d60208110156131a857600080fd5b5051614426565b600160a060020a03821615156131c457600080fd5b600154604080517fbc735d90000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03858116602483015284151560448301529151919092169163bc735d9091606480830192600092919082900301818387803b15801561323957600080fd5b505af115801561324d573d6000803e3d6000fd5b50506040805184151581529051600160a060020a03861693503392507f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6001546040805160e060020a63caf590f902815260ff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b1580156132f257600080fd5b505af1158015613306573d6000803e3d6000fd5b505050506040513d602081101561331c57600080fd5b505180156133a857506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561337b57600080fd5b505af115801561338f573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b50515b15156133b357600080fd5b600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815260ff86166004820152600160a060020a0385811660248301529151919092169163a297c1d891604480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815261ffff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b15801561347f57600080fd5b505af1158015613493573d6000803e3d6000fd5b505050506040513d60208110156134a957600080fd5b5051801561353557506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050506040513d602081101561353257600080fd5b50515b151561354057600080fd5b600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815261ffff86166004820152600160a060020a03858116602483015291519190921691632a19642c91604480830192600092919082900301818387803b158015610aa457600080fd5b60006135be8585856118d3565b6135d084600160a060020a0316614944565b15610d32576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038881166024850152604484018790526080606485019081528651608486015286519189169463150b7a0294938b938a938a93909160a490910190602085019080838360005b83811015613668578181015183820152602001613650565b50505050905090810190601f1680156136955780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156136b757600080fd5b505af11580156136cb573d6000803e3d6000fd5b505050506040513d60208110156136e157600080fd5b50519050600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014610d3257600080fd5b600054600160a060020a0316331461373257600080fd5b6001546040517fbac55edd00000000000000000000000000000000000000000000000000000000815260606004820190815260648201889052600160a060020a039092169163bac55edd918991899189918991899189918190602481019060448101906084018a8a80828437909101858103845288815260200190508888808284379091018581038352868152602001905086868082843782019150509950505050505050505050600060405180830381600087803b158015611f4657600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b15801561386057600080fd5b505af1158015613874573d6000803e3d6000fd5b505050506040513d602081101561388a57600080fd5b505180156139a45750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b15801561390757600080fd5b505af115801561391b573d6000803e3d6000fd5b505050506040513d602081101561393157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050506040513d60208110156139a157600080fd5b50515b15156139af57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8516600482015233602482015290518492600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050506040513d6020811015613ab557600080fd5b50518015613b4157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613b1457600080fd5b505af1158015613b28573d6000803e3d6000fd5b505050506040513d6020811015613b3e57600080fd5b50515b1515613b4c57600080fd5b613b568383611f66565b1515613b6157600080fd5b600154604080517fa634585900000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152851660248201529051600160a060020a039092169163a63458599160448082019260009290919082900301818387803b158015610aa457600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b158015613c4057600080fd5b505af1158015613c54573d6000803e3d6000fd5b505050506040513d6020811015613c6a57600080fd5b50518015613d845750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b505050506040513d6020811015613d1157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015613d5757600080fd5b505af1158015613d6b573d6000803e3d6000fd5b505050506040513d6020811015613d8157600080fd5b50515b1515613d8f57600080fd5b600154604080517f1306318000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163130631809160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8416600482015233602482015290518392600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613e6b57600080fd5b505af1158015613e7f573d6000803e3d6000fd5b505050506040513d6020811015613e9557600080fd5b50518015613f2157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613ef457600080fd5b505af1158015613f08573d6000803e3d6000fd5b505050506040513d6020811015613f1e57600080fd5b50515b1515613f2c57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff851660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015613f9757600080fd5b505af11580156127dd573d6000803e3d6000fd5b606080826401000000008110613fc057600080fd5b60408051606081018252602e81527f68747470733a2f2f617a696d7574682e6e6574776f726b2f6572633732312f3060208201527f3030303030303030302e6a736f6e0000000000000000000000000000000000009181019190915292508291507fff00000000000000000000000000000000000000000000000000000000000000600a633b9aca0086040660300160f860020a0216600081901a603f84015350600a6305f5e10085040660300160f860020a0282602081518110151561408357fe5b906020010190600160f860020a031916908160001a905350600a6298968085040660300160f860020a028260218151811015156140bc57fe5b906020010190600160f860020a031916908160001a905350600a620f424085040660300160f860020a028260228151811015156140f557fe5b906020010190600160f860020a031916908160001a905350600a620186a085040660300160f860020a0282602381518110151561412e57fe5b906020010190600160f860020a031916908160001a905350600a61271085040660300160f860020a0282602481518110151561416657fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602581518110151561419e57fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a028260268151811015156141d557fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602781518110151561420b57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602881518110151561423f57fe5b906020010190600160f860020a031916908160001a9053505050919050565b600154600160a060020a031681565b600554600160a060020a031681565b600254600160a060020a031681565b600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163b6363cf29160448082019260209290919082900301818787803b158015610e4657600080fd5b600354600160a060020a031681565b6001546040805160e060020a639397640502815263ffffffff85166004820152905160009283928392600160a060020a039092169163939764059160248082019260209290919082900301818787803b15801561436957600080fd5b505af115801561437d573d6000803e3d6000fd5b505050506040513d602081101561439357600080fd5b5051915060008260028111156143a557fe5b14156143b45760ff92506121d5565b60018260028111156143c257fe5b14156143fa57506301e13380635c2aad7f1984010460068110156143ef578060020a6104000292506143f5565b61ffff92505b6121d5565b600092506121d5565b600054600160a060020a0316331461441a57600080fd5b6144238161494c565b50565b600154604080517fc17ad9d800000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163c17ad9d89160248082019260009290919082900301818387803b15801561449157600080fd5b505af11580156144a5573d6000803e3d6000fd5b50505050811561460957600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561451a57600080fd5b505af115801561452e573d6000803e3d6000fd5b5050600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff89166004820152600160a060020a038881166024830152915191909216935063ddc359509250604480830192600092919082900301818387803b1580156145a557600080fd5b505af11580156145b9573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36118cd565b600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff87166004820152600160a060020a0384811660248301529151919092169163ddc3595091604480830192600092919082900301818387803b15801561467c57600080fd5b505af1158015614690573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff89166004820152600160a060020a0388811660248301529151919092169350632c7ba5649250604480830192600092919082900301818387803b1580156146f157600080fd5b505af1158015614705573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0385169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a382600160a060020a031681600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258663ffffffff166040518082815260200191505060405180910390a350505050565b600154604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163f2fde38b91602480830192600092919082900301818387803b15801561480e57600080fd5b505af1158015614822573d6000803e3d6000fd5b5050600254604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216935063f2fde38b9250602480830192600092919082900301818387803b15801561488d57600080fd5b505af11580156148a1573d6000803e3d6000fd5b5050505080600160a060020a0316631824a46b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156148e357600080fd5b505af11580156148f7573d6000803e3d6000fd5b505060408051600160a060020a038516815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9350908190036020019150a180600160a060020a0316ff5b6000903b1190565b600160a060020a038116151561496157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582053db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad0029

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

000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a

-----Decoded View---------------
Arg [0] : _previous (address): 0xa23B5d8e86091aB6c14981F404c2864701aa2903
Arg [1] : _azimuth (address): 0x223c067F8CF28ae173EE5CafEa60cA44C335fecB
Arg [2] : _polls (address): 0x7fEcaB617c868Bb5996d99D95200D2Fa708218e4
Arg [3] : _claims (address): 0xe7e7f69b34D7d9Bd8d61Fb22C33b22708947971A

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903
Arg [1] : 000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb
Arg [2] : 0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4
Arg [3] : 000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a


Swarm Source

bzzr://53db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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