Token Skyweaver

 

Overview ERC-1155

Total Supply:
0 Skyweaver

Holders:
136,360 addresses

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
Loading

OVERVIEW

A trading card game from another dimension.


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

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x27A11C1563a5dDa238379B95c91B3AbBaD9C0cf6

Contract Name:
SkyweaverAssets

Compiler Version
v0.7.4+commit.3f05b770

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion, MIT license
File 1 of 29 : SkyweaverAssets.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "../utils/Ownable.sol";

import "@0xsequence/erc-1155/contracts/tokens/ERC1155PackedBalance/ERC1155MintBurnPackedBalance.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155Metadata.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC2981/ERC2981Global.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";


/**
 * ERC-1155 token contract for skyweaver assets.
 * This contract manages the various SW asset factories
 * and ensures that each factory has constraint access in
 * terms of the id space they are allowed to mint.
 * @dev Mint permissions use range because factory contracts
 *      could be minting large numbers of NFTs or be built
 *      with granular, but efficient permission checks.
 */
contract SkyweaverAssets is ERC1155MintBurnPackedBalance, ERC1155Metadata, ERC2981Global, Ownable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Factory mapping variables
  mapping(address => bool) internal isFactoryActive;          // Whether an address can print tokens or not
  mapping(address => AssetRange[]) internal mintAccessRanges; // Contains the ID ranges factories are allowed to mint
  AssetRange[] internal lockedRanges;                         // Ranges of IDs that can't be granted permission to mint

  // Issuance mapping variables
  mapping (uint256 => uint256) internal currentIssuance; // Current Issuance of token for tokens that have max issuance ONLY
  mapping (uint256 => uint256) internal maxIssuance;     // Issuance is counted and capped to associated maxIssuance if it's non-zero

  // Struct for mint ID ranges permissions
  struct AssetRange {
    uint64 minID;     // Minimum value the ID need to be to fall in the range
    uint64 maxID;     // Maximum value the ID need to be to fall in the range
    uint64 startTime; // Timestamp when the range becomes valid
    uint64 endTime;   // Timestamp after which the range is no longer valid 
  }

  /***********************************|
  |               Events              |
  |__________________________________*/

  event FactoryActivation(address indexed factory);
  event FactoryShutdown(address indexed factory);
  event MaxIssuancesChanged(uint256[] ids, uint256[] newMaxIssuances);
  event MintPermissionAdded(address indexed factory, AssetRange new_range);
  event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);
  event RangeLocked(AssetRange locked_range);


  /***********************************|
  |             Constuctor            |
  |__________________________________*/
  
  constructor (address _firstOwner) ERC1155Metadata("Skyweaver", "") Ownable(_firstOwner) public {}


  /***********************************|
  |     Factory Management Methods    |
  |__________________________________*/

  /**
   * @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
   * @param _factory Address of the factory to activate
   */
  function activateFactory(address _factory) external onlyOwner() {
    isFactoryActive[_factory] = true;
    emit FactoryActivation(_factory);
  }

  /**
   * @notice Will DISALLOW factory to print any asset
   * @param _factory Address of the factory to shutdown
   */
  function shutdownFactory(address _factory) external onlyOwner() {
    isFactoryActive[_factory] = false;
    emit FactoryShutdown(_factory);
  }

  /**
   * @notice Will allow a factory to mint some token ids
   * @param _factory   Address of the factory to update permission
   * @param _minRange  Minimum ID (inclusive) in id range that factory will be able to mint
   * @param _maxRange  Maximum ID (inclusive) in id range that factory will be able to mint
   * @param _startTime Timestamp when the range becomes valid
   * @param _endTime   Timestamp after which the range is no longer valid 
   */
  function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external onlyOwner() {
    require(_maxRange > 0, "SkyweaverAssets#addMintPermission: NULL_RANGE");
    require(_minRange <= _maxRange, "SkyweaverAssets#addMintPermission: INVALID_RANGE");
    require(_startTime < _endTime, "SkyweaverAssets#addMintPermission: START_TIME_IS_NOT_LESSER_THEN_END_TIME");

    // Check if new range has an overlap with locked ranges.
    // lockedRanges is expected to be a small array
    for (uint256 i = 0; i < lockedRanges.length; i++) {
      AssetRange memory locked_range = lockedRanges[i];
      require(
        (_maxRange < locked_range.minID) || (locked_range.maxID < _minRange),
        "SkyweaverAssets#addMintPermission: OVERLAP_WITH_LOCKED_RANGE"
      );
    }

    // Create and store range struct for _factory
    AssetRange memory range = AssetRange(_minRange, _maxRange, _startTime, _endTime);
    mintAccessRanges[_factory].push(range);
    emit MintPermissionAdded(_factory, range);
  }

  /**
   * @notice Will remove the permission a factory has to mint some token ids
   * @param _factory    Address of the factory to update permission
   * @param _rangeIndex Array's index where the range to delete is located for _factory
   */
  function removeMintPermission(address _factory, uint256 _rangeIndex) external onlyOwner() {
    // Will take the last range and put it where the "hole" will be after
    // the AssetRange struct at _rangeIndex is deleted
    uint256 last_index = mintAccessRanges[_factory].length - 1; // won't underflow because of require() statement above
    AssetRange memory range_to_delete = mintAccessRanges[_factory][_rangeIndex]; // Stored for log

    if (_rangeIndex != last_index) {
      AssetRange memory last_range = mintAccessRanges[_factory][last_index]; // Retrieve the range that will be moved
      mintAccessRanges[_factory][_rangeIndex] = last_range;                  // Overwrite the "to-be-deleted" range
    }

    // Delete last element of the array
    mintAccessRanges[_factory].pop();
    emit MintPermissionRemoved(_factory, range_to_delete);
  }

  /**
   * @notice Will forever prevent new mint permissions for provided ids
   * @dev THIS ACTION IS IRREVERSIBLE, USE WITH CAUTION
   * @dev In order to forever restrict minting of certain ids to a set of factories,
   *      one first needs to call `addMintPermission()` for the corresponding factory
   *      and the corresponding ids, then call this method to prevent further mint
   *      permissions to be granted. One can also remove mint permissions after ids
   *      mint permissions where locked down.
   * @param _range AssetRange struct for range of asset that can't be granted
   *               new mint permission to
   */
  function lockRangeMintPermissions(AssetRange memory _range) public onlyOwner() {
    lockedRanges.push(_range);
    emit RangeLocked(_range);
  }

  /***********************************|
  |    Supplies Management Methods    |
  |__________________________________*/

  /**
   * @notice Set max issuance for some token IDs that can't ever be increased
   * @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
   * @param _ids Array of token IDs to set the max issuance
   * @param _newMaxIssuances Array of max issuances for each corresponding ID
   */
  function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external onlyOwner() {
    require(_ids.length == _newMaxIssuances.length, "SkyweaverAssets#setMaxIssuances: INVALID_ARRAYS_LENGTH");

    // Can only *decrease* a max issuance
    // Can't set max issuance back to 0
    for (uint256 i = 0; i < _ids.length; i++ ) {
      if (maxIssuance[_ids[i]] > 0) {
        require(
          0 < _newMaxIssuances[i] && _newMaxIssuances[i] < maxIssuance[_ids[i]],
          "SkyweaverAssets#setMaxIssuances: INVALID_NEW_MAX_ISSUANCE"
        );
      }
      maxIssuance[_ids[i]] = _newMaxIssuances[i];
    }

    emit MaxIssuancesChanged(_ids, _newMaxIssuances);
  }

  /***********************************|
  |    Royalty Management Methods     |
  |__________________________________*/

  /**
   * @notice Will set the basis point and royalty recipient that is applied to all Skyweaver assets
   * @param _receiver Fee recipient that will receive the royalty payments
   * @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
   *        e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
   */
  function setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) external onlyOwner() {
    _setGlobalRoyaltyInfo(_receiver, _royaltyBasisPoints);
  }

  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("UNSUPPORTED_METHOD");
  }

  /***********************************|
  |          Minting Function         |
  |__________________________________*/

  /**
   * @notice Mint tokens for each ids in _ids
   * @dev This methods assumes ids are sorted by how the ranges are sorted in
   *      the corresponding mintAccessRanges[msg.sender] array. Call might throw
   *      if they are not.
   * @param _to      The address to mint tokens to.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   * @param _data    Byte array of data to pass to recipient if it's a contract
   */
  function batchMint(
    address _to,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data) public
  {
    // Validate assets to be minted
    _validateMints(_ids, _amounts);

    // If hasn't reverted yet, all IDs are allowed for factory
    _batchMint(_to, _ids, _amounts, _data);
  }

  /**
   * @notice Mint _amount of tokens of a given id, if allowed.
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external
  {
    // Put into array for validation
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Validate and mint
    _validateMints(ids, amounts);
    _mint(_to, _id, _amount, _data);
  }

  /**
   * @notice Will validate the ids and amounts to mint
   * @dev This methods assumes ids are sorted by how the ranges are sorted in
   *      the corresponding mintAccessRanges[msg.sender] array. Call will revert
   *      if they are not.
   * @dev When the maxIssuance of an asset is set to a non-zero value, the
   *      supply manager contract will start keeping track of how many of that
   *      token are minted, until the maxIssuance hit.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   */
  function _validateMints(uint256[] memory _ids, uint256[] memory _amounts) internal {
    require(isFactoryActive[msg.sender], "SkyweaverAssets#_validateMints: FACTORY_NOT_ACTIVE");

    // Number of mint ranges
    uint256 n_ranges = mintAccessRanges[msg.sender].length;

    // Load factory's default range
    AssetRange memory range = mintAccessRanges[msg.sender][0];
    uint256 range_index = 0;

    // Will make sure that factory is allowed to print all ids
    // and that no max issuance is exceeded
    for (uint256 i = 0; i < _ids.length; i++) {
      uint256 id = _ids[i];
      uint256 amount = _amounts[i];
      uint256 max_issuance = maxIssuance[id];

      // If ID is out of current range, move to next range, else skip.
      // This function only moves forwards in the AssetRange array,
      // hence if _ids are not sorted correctly, the call will fail.
      while (block.timestamp < range.startTime || block.timestamp > range.endTime || id < range.minID || range.maxID < id) {
        range_index += 1;

        // Load next range. If none left, ID is assumed to be out of all ranges
        require(range_index < n_ranges, "SkyweaverAssets#_validateMints: ID_OUT_OF_RANGE");
        range = mintAccessRanges[msg.sender][range_index];
      }

      // If max supply is specified for id
      if (max_issuance > 0) {
        uint256 new_current_issuance = currentIssuance[id].add(amount);
        require(new_current_issuance <= max_issuance, "SkyweaverAssets#_validateMints: MAX_ISSUANCE_EXCEEDED");
        currentIssuance[id] = new_current_issuance;
      }
    }
  }

  /***********************************|
  |         Getter Functions          |
  |__________________________________*/

  /**
   * @notice Get the max issuance of multiple asset IDs
   * @dev The max issuance of a token does not reflect the maximum supply, only
   *      how many tokens can be minted once the maxIssuance for a token is set.
   * @param _ids Array containing the assets IDs
   * @return The current max issuance of each asset ID in _ids
   */
  function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
    uint256 nIds = _ids.length;
    uint256[] memory max_issuances = new uint256[](nIds);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < nIds; i++) {
      max_issuances[i] = maxIssuance[_ids[i]];
    }

    return max_issuances;
  }

  /**
   * @notice Get the current issuanc of multiple asset ID
   * @dev The current issuance of a token does not reflect the current supply, only
   *      how many tokens since a max issuance was set for a given token id.
   * @param _ids Array containing the assets IDs
   * @return The current issuance of each asset ID in _ids
   */
  function getCurrentIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
    uint256 nIds = _ids.length;
    uint256[] memory current_issuances = new uint256[](nIds);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < nIds; i++) {
      current_issuances[i] = currentIssuance[_ids[i]];
    }

    return current_issuances;
  }

  /**
   * @return Returns whether a factory is active or not
   */
  function getFactoryStatus(address _factory) external view returns (bool) {
    return isFactoryActive[_factory];
  }

  /**
   * @return Returns whether the sale has ended or not
   */
  function getFactoryAccessRanges(address _factory) external view returns (AssetRange[] memory) {
    return mintAccessRanges[_factory];
  }

  /**
   * @return Returns all the ranges that are locked
   */
  function getLockedRanges() external view returns (AssetRange[] memory) {
    return lockedRanges;
  }

  /***********************************|
  |          Burning Functions        |
  |__________________________________*/

  /**
   * @notice Burn _amount of tokens of a given id from msg.sender
   * @dev This will not change the current issuance tracked in _supplyManagerAddr.
   * @param _id     Asset id to burn
   * @param _amount The amount to be burn
   */
  function burn(
    uint256 _id,
    uint256 _amount)
    external
  {
    _burn(msg.sender, _id, _amount);
  }

  /**
   * @notice Burn _amounts of tokens of given ids from msg.sender
   * @dev This will not change the current issuance tracked in _supplyManagerAddr.
   * @param _ids     Asset id to burn
   * @param _amounts The amount to be burn
   */
  function batchBurn(
    uint256[] calldata _ids,
    uint256[] calldata _amounts)
    external
  {
    _batchBurn(msg.sender, _ids, _amounts);
  }

  /***********************************|
  |           URI Functions           |
  |__________________________________*/

  /**
   * @dev Will update the base URL of token's URI
   * @param _newBaseMetadataURI New base URL of token's URI
   */
  function setBaseMetadataURI(string calldata _newBaseMetadataURI) external onlyOwner() {
    _setBaseMetadataURI(_newBaseMetadataURI);
  }

  /**
   * @dev Will emit default URI log event for corresponding token _id
   * @param _tokenIDs Array of IDs of tokens to log default URI
   */
  function logURIs(uint256[] calldata _tokenIDs) external onlyOwner() {
    _logURIs(_tokenIDs);
  }

  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC1155PackedBalance, ERC1155Metadata, ERC2981Global) virtual pure returns (bool) {
    return super.supportsInterface(_interfaceID);
  }
}

File 2 of 29 : ISkyweaverAssets.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

interface ISkyweaverAssets {

  /***********************************|
  |               Events              |
  |__________________________________*/

  event FactoryActivation(address indexed factory);
  event FactoryShutdown(address indexed factory);
  event MintPermissionAdded(address indexed factory, AssetRange new_range);
  event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);

  // Struct for mint ID ranges permissions
  struct AssetRange {
    uint256 minID;
    uint256 maxID;
  }

  /***********************************|
  |    Supplies Management Methods    |
  |__________________________________*/

  /**
   * @notice Set max issuance for some token IDs that can't ever be increased
   * @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
   * @param _ids Array of token IDs to set the max issuance
   * @param _newMaxIssuances Array of max issuances for each corresponding ID
   */
  function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external;

  /***********************************|
  |     Factory Management Methods    |
  |__________________________________*/

  /**
   * @notice Will allow a factory to mint some token ids
   * @param _factory   Address of the factory to update permission
   * @param _minRange  Minimum ID (inclusive) in id range that factory will be able to mint
   * @param _maxRange  Maximum ID (inclusive) in id range that factory will be able to mint
   * @param _startTime Timestamp when the range becomes valid
   * @param _endTime   Timestamp after which the range is no longer valid 
   */
  function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external;

  /**
   * @notice Will remove the permission a factory has to mint some token ids
   * @param _factory    Address of the factory to update permission
   * @param _rangeIndex Array's index where the range to delete is located for _factory
   */
  function removeMintPermission(address _factory, uint256 _rangeIndex) external;

  /**
   * @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
   * @param _factory Address of the factory to activate
   */
  function activateFactory(address _factory) external;

  /**
   * @notice Will DISALLOW factory to print any asset
   * @param _factory Address of the factory to shutdown
   */
  function shutdownFactory(address _factory) external;

  /**
   * @notice Will forever prevent new mint permissions for provided ids
   * @param _range AssetRange struct for range of asset that can't be granted
   *               new mint permission to
   */
  function lockRangeMintPermissions(AssetRange calldata _range) external;


  /***********************************|
  |         Getter Functions          |
  |__________________________________*/

  /**
   * @return Returns whether a factory is active or not
   */
  function getFactoryStatus(address _factory) external view returns (bool);

  /**
   * @return Returns whether the sale has ended or not
   */
  function getFactoryAccessRanges(address _factory) external view returns ( AssetRange[] memory);

  /**
   * @notice Get the max issuance of multiple asset IDs
   * @dev The max issuance of a token does not reflect the maximum supply, only
   *      how many tokens can be minted once the maxIssuance for a token is set.
   * @param _ids Array containing the assets IDs
   * @return The current max issuance of each asset ID in _ids
   */
  function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory);

  /**
   * @notice Get the current issuanc of multiple asset ID
   * @dev The current issuance of a token does not reflect the current supply, only
   *      how many tokens since a max issuance was set for a given token id.
   * @param _ids Array containing the assets IDs
   * @return The current issuance of each asset ID in _ids
   */
  function getCurrentIssuances(uint256[] calldata _ids)external view returns (uint256[] memory);

  /***************************************|
  |           Minting Functions           |
  |______________________________________*/

  /**
   * @dev Mint _amount of tokens of a given id if not frozen and if max supply not exceeded
   * @param _to     The address to mint tokens to.
   * @param _id     Token id to mint
   * @param _amount The amount to be minted
   * @param _data   Byte array of data to pass to recipient if it's a contract
   */
  function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;

  /**
   * @dev Mint tokens for each ids in _ids
   * @param _to      The address to mint tokens to.
   * @param _ids     Array of ids to mint
   * @param _amounts Array of amount of tokens to mint per id
   * @param _data    Byte array of data to pass to recipient if it's a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;


  /***************************************|
  |           Burning Functions           |
  |______________________________________*/

  /**
   * @notice Burn sender's_amount of tokens of a given token id
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function burn(uint256 _id, uint256 _amount) external;

  /**
   * @notice Burn sender's tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function batchBurn(uint256[] calldata _ids, uint256[] calldata _amounts) external;
}

File 3 of 29 : Conquest.sol
pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "../interfaces/IRewardFactory.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";

/**
 * @notice Keep track of players participation in Conquest and used to issue rewards.
 * @dev This contract must be at least a TIER 1 owner of the silverCardFactory and
 *      goldCardFactory.
 */
contract Conquest is IERC1155TokenReceiver, TieredOwnable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Parameters
  uint256 constant internal TIME_BETWEEN_CONQUESTS = 1 seconds; // Seconds that must elapse between two conquest
  uint256 constant internal ENTRIES_DECIMALS = 2;               // Amount of decimals conquest entries have
  uint256 constant internal CARDS_DECIMALS = 2;                 // Number of decimals cards have

  // Contracts
  IRewardFactory immutable public silverCardFactory; // Factory that mints Silver cards
  IRewardFactory immutable public goldCardFactory;   // Factory that mints Gold cards
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
  uint256 immutable public conquestEntryID;          // Conquest entry token id

  // Mappings
  mapping(address => bool) public isActiveConquest;    // Whether a given player is currently in a conquest
  mapping(address => uint256) public conquestsEntered; // Number of conquest a given player has entered so far
  mapping(address => uint256) public nextConquestTime; // Time when the next conquest can be started for players

  // Event
  event ConquestEntered(address user, uint256 nConquests);


  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Link factories and skyweaver assets, store initial parameters
   * @param _firstOwner               Address of the first owner
   * @param _skyweaverAssetsAddress   The address of the ERC-1155 Assets Token contract
   * @param _silverCardFactoryAddress The address of the Silver Card Factory
   * @param _goldCardFactoryAddress   The address of the Gold Card Factory
   * @param _conquestEntryTokenId     Conquest entry token id
   */
  constructor(
    address _firstOwner,
    address _skyweaverAssetsAddress,
    address _silverCardFactoryAddress,
    address _goldCardFactoryAddress,
    uint256 _conquestEntryTokenId
  ) TieredOwnable(_firstOwner) public 
  {
    require(
      _skyweaverAssetsAddress != address(0) &&
      _silverCardFactoryAddress != address(0) &&
      _goldCardFactoryAddress != address(0),
      "Conquest#constructor: INVALID_INPUT"
    );

    // Store parameters
    skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
    silverCardFactory = IRewardFactory(_silverCardFactoryAddress);
    goldCardFactory = IRewardFactory(_goldCardFactoryAddress);
    conquestEntryID = _conquestEntryTokenId;
  }

  
  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsupported methods
   */
  fallback () external {
    revert("Conquest#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Players entering conquest with conquest entry token
   * @dev Payload is passed to and verified by onERC1155BatchReceived()
   */
  function onERC1155Received(
    address _operator,
    address _from,
    uint256 _id, 
    uint256 _amount, 
    bytes calldata _data
  )
    external override returns(bytes4)
  {
    // Convert payload to arrays to pass to onERC1155BatchReceived()
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Will revert call if doesn't pass
    onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
    
    // Return success
    return IERC1155TokenReceiver.onERC1155Received.selector;
  }

  /**
   * @notice Conquest entry point. Will mark user as having entered conquest if valid entry.
   * @param _from    Address who sent the token
   * @param _ids     An array containing ids of each Token being transferred
   * @param _amounts An array containing amounts of each Token being transferred
   */
  function onERC1155BatchReceived(
    address, // _operator
    address _from,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory // _data
  )
    public override returns(bytes4)
  {
    require(msg.sender == address(skyweaverAssets), "Conquest#entry: INVALID_ENTRY_TOKEN_ADDRESS");
    require(_ids.length == 1, "Conquest#entry: INVALID_IDS_ARRAY_LENGTH");
    require(_amounts.length == 1, "Conquest#entry: INVALID_AMOUNTS_ARRAY_LENGTH");
    require(_ids[0] == conquestEntryID, "Conquest#entry: INVALID_ENTRY_TOKEN_ID");
    require(_amounts[0] == 10**ENTRIES_DECIMALS, "Conquest#entry: INVALID_ENTRY_TOKEN_AMOUNT");
    require(!isActiveConquest[_from], "Conquest#entry: PLAYER_ALREADY_IN_CONQUEST");
    require(nextConquestTime[_from] <= block.timestamp, "Conquest#entry: NEW_CONQUEST_TOO_EARLY");

    // Mark player as playing
    isActiveConquest[_from] = true;
    conquestsEntered[_from] = conquestsEntered[_from].add(1);
    nextConquestTime[_from] = block.timestamp.add(TIME_BETWEEN_CONQUESTS);

    // Burn tickets
    skyweaverAssets.burn(conquestEntryID, 10**ENTRIES_DECIMALS);

    // Emit event
    emit ConquestEntered(_from, conquestsEntered[_from]);

    // Return success
    return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
  }


  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will exit user from conquest and mint tokens to user 
   * @param _user      The address that exits conquest and receive the rewards
   * @param _silverIds Ids of silver cards to mint (duplicate ids if amount > 1)
   * @param _goldIds   Ids of gold cards to mint (duplicate ids if amount > 1)
   */
  function exitConquest(address _user, uint256[] calldata _silverIds, uint256[] calldata _goldIds)
    external onlyOwnerTier(1)
  { 
    require(isActiveConquest[_user], "Conquest#exitConquest: USER_IS_NOT_IN_CONQUEST");

    // Mark player as not playing anymore
    isActiveConquest[_user] = false;

    // 0 win - 1 loss ===> 0 rewards
    if (_silverIds.length == 0 && _goldIds.length == 0) {
      /*  Do nothing if user didn't win any matches  */

    // 1 win - 1 loss ===> 1 Silver card
    } else if (_silverIds.length == 1 && _goldIds.length == 0) { 
      silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");

    // 2 wins - 1 loss ===> 2 silver cards
    } else if (_silverIds.length == 2 && _goldIds.length == 0) { 
      silverCardFactory.batchMint(_user, _silverIds, array(2, 10**CARDS_DECIMALS), "");

    // 3 wins - 0 loss ===> 1 Silver card and 1 Gold card
    } else if (_silverIds.length == 1 && _goldIds.length == 1) { 
      silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");
      goldCardFactory.batchMint(_user, _goldIds, array(1, 10**CARDS_DECIMALS), "");

    // Revert for any other combination
    } else {
      revert("Conquest#exitConquest: INVALID_REWARDS");
    }
  }

  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /** 
   * @notice Will create an array of uint _value of length _length
   * @param _length Number of elements in array
   * @param _value  Value to put in array at each element
   */
  function array(uint256 _length, uint256 _value) internal pure returns (uint256[] memory) {
    uint256[] memory a = new uint256[](_length);
    for (uint256 i = 0; i < _length; i++) {
      a[i] = _value;
    }
    return a;
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId || 
      interfaceID == type(IERC1155TokenReceiver).interfaceId;
  }
}

File 4 of 29 : TieredOwnable.sol
pragma solidity 0.7.4;

/**
 * @notice The TieredOwnable can assign ownership tiers to addresses,
 * allowing inheriting contracts to choose which tier can call which function.
 */
contract TieredOwnable {
  uint256 constant internal HIGHEST_OWNER_TIER = 2**256-1; //Highest possible tier

  mapping(address => uint256) internal ownerTier;
  event OwnershipGranted(address indexed owner, uint256 indexed previousTier, uint256 indexed newTier);

  /**
   * @dev Sets the _firstOwner provided to highest owner tier
   * @dev _firstOwner First address to be a owner of this contract
   */
  constructor (address _firstOwner) {
    require(_firstOwner != address(0), "TieredOwnable#constructor: INVALID_FIRST_OWNER");
    ownerTier[_firstOwner] = HIGHEST_OWNER_TIER;
    emit OwnershipGranted(_firstOwner, 0, HIGHEST_OWNER_TIER);
  }

  /**
   * @dev Throws if called by an account that's in lower ownership tier than expected
   */
  modifier onlyOwnerTier(uint256 _minTier) {
    require(ownerTier[msg.sender] >= _minTier, "TieredOwnable#onlyOwnerTier: OWNER_TIER_IS_TOO_LOW");
    _;
  }

  /**
   * @notice Highest owners can change ownership tier of other owners
   * @dev Prevents changing sender's tier to ensure there is always at least one HIGHEST_OWNER_TIER owner.
   * @param _address Address of the owner
   * @param _tier    Ownership tier assigned to owner
   */
  function assignOwnership(address _address, uint256 _tier) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    require(_address != address(0), "TieredOwnable#assignOwnership: INVALID_ADDRESS");
    require(msg.sender != _address, "TieredOwnable#assignOwnership: UPDATING_SELF_TIER");
    emit OwnershipGranted(_address, ownerTier[_address], _tier);
    ownerTier[_address] = _tier;
  }

  /**
   * @notice Returns the ownership tier of provided owner
   * @param _owner Owner's address to query ownership tier
   */
  function getOwnerTier(address _owner) external view returns (uint256) {
    return ownerTier[_owner];
  }
}

File 5 of 29 : IRewardFactory.sol
pragma solidity 0.7.4;

/**
 * @notice This is a contract allowing contract owner to mint up to N
 *         assets per period of 6 hours.
 * @dev This contract should only be able to mint some assets types
 */
interface IRewardFactory {

  // Event
  event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);

  /***********************************|
  |         Management Methods        |
  |__________________________________*/

  /**
   * @notice Will update the daily mint limit
   * @dev This change will take effect immediatly once executed
   * @param _newPeriodMintLimit Amount of assets that can be minted within a period
   */
  function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external;


  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will mint tokens to user
   * @dev Can only mint up to the periodMintLimit in a given 6hour period
   * @param _to      The address that receives the assets
   * @param _ids     Array of Tokens ID that are minted
   * @param _amounts Amount of Tokens id minted for each corresponding Token id in _tokenIds
   * @param _data    Byte array passed to recipient if recipient is a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;

  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Returns how many cards can currently be minted by this factory
   */
  function getAvailableSupply() external view returns (uint256);

  /**
   * @notice Calculate the current period
   */
  function livePeriod() external view returns (uint256);

  /**
   * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
   * @param  interfaceID The ERC-165 interface ID that is queried for support.s
   * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
   *      This function MUST NOT consume more than 5,000 gas.
   * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool);
}

File 6 of 29 : SafeMath.sol
pragma solidity 0.7.4;


/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {

  /**
   * @dev Multiplies two unsigned integers, reverts on overflow.
   */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b, "SafeMath#mul: OVERFLOW");

    return c;
  }

  /**
   * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
   */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // Solidity only automatically asserts when dividing by 0
    require(b > 0, "SafeMath#div: DIVISION_BY_ZERO");
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
   * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
   */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a, "SafeMath#sub: UNDERFLOW");
    uint256 c = a - b;

    return c;
  }

  /**
   * @dev Adds two unsigned integers, reverts on overflow.
   */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, "SafeMath#add: OVERFLOW");

    return c; 
  }

  /**
   * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
   * reverts when dividing by zero.
   */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO");
    return a % b;
  }
}

File 7 of 29 : IERC165.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;


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

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

File 8 of 29 : IERC1155.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';


interface IERC1155 is IERC165 {

  /****************************************|
  |                 Events                 |
  |_______________________________________*/

  /**
   * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
   *   Operator MUST be msg.sender
   *   When minting/creating tokens, the `_from` field MUST be set to `0x0`
   *   When burning/destroying tokens, the `_to` field MUST be set to `0x0`
   *   The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
   *   To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
   */
  event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);

  /**
   * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
   *   Operator MUST be msg.sender
   *   When minting/creating tokens, the `_from` field MUST be set to `0x0`
   *   When burning/destroying tokens, the `_to` field MUST be set to `0x0`
   *   The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
   *   To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
   */
  event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);

  /**
   * @dev MUST emit when an approval is updated
   */
  event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);


  /****************************************|
  |                Functions               |
  |_______________________________________*/

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

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

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

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders
   * @param _ids    ID of the Tokens
   * @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
   */
  function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

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

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

File 9 of 29 : IERC1155TokenReceiver.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

/**
 * @dev ERC-1155 interface for accepting safe transfers.
 */
interface IERC1155TokenReceiver {

  /**
   * @notice Handle the receipt of a single ERC1155 token type
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value MUST result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _id        The id of the token being transferred
   * @param _amount    The amount of tokens being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
   */
  function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);

  /**
   * @notice Handle the receipt of multiple ERC1155 token types
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value WILL result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeBatchTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _ids       An array containing ids of each token being transferred
   * @param _amounts   An array containing amounts of each token being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
   */
  function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
}

File 10 of 29 : ERC1155PackedBalance.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";


/**
 * @dev Implementation of Multi-Token Standard contract. This implementation of the ERC-1155 standard
 *      utilizes the fact that balances of different token ids can be concatenated within individual
 *      uint256 storage slots. This allows the contract to batch transfer tokens more efficiently at
 *      the cost of limiting the maximum token balance each address can hold. This limit is
 *      2^IDS_BITS_SIZE, which can be adjusted below. In practice, using IDS_BITS_SIZE smaller than 16
 *      did not lead to major efficiency gains.
 */
contract ERC1155PackedBalance is IERC1155, ERC165 {
  using SafeMath for uint256;
  using Address for address;

  /***********************************|
  |        Variables and Events       |
  |__________________________________*/

  // onReceive function signatures
  bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
  bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;

  // Constants regarding bin sizes for balance packing
  // IDS_BITS_SIZE **MUST** be a power of 2 (e.g. 2, 4, 8, 16, 32, 64, 128)
  uint256 internal constant IDS_BITS_SIZE   = 32;                  // Max balance amount in bits per token ID
  uint256 internal constant IDS_PER_UINT256 = 256 / IDS_BITS_SIZE; // Number of ids per uint256

  // Operations for _updateIDBalance
  enum Operations { Add, Sub }

  // Token IDs balances ; balances[address][id] => balance (using array instead of mapping for efficiency)
  mapping (address => mapping(uint256 => uint256)) internal balances;

  // Operators
  mapping (address => mapping(address => bool)) internal operators;


  /***********************************|
  |     Public Transfer Functions     |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   * @param _data    Additional data with no specified format, sent in call to `_to`
   */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeTransferFrom: INVALID_RECIPIENT");
    // require(_amount <= balances);  Not necessary since checked with _viewUpdateBinValue() checks

    _safeTransferFrom(_from, _to, _id, _amount);
    _callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   * @param _data     Additional data with no specified format, sent in call to `_to`
   */
  function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeBatchTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeBatchTransferFrom: INVALID_RECIPIENT");

    _safeBatchTransferFrom(_from, _to, _ids, _amounts);
    _callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
  }


  /***********************************|
  |    Internal Transfer Functions    |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   */
  function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
    internal
  {
    //Update balances
    _updateIDBalance(_from, _id, _amount, Operations.Sub); // Subtract amount from sender
    _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

    // Emit event
    emit TransferSingle(msg.sender, _from, _to, _id, _amount);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
   */
  function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Check if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas:_gasLimit}(msg.sender, _from, _id, _amount, _data);
      require(retval == ERC1155_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
    }
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   */
  function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    uint256 nTransfer = _ids.length; // Number of transfer to execute
    require(nTransfer == _amounts.length, "ERC1155PackedBalance#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");

    if (_from != _to && nTransfer > 0) {
      // Load first bin and index where the token ID balance exists
      (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

      // Balance for current bin in memory (initialized with first transfer)
      uint256 balFrom = _viewUpdateBinValue(balances[_from][bin], index, _amounts[0], Operations.Sub);
      uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

      // Last bin updated
      uint256 lastBin = bin;

      for (uint256 i = 1; i < nTransfer; i++) {
        (bin, index) = getIDBinIndex(_ids[i]);

        // If new bin
        if (bin != lastBin) {
          // Update storage balance of previous bin
          balances[_from][lastBin] = balFrom;
          balances[_to][lastBin] = balTo;

          balFrom = balances[_from][bin];
          balTo = balances[_to][bin];

          // Bin will be the most recent bin
          lastBin = bin;
        }

        // Update memory balance
        balFrom = _viewUpdateBinValue(balFrom, index, _amounts[i], Operations.Sub);
        balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
      }

      // Update storage of the last bin visited
      balances[_from][bin] = balFrom;
      balances[_to][bin] = balTo;

    // If transfer to self, just make sure all amounts are valid
    } else {
      for (uint256 i = 0; i < nTransfer; i++) {
        require(balanceOf(_from, _ids[i]) >= _amounts[i], "ERC1155PackedBalance#_safeBatchTransferFrom: UNDERFLOW");
      }
    }

    // Emit event
    emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
   */
  function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Pass data if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
      require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
    }
  }


  /***********************************|
  |         Operator Functions        |
  |__________________________________*/

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved)
    external override
  {
    // Update operator status
    operators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator)
    public override view returns (bool isOperator)
  {
    return operators[_owner][_operator];
  }


  /***********************************|
  |     Public Balance Functions      |
  |__________________________________*/

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id)
    public override view returns (uint256)
  {
    uint256 bin;
    uint256 index;

    //Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);
    return getValueInBin(balances[_owner][bin], index);
  }

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders (sorted owners will lead to less gas usage)
   * @param _ids    ID of the Tokens (sorted ids will lead to less gas usage
   * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
    */
  function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
    public override view returns (uint256[] memory)
  {
    uint256 n_owners = _owners.length;
    require(n_owners == _ids.length, "ERC1155PackedBalance#balanceOfBatch: INVALID_ARRAY_LENGTH");

    // First values
    (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
    uint256 balance_bin = balances[_owners[0]][bin];
    uint256 last_bin = bin;

    // Initialization
    uint256[] memory batchBalances = new uint256[](n_owners);
    batchBalances[0] = getValueInBin(balance_bin, index);

    // Iterate over each owner and token ID
    for (uint256 i = 1; i < n_owners; i++) {
      (bin, index) = getIDBinIndex(_ids[i]);

      // SLOAD if bin changed for the same owner or if owner changed
      if (bin != last_bin || _owners[i-1] != _owners[i]) {
        balance_bin = balances[_owners[i]][bin];
        last_bin = bin;
      }

      batchBalances[i] = getValueInBin(balance_bin, index);
    }

    return batchBalances;
  }


  /***********************************|
  |      Packed Balance Functions     |
  |__________________________________*/

  /**
   * @notice Update the balance of a id for a given address
   * @param _address    Address to update id balance
   * @param _id         Id to update balance of
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to id balance
   *   Operations.Sub: Substract _amount from id balance
   */
  function _updateIDBalance(address _address, uint256 _id, uint256 _amount, Operations _operation)
    internal
  {
    uint256 bin;
    uint256 index;

    // Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);

    // Update balance
    balances[_address][bin] = _viewUpdateBinValue(balances[_address][bin], index, _amount, _operation);
  }

  /**
   * @notice Update a value in _binValues
   * @param _binValues  Uint256 containing values of size IDS_BITS_SIZE (the token balances)
   * @param _index      Index of the value in the provided bin
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to value in _binValues at _index
   *   Operations.Sub: Substract _amount from value in _binValues at _index
   */
  function _viewUpdateBinValue(uint256 _binValues, uint256 _index, uint256 _amount, Operations _operation)
    internal pure returns (uint256 newBinValues)
  {
    uint256 shift = IDS_BITS_SIZE * _index;
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    if (_operation == Operations.Add) {
      newBinValues = _binValues + (_amount << shift);
      require(newBinValues >= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW");
      require(
        ((_binValues >> shift) & mask) + _amount < 2**IDS_BITS_SIZE, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW"
      );

    } else if (_operation == Operations.Sub) {
      newBinValues = _binValues - (_amount << shift);
      require(newBinValues <= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW");
      require(
        ((_binValues >> shift) & mask) >= _amount, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW"
      );

    } else {
      revert("ERC1155PackedBalance#_viewUpdateBinValue: INVALID_BIN_WRITE_OPERATION"); // Bad operation
    }

    return newBinValues;
  }

  /**
  * @notice Return the bin number and index within that bin where ID is
  * @param _id  Token id
  * @return bin index (Bin number, ID"s index within that bin)
  */
  function getIDBinIndex(uint256 _id)
    public pure returns (uint256 bin, uint256 index)
  {
    bin = _id / IDS_PER_UINT256;
    index = _id % IDS_PER_UINT256;
    return (bin, index);
  }

  /**
   * @notice Return amount in _binValues at position _index
   * @param _binValues  uint256 containing the balances of IDS_PER_UINT256 ids
   * @param _index      Index at which to retrieve amount
   * @return amount at given _index in _bin
   */
  function getValueInBin(uint256 _binValues, uint256 _index)
    public pure returns (uint256)
  {
    // require(_index < IDS_PER_UINT256) is not required since getIDBinIndex ensures `_index < IDS_PER_UINT256`

    // Mask to retrieve data for a given binData
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    // Shift amount
    uint256 rightShift = IDS_BITS_SIZE * _index;
    return (_binValues >> rightShift) & mask;
  }


  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

File 11 of 29 : Address.sol
pragma solidity 0.7.4;


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

  // Default hash for EOA accounts returned by extcodehash
  bytes32 constant internal ACCOUNT_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract.
   * @param _address address of the account to check
   * @return Whether the target address is a contract
   */
  function isContract(address _address) internal view returns (bool) {
    bytes32 codehash;

    // 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 or if it has a non-zero code hash or account hash
    assembly { codehash := extcodehash(_address) }
    return (codehash != 0x0 && codehash != ACCOUNT_HASH);
  }
}

File 12 of 29 : ERC165.sol
pragma solidity 0.7.4;
import "../interfaces/IERC165.sol";

abstract contract ERC165 is IERC165 {
  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(bytes4 _interfaceID) virtual override public pure returns (bool) {
    return _interfaceID == this.supportsInterface.selector;
  }
}

File 13 of 29 : ERC2981Global.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../utils/ERC165.sol";
import "../../utils/SafeMath.sol";
import "../../interfaces/IERC2981.sol";

/**
 * @notice Contract return royalty information for tokens of this contract
 * @dev This contract sets a global fee information for all token ids.
 */
contract ERC2981Global is IERC2981, ERC165 {
  using SafeMath for uint256;

  struct FeeInfo {
    address receiver;
    uint256 feeBasisPoints;
  }

  // Royalty Fee information struct
  FeeInfo public globalRoyaltyInfo;

  /**
   * @notice Will set the basis point and royalty recipient that is applied to all assets
   * @param _receiver Fee recipient that will receive the royalty payments
   * @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
   *        e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
   */
  function _setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) internal {
    require(_receiver != address(0x0), "ERC2981Global#_setGlobalRoyalty: RECIPIENT_IS_0x0");
    require(_royaltyBasisPoints <= 1000, "ERC2981Global#_setGlobalRoyalty: FEE_IS_ABOVE_100_PERCENT");
    globalRoyaltyInfo.receiver = _receiver;
    globalRoyaltyInfo.feeBasisPoints = _royaltyBasisPoints;
  }


  /***********************************|
  |         ERC-2981 Functions        |
  |__________________________________*/

    /**  
    * @notice Called with the sale price to determine how much royalty is owed and to whom.
    * @param _saleCost - the sale cost of the NFT asset specified by _tokenId
    * @return receiver - address of who should be sent the royalty payment
    * @return royaltyAmount - the royalty payment amount for _salePrice
    */
  function royaltyInfo(
    uint256, 
    uint256 _saleCost
  ) external view override returns (address receiver, uint256 royaltyAmount) 
  {
    FeeInfo memory info = globalRoyaltyInfo;
    return (info.receiver, _saleCost.mul(info.feeBasisPoints).div(1000));
  }


  /***********************************|
  |         ERC-165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC2981).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

File 14 of 29 : IERC2981.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';

interface IERC2981 is IERC165 {
  /**  
    * @notice Called with the sale price to determine how much royalty is owed and to whom.
    * @param _tokenId - the NFT asset queried for royalty information
    * @param _saleCost - the sale cost of the NFT asset specified by _tokenId
    * @return receiver - address of who should be sent the royalty payment
    * @return royaltyAmount - the royalty payment amount for _salePrice
    */
  function royaltyInfo(uint256 _tokenId, uint256 _saleCost) external view returns (address receiver, uint256 royaltyAmount);
}

File 15 of 29 : RewardFactory.sol
pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";

/**
 * @notice This is a contract allowing contract owner to mint up to N 
 *         assets per period of 6 hours.
 * @dev This contract should only be able to mint some asset types
 */
contract RewardFactory is TieredOwnable {
  using SafeMath for uint256;

  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Token information
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract

  // Period variables
  uint256 internal period;                // Current period
  uint256 internal availableSupply;       // Amount of assets that can currently be minted
  uint256 public periodMintLimit;         // Amount that can be minted within 6h
  uint256 immutable public PERIOD_LENGTH; // Length of each mint periods in seconds

  // Whitelist
  bool internal immutable MINT_WHITELIST_ONLY;
  mapping(uint256 => bool) public mintWhitelist;

  // Event
  event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);
  event AssetsEnabled(uint256[] enabledIds);
  event AssetsDisabled(uint256[] disabledIds);
  
  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory, link skyweaver assets and store initial parameters
   * @param _firstOwner      Address of the first owner
   * @param _assetsAddr      The address of the ERC-1155 Assets Token contract
   * @param _periodLength    Number of seconds each period lasts
   * @param _periodMintLimit Can only mint N assets per period
   * @param _whitelistOnly   Whether this factory uses a mint whitelist or not
   */
  constructor(
    address _firstOwner,
    address _assetsAddr,
    uint256 _periodLength,
    uint256 _periodMintLimit,
    bool _whitelistOnly
  ) TieredOwnable(_firstOwner) public {
    require(
      _assetsAddr != address(0) &&
      _periodLength > 0 &&
      _periodMintLimit > 0,
      "RewardFactory#constructor: INVALID_INPUT"
    );

    // Assets
    skyweaverAssets = ISkyweaverAssets(_assetsAddr);

    // Set Period length
    PERIOD_LENGTH = _periodLength;

    // Set whether this factory uses a mint whitelist or not
    MINT_WHITELIST_ONLY = _whitelistOnly;

    // Set current period
    period = block.timestamp / _periodLength; // From livePeriod()
    availableSupply = _periodMintLimit;

    // Rewards parameters
    periodMintLimit = _periodMintLimit;
    emit PeriodMintLimitChanged(0, _periodMintLimit);
  }


  /***********************************|
  |         Management Methods        |
  |__________________________________*/

  /**
   * @notice Will update the daily mint limit
   * @dev This change will take effect immediatly once executed
   * @param _newPeriodMintLimit Amount of assets that can be minted within a period
   */
  function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    // Immediately update supply instead of waiting for next period
    if (availableSupply > _newPeriodMintLimit) {
      availableSupply = _newPeriodMintLimit;
    }

    emit PeriodMintLimitChanged(periodMintLimit, _newPeriodMintLimit);
    periodMintLimit = _newPeriodMintLimit;
  }

  /**
   * @notice Will enable these tokens to be minted by this factory
   * @param _enabledIds IDs this factory can mint
   */
  function enableMint(uint256[] calldata _enabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    for (uint256 i = 0; i < _enabledIds.length; i++) {
      mintWhitelist[_enabledIds[i]] = true;
    }
    emit AssetsEnabled(_enabledIds);
  }

  /**
   * @notice Will prevent these ids from being minted by this factory
   * @param _disabledIds IDs this factory can mint
   */
  function disableMint(uint256[] calldata _disabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    for (uint256 i = 0; i < _disabledIds.length; i++) {
      mintWhitelist[_disabledIds[i]] = false;
    }
    emit AssetsDisabled(_disabledIds);
  }


  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("RewardFactory#_: UNSUPPORTED_METHOD");
  }

  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @notice Will mint tokens to user
   * @dev Can only mint up to the periodMintLimit in a given 6hour period
   * @param _to      The address that receives the assets
   * @param _ids     Array of Tokens ID that are minted
   * @param _amounts Amount of Tokens id minted for each corresponding Token id in _ids
   * @param _data    Byte array passed to recipient if recipient is a contract
   */
  function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data)
    external onlyOwnerTier(1)
  {
    uint256 live_period = livePeriod();
    uint256 stored_period = period;
    uint256 available_supply;

    // Update period and refresh the available supply if period
    // is different, otherwise use current available supply.
    if (live_period == stored_period) {
      available_supply = availableSupply;
    } else {
      available_supply = periodMintLimit;
      period = live_period;
    }

    // If there is an insufficient available supply, this will revert
    for (uint256 i = 0; i < _ids.length; i++) {
      available_supply = available_supply.sub(_amounts[i]);
      if (MINT_WHITELIST_ONLY) {
        require(mintWhitelist[_ids[i]], "RewardFactory#batchMint: ID_IS_NOT_WHITELISTED");
      }
    }

    // Store available supply
    availableSupply = available_supply;
    
    // Mint assets
    skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Returns how many cards can currently be minted by this factory
   */
  function getAvailableSupply() external view returns (uint256) {
    return livePeriod() == period ? availableSupply : periodMintLimit;
  }

  /**
   * @notice Calculate the current period
   */
  function livePeriod() public view returns (uint256) {
    return block.timestamp / PERIOD_LENGTH;
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId;
  }
}

File 16 of 29 : DelayedOwner.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "./Ownable.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";

/**
 * @dev This contract allows an owner to execute registered calls after an expiration
 *      delay has passed. This contract can then be the owner of another contract to
 *      enforce delayed function calls.
 * @dev Does not support passing ETH in calls for simplicity, but could be added in V2.
 */
contract DelayedOwner is Ownable {
  using SafeMath for uint256;

  // Time transactions must be registered before being executable
  uint256 immutable internal EXECUTION_DELAY;
  
  // Mapping between transaction id and transaction hashes
  mapping(uint256 => bytes32) public txHashes;

  // Events
  event TransactionRegistered(Transaction transaction);
  event TransactionCancelled(Transaction transaction);
  event TransactionExecuted(Transaction transaction);

  // Transaction structure
  struct Transaction {
    Status status;       // Transaction status
    uint256 triggerTime; // Timestamp after which the transaction can be executed
    address target;      // Address of the contract to call
    uint256 id;          // Transaction identifier (unique)
    bytes data;          // calldata to pass
  }

  enum Status {
    NotRegistered, // 0x0 - Transaction was not registered
    Pending,       // 0x1 - Transaction was registered but not executed
    Executed,      // 0x2 - Transaction was executed
    Cancelled      // 0x3 - Transaction was registered and cancelled
  }

  /**
   * @dev Registers the execution delay for this contract 
   * @param _firstOwner Address of the first owner
   * @param _delay Amount of time in seconds the delay will be
   */
  constructor (address _firstOwner, uint256 _delay) Ownable(_firstOwner) {
    EXECUTION_DELAY = _delay;
  }


  /***********************************|
  |           Core Functions          |
  |__________________________________*/

  /**
   * @notice Register a transaction to execute post delay
   * @param _tx Transaction to execute
   */
  function register(Transaction memory _tx) onlyOwner() public {
    require(txHashes[_tx.id] == 0x0, "DelayedOwner#register: TX_ALREADY_REGISTERED");

    // Set trigger time and mark transaction as pending
    _tx.triggerTime = block.timestamp.add(EXECUTION_DELAY);
    _tx.status = Status.Pending;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));
    emit TransactionRegistered(_tx);
  }

  /**
   * @notice Cancels a transaction that was registered but not yet executed or cancelled
   * @param _tx Transaction to cancel
   */
  function cancel(Transaction memory _tx) onlyOwner() onlyValidWitnesses(_tx) public {
    require(_tx.status == Status.Pending, "DelayedOwner#cancel: TX_NOT_PENDING");

    // Set status to Cancelled
    _tx.status = Status.Cancelled;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));
    emit TransactionCancelled(_tx);
  }

  /**
   * @notice Will execute transaction specified
   * @param _tx Transaction to execute
   */
  function execute(Transaction memory _tx) onlyValidWitnesses(_tx) public {
    require(_tx.status == Status.Pending, "DelayedOwner#execute: TX_NOT_PENDING");
    require(_tx.triggerTime <= block.timestamp, "DelayedOwne#execute: TX_NOT_YET_EXECUTABLE");

    // Mark transaction as executed, preventing re-entrancy and replay
    _tx.status = Status.Executed;

    // Store transaction
    txHashes[_tx.id] = keccak256(abi.encode(_tx));

    // Execute transaction
    (bool success,) = _tx.target.call(_tx.data);
    require(success, "DelayedOwner#execute: TX_FAILED");
    emit TransactionExecuted(_tx); 
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Verify if provided transaction object matches registered transaction
   * @param _tx Transaction to validate
   */
  function isValidWitness(Transaction memory _tx) public view returns (bool isValid) {
    return txHashes[_tx.id] == keccak256(abi.encode(_tx));
  }

  /**
   * @notice Will enforce that the provided transaction witness is valid
   * @param _tx Transaction to validate
   */
  modifier onlyValidWitnesses(Transaction memory _tx) {
    require(
      isValidWitness(_tx),
      "DelayedOwner#onlyValidWitnesses: INVALID_TX_WITNESS"
    );

    _;
  }
}

File 17 of 29 : Ownable.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

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

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

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the specied address
   * @param _firstOwner Address of the first owner
   */
  constructor (address _firstOwner) {
    owner = _firstOwner;
    emit OwnershipTransferred(address(0), _firstOwner);
  }

  /**
   * @dev Throws if called by any account other than the master owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner, "Ownable#onlyOwner: SENDER_IS_NOT_OWNER");
    _;
  }

  /**
   * @notice Transfers the ownership of the contract to new address
   * @param _newOwner Address of the new owner
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    require(_newOwner != address(0), "Ownable#transferOwnership: INVALID_ADDRESS");
    owner = _newOwner;
    emit OwnershipTransferred(owner, _newOwner);
  }

  /**
   * @notice Returns the address of the owner.
   */
  function getOwner() public view returns (address) {
    return owner;
  }

}

File 18 of 29 : ERC1155MintBurnPackedBalance.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "./ERC1155PackedBalance.sol";


/**
 * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
 *      a parent contract to be executed as they are `internal` functions.
 */
contract ERC1155MintBurnPackedBalance is ERC1155PackedBalance {

  /****************************************|
  |            Minting Functions           |
  |_______________________________________*/

  /**
   * @notice Mint _amount of tokens of a given id
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
    internal
  {
    //Add _amount
    _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

    // Emit event
    emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);

    // Calling onReceive method if recipient is contract
    _callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Mint tokens for each (_ids[i], _amounts[i]) pair
   * @param _to       The address to mint tokens to
   * @param _ids      Array of ids to mint
   * @param _amounts  Array of amount of tokens to mint per id
   * @param _data    Data to pass if receiver is contract
   */
  function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#_batchMint: INVALID_ARRAYS_LENGTH");

    if (_ids.length > 0) {
      // Load first bin and index where the token ID balance exists
      (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

      // Balance for current bin in memory (initialized with first transfer)
      uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

      // Number of transfer to execute
      uint256 nTransfer = _ids.length;

      // Last bin updated
      uint256 lastBin = bin;

      for (uint256 i = 1; i < nTransfer; i++) {
        (bin, index) = getIDBinIndex(_ids[i]);

        // If new bin
        if (bin != lastBin) {
          // Update storage balance of previous bin
          balances[_to][lastBin] = balTo;
          balTo = balances[_to][bin];

          // Bin will be the most recent bin
          lastBin = bin;
        }

        // Update memory balance
        balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
      }

      // Update storage of the last bin visited
      balances[_to][bin] = balTo;
    }

    // //Emit event
    emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);

    // Calling onReceive method if recipient is contract
    _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
  }


  /****************************************|
  |            Burning Functions           |
  |_______________________________________*/

  /**
   * @notice Burn _amount of tokens of a given token id
   * @param _from    The address to burn tokens from
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function _burn(address _from, uint256 _id, uint256 _amount)
    internal
  {
    // Substract _amount
    _updateIDBalance(_from, _id, _amount, Operations.Sub);

    // Emit event
    emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
  }

  /**
   * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @dev This batchBurn method does not implement the most efficient way of updating
   *      balances to reduce the potential bug surface as this function is expected to
   *      be less common than transfers. EIP-2200 makes this method significantly
   *      more efficient already for packed balances.
   * @param _from     The address to burn tokens from
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    // Number of burning to execute
    uint256 nBurn = _ids.length;
    require(nBurn == _amounts.length, "ERC1155MintBurnPackedBalance#batchBurn: INVALID_ARRAYS_LENGTH");

    // Executing all burning
    for (uint256 i = 0; i < nBurn; i++) {
      // Update storage balance
      _updateIDBalance(_from,   _ids[i], _amounts[i], Operations.Sub); // Add amount to recipient
    }

    // Emit batch burn event
    emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
  }
}

File 19 of 29 : ERC1155Metadata.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../interfaces/IERC1155Metadata.sol";
import "../../utils/ERC165.sol";


/**
 * @notice Contract that handles metadata related methods.
 * @dev Methods assume a deterministic generation of URI based on token IDs.
 *      Methods also assume that URI uses hex representation of token IDs.
 */
contract ERC1155Metadata is IERC1155Metadata, ERC165 {
  // URI's default URI prefix
  string public baseURI;
  string public name;

  // set the initial name and base URI
  constructor(string memory _name, string memory _baseURI) {
    name = _name;
    baseURI = _baseURI;
  }

  /***********************************|
  |     Metadata Public Functions     |
  |__________________________________*/

  /**
   * @notice A distinct Uniform Resource Identifier (URI) for a given token.
   * @dev URIs are defined in RFC 3986.
   *      URIs are assumed to be deterministically generated based on token ID
   * @return URI string
   */
  function uri(uint256 _id) public override view returns (string memory) {
    return string(abi.encodePacked(baseURI, _uint2str(_id), ".json"));
  }


  /***********************************|
  |    Metadata Internal Functions    |
  |__________________________________*/

  /**
   * @notice Will emit default URI log event for corresponding token _id
   * @param _tokenIDs Array of IDs of tokens to log default URI
   */
  function _logURIs(uint256[] memory _tokenIDs) internal {
    string memory baseURL = baseURI;
    string memory tokenURI;

    for (uint256 i = 0; i < _tokenIDs.length; i++) {
      tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
      emit URI(tokenURI, _tokenIDs[i]);
    }
  }

  /**
   * @notice Will update the base URL of token's URI
   * @param _newBaseMetadataURI New base URL of token's URI
   */
  function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
    baseURI = _newBaseMetadataURI;
  }

  /**
   * @notice Will update the name of the contract
   * @param _newName New contract name
   */
  function _setContractName(string memory _newName) internal {
    name = _newName;
  }

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155Metadata).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }


  /***********************************|
  |    Utility Internal Functions     |
  |__________________________________*/

  /**
   * @notice Convert uint256 to string
   * @param _i Unsigned integer to convert to string
   */
  function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {
    if (_i == 0) {
      return "0";
    }

    uint256 j = _i;
    uint256 ii = _i;
    uint256 len;

    // Get number of bytes
    while (j != 0) {
      len++;
      j /= 10;
    }

    bytes memory bstr = new bytes(len);
    uint256 k = len - 1;

    // Get each individual ASCII
    while (ii != 0) {
      bstr[k--] = byte(uint8(48 + ii % 10));
      ii /= 10;
    }

    // Convert to string
    return string(bstr);
  }
}

File 20 of 29 : IERC1155Metadata.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;


interface IERC1155Metadata {

  event URI(string _uri, uint256 indexed _id);

  /****************************************|
  |                Functions               |
  |_______________________________________*/

  /**
   * @notice A distinct Uniform Resource Identifier (URI) for a given token.
   * @dev URIs are defined in RFC 3986.
   *      URIs are assumed to be deterministically generated based on token ID
   *      Token IDs are assumed to be represented in their hex format in URIs
   * @return URI string
   */
  function uri(uint256 _id) external view returns (string memory);
}

File 21 of 29 : ERC1155MintBurnMock.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

import "../tokens/ERC1155/ERC1155MintBurn.sol";
import "../tokens/ERC1155/ERC1155Metadata.sol";


contract ERC1155MintBurnMock is ERC1155MintBurn, ERC1155Metadata {

  // set the initial name and base URI
  constructor(string memory _name, string memory _baseURI) ERC1155Metadata(_name, _baseURI) {}

  /**
   * @notice Query if a contract implements an interface
   * @dev Parent contract inheriting multiple contracts with supportsInterface()
   *      need to implement an overriding supportsInterface() function specifying
   *      all inheriting contracts that have a supportsInterface() function.
   * @param _interfaceID The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(
    bytes4 _interfaceID
  ) public override(
    ERC1155,
    ERC1155Metadata
  ) pure virtual returns (bool) {
    return super.supportsInterface(_interfaceID);
  }

  /***********************************|
  |         Minting Functions         |
  |__________________________________*/

  /**
   * @dev Mint _value of tokens of a given id
   * @param _to The address to mint tokens to.
   * @param _id token id to mint
   * @param _value The amount to be minted
   * @param _data Data to be passed if receiver is contract
   */
  function mintMock(address _to, uint256 _id, uint256 _value, bytes memory _data)
    public
  {
    super._mint(_to, _id, _value, _data);
  }

  /**
   * @dev Mint tokens for each ids in _ids
   * @param _to The address to mint tokens to.
   * @param _ids Array of ids to mint
   * @param _values Array of amount of tokens to mint per id
   * @param _data Data to be passed if receiver is contract
   */
  function batchMintMock(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
    public
  {
    super._batchMint(_to, _ids, _values, _data);
  }


  /***********************************|
  |         Burning Functions         |
  |__________________________________*/

  /**
   * @dev burn _value of tokens of a given token id
   * @param _from The address to burn tokens from.
   * @param _id token id to burn
   * @param _value The amount to be burned
   */
  function burnMock(address _from, uint256 _id, uint256 _value)
    public
  {
    super._burn(_from, _id, _value);
  }

  /**
   * @dev burn _value of tokens of a given token id
   * @param _from The address to burn tokens from.
   * @param _ids Array of token ids to burn
   * @param _values Array of the amount to be burned
   */
  function batchBurnMock(address _from, uint256[] memory _ids, uint256[] memory _values)
    public
  {
    super._batchBurn(_from, _ids, _values);
  }
  
  /***********************************|
  |       Unsupported Functions       |
  |__________________________________*/

  fallback () virtual external {
    revert("ERC1155MetaMintBurnMock: INVALID_METHOD");
  }
}

File 22 of 29 : ERC1155MintBurn.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "./ERC1155.sol";


/**
 * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
 *      a parent contract to be executed as they are `internal` functions
 */
contract ERC1155MintBurn is ERC1155 {
  using SafeMath for uint256;

  /****************************************|
  |            Minting Functions           |
  |_______________________________________*/

  /**
   * @notice Mint _amount of tokens of a given id
   * @param _to      The address to mint tokens to
   * @param _id      Token id to mint
   * @param _amount  The amount to be minted
   * @param _data    Data to pass if receiver is contract
   */
  function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
    internal
  {
    // Add _amount
    balances[_to][_id] = balances[_to][_id].add(_amount);

    // Emit event
    emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);

    // Calling onReceive method if recipient is contract
    _callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Mint tokens for each ids in _ids
   * @param _to       The address to mint tokens to
   * @param _ids      Array of ids to mint
   * @param _amounts  Array of amount of tokens to mint per id
   * @param _data    Data to pass if receiver is contract
   */
  function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH");

    // Number of mints to execute
    uint256 nMint = _ids.length;

     // Executing all minting
    for (uint256 i = 0; i < nMint; i++) {
      // Update storage balance
      balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
    }

    // Emit batch mint event
    emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);

    // Calling onReceive method if recipient is contract
    _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
  }


  /****************************************|
  |            Burning Functions           |
  |_______________________________________*/

  /**
   * @notice Burn _amount of tokens of a given token id
   * @param _from    The address to burn tokens from
   * @param _id      Token id to burn
   * @param _amount  The amount to be burned
   */
  function _burn(address _from, uint256 _id, uint256 _amount)
    internal
  {
    //Substract _amount
    balances[_from][_id] = balances[_from][_id].sub(_amount);

    // Emit event
    emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
  }

  /**
   * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
   * @param _from     The address to burn tokens from
   * @param _ids      Array of token ids to burn
   * @param _amounts  Array of the amount to be burned
   */
  function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    // Number of mints to execute
    uint256 nBurn = _ids.length;
    require(nBurn == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH");

    // Executing all minting
    for (uint256 i = 0; i < nBurn; i++) {
      // Update storage balance
      balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
    }

    // Emit batch mint event
    emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
  }
}

File 23 of 29 : ERC1155.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;

import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";


/**
 * @dev Implementation of Multi-Token Standard contract
 */
contract ERC1155 is IERC1155, ERC165 {
  using SafeMath for uint256;
  using Address for address;

  /***********************************|
  |        Variables and Events       |
  |__________________________________*/

  // onReceive function signatures
  bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
  bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;

  // Objects balances
  mapping (address => mapping(uint256 => uint256)) internal balances;

  // Operator Functions
  mapping (address => mapping(address => bool)) internal operators;


  /***********************************|
  |     Public Transfer Functions     |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   * @param _data    Additional data with no specified format, sent in call to `_to`
   */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
    public override
  {
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
    // require(_amount <= balances[_from][_id]) is not necessary since checked with safemath operations

    _safeTransferFrom(_from, _to, _id, _amount);
    _callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   * @param _data     Additional data with no specified format, sent in call to `_to`
   */
  function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
    require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");

    _safeBatchTransferFrom(_from, _to, _ids, _amounts);
    _callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
  }


  /***********************************|
  |    Internal Transfer Functions    |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   */
  function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
    internal
  {
    // Update balances
    balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount
    balances[_to][_id] = balances[_to][_id].add(_amount);     // Add amount

    // Emit event
    emit TransferSingle(msg.sender, _from, _to, _id, _amount);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
   */
  function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Check if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas: _gasLimit}(msg.sender, _from, _id, _amount, _data);
      require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
    }
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   */
  function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");

    // Number of transfer to execute
    uint256 nTransfer = _ids.length;

    // Executing all transfers
    for (uint256 i = 0; i < nTransfer; i++) {
      // Update storage balance of previous bin
      balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
      balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
    }

    // Emit event
    emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
   */
  function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Pass data if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
      require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
    }
  }


  /***********************************|
  |         Operator Functions        |
  |__________________________________*/

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved)
    external override
  {
    // Update operator status
    operators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator)
    public override view returns (bool isOperator)
  {
    return operators[_owner][_operator];
  }


  /***********************************|
  |         Balance Functions         |
  |__________________________________*/

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id)
    public override view returns (uint256)
  {
    return balances[_owner][_id];
  }

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders
   * @param _ids    ID of the Tokens
   * @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
   */
  function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
    public override view returns (uint256[] memory)
  {
    require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");

    // Variables
    uint256[] memory batchBalances = new uint256[](_owners.length);

    // Iterate over each owner and token ID
    for (uint256 i = 0; i < _owners.length; i++) {
      batchBalances[i] = balances[_owners[i]][_ids[i]];
    }

    return batchBalances;
  }


  /***********************************|
  |          ERC165 Functions         |
  |__________________________________*/

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID  The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID` and
   */
  function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
    if (_interfaceID == type(IERC1155).interfaceId) {
      return true;
    }
    return super.supportsInterface(_interfaceID);
  }
}

File 24 of 29 : ConquestEntriesFactory.sol
pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";

/**
 * @notice Allows players to convert their silver cards and Wrapped DAI (wDAI) to conquest entries.
 *
 * @dev Assumes both cards and entries have the same number of decimals, if not, need to change
 * the amount minted.
 * 
 * @dev This contract should only be able to mint conquest entries.
 */
contract ConquestEntriesFactory is IERC1155TokenReceiver, TieredOwnable {
  using SafeMath for uint256;
  
  /***********************************|
  |             Variables             |
  |__________________________________*/

  // Assets
  ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
  IERC1155 immutable internal wDai;                  // ERC-1155 Wrapped DAI contract
  uint256 immutable public wDaiID;                   // ID of wDAI token in respective ERC-1155 contract
  uint256 immutable public silverRangeMin;           // Lower bound for the range of asset IDs that can be converted to entries
  uint256 immutable public silverRangeMax;           // Upper bound for the range of asset IDs that can be converted to entries

  // Conquest entry token id
  uint256 immutable public conquestEntryID; 

  // Parameters
  uint256 constant internal CARD_DECIMALS = 2;                     // Number of decimals cards have
  uint256 constant internal ENTRIES_DECIMALS = 2;                  // Number of decimals entries have
  uint256 constant internal wDAI_DECIMALS = 6;                    // Number of decimals wDAI have
  uint256 constant internal wDAI_REQUIRED = 15 * 10**(wDAI_DECIMALS-1); // 1.5 wDAI for 1 conquest entry (after decimals)


  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory, link skyweaver assets and store initial parameters
   * @param _firstOwner             Address of the first owner
   * @param _skyweaverAssetsAddress The address of the ERC-1155 Assets Token contract
   * @param _wDaiAddress            The address of the ERC-1155 Wrapped DAI
   * @param _wDaiID                 Wrapped DAI token id
   * @param _conquestEntryTokenId   Conquest entry token id
   * @param _silverRangeMin         Minimum id for silver cards
   * @param _silverRangeMax         Maximum id for silver cards
   */
  constructor(
    address _firstOwner,
    address _skyweaverAssetsAddress,
    address _wDaiAddress,
    uint256 _wDaiID,
    uint256 _conquestEntryTokenId,
    uint256 _silverRangeMin,
    uint256 _silverRangeMax
  ) TieredOwnable(_firstOwner) public 
  {
    require(
      _skyweaverAssetsAddress != address(0) && 
      _wDaiAddress != address(0) &&
      _silverRangeMin < _silverRangeMax,
      "ConquestEntriesFactory#constructor: INVALID_INPUT"
    );

    // Assets
    skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
    wDai = IERC1155(_wDaiAddress);
    wDaiID = _wDaiID;
    conquestEntryID = _conquestEntryTokenId;
    silverRangeMin = _silverRangeMin;
    silverRangeMax = _silverRangeMax;
  }

  
  /***********************************|
  |      Receiver Method Handler      |
  |__________________________________*/

  /**
   * @notice Prevents receiving Ether or calls to unsuported methods
   */
  fallback () external {
    revert("ConquestEntriesFactory#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Players converting silver cards to conquest entries
   * @dev Payload is passed to and verified by onERC1155BatchReceived()
   */
  function onERC1155Received(
    address _operator,
    address _from,
    uint256 _id, 
    uint256 _amount, 
    bytes calldata _data
  )
    external override returns(bytes4)
  {
    // Convert payload to arrays to pass to onERC1155BatchReceived()
    uint256[] memory ids = new uint256[](1);
    uint256[] memory amounts = new uint256[](1);
    ids[0] = _id;
    amounts[0] = _amount;

    // Will revert call if doesn't pass
    onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
    
    // Return success
    return IERC1155TokenReceiver.onERC1155Received.selector;
  }

  /**
   * @notice Players converting silver cards or wDAIs to conquest entries
   * @param _from    Address who sent the token
   * @param _ids     An array containing ids of each Token being transferred
   * @param _amounts An array containing amounts of each Token being transferred
   * @param _data    If data is provided, it should be address who will receive the entries
   */
  function onERC1155BatchReceived(
    address, // _operator
    address _from,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data
  )
    public override returns(bytes4)
  { 
    // Number of entries to mint
    uint256 n_entries = 0; 

    // Burn cards or store wDAI
    if (msg.sender == address(skyweaverAssets)) {
      
      // Validate IDs and count number of entries to mint
      for (uint256 i = 0; i < _ids.length; i++) {
        require(
          silverRangeMin <= _ids[i] && _ids[i] <= silverRangeMax, 
          "ConquestEntriesFactory#onERC1155BatchReceived: ID_IS_OUT_OF_RANGE"
        );
        n_entries = n_entries.add(_amounts[i]);
      }
      // Account for cards decimals
      n_entries = n_entries.div(10**CARD_DECIMALS);

      // Burn silver cards received
      skyweaverAssets.batchBurn(_ids, _amounts);

    } else if (msg.sender == address(wDai)) {
      require(_ids.length == 1, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_ARRAY_LENGTH");
      require(_ids[0] == wDaiID, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_wDAI_ID");
      n_entries = _amounts[0] / wDAI_REQUIRED; 

      // Do nothing else. wDAIs are stored until withdrawn

    } else {
      revert("ConquestEntriesFactory#onERC1155BatchReceived: INVALID_TOKEN_ADDRESS");
    }

    // If an address is specified in _data, use it as receiver, otherwise use _from address
    address receiver = _data.length > 0 ? abi.decode(_data, (address)) : _from;

    // Mint conquest entries (with decimals)
    skyweaverAssets.mint(receiver, conquestEntryID, n_entries*10**ENTRIES_DECIMALS, "");

    // Return success
    return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
  }

  /**
   * @notice Send current wDAI balance of this contract to recipient
   * @param _recipient Address where the currency will be sent to
   * @param _data      Data to pass with transfer function
   */
  function withdraw(address _recipient, bytes calldata _data) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
    require(_recipient != address(0x0), "ConquestEntriesFactory#withdraw: INVALID_RECIPIENT");
    uint256 this_balance = wDai.balanceOf(address(this), wDaiID);
    wDai.safeTransferFrom(address(this), _recipient, wDaiID, this_balance, _data);
  }


  /***********************************|
  |         Utility Functions         |
  |__________________________________*/

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId || 
      interfaceID == type(IERC1155TokenReceiver).interfaceId;
  }
}

File 25 of 29 : FactoryMock.sol
pragma solidity 0.7.4;
import "../interfaces/ISkyweaverAssets.sol";

contract FactoryMock {

  ISkyweaverAssets internal skyweaverAssets; //SkyWeaver Curencies Factory Manager Contract

  constructor(address _factoryManagerAddr) public {
    skyweaverAssets = ISkyweaverAssets(_factoryManagerAddr);
  }

  function batchMint(
    address _to,
    uint256[] memory _ids,
    uint256[] memory _amounts,
    bytes memory _data) public
  {
    skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
  }

  function mint(
    address _to,
    uint256 _id,
    uint256 _amount,
    bytes memory _data) public
  {
    skyweaverAssets.mint(_to, _id, _amount, _data);
  }

}

File 26 of 29 : FreemintFactory.sol
pragma solidity 0.7.4;

import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";

/**
 * This is a contract allowing owner to mint any tokens within a given
 * range. This factory will be used to mint community related assets, special
 * event assets that are meant to be given away.
 */
contract FreemintFactory is TieredOwnable {

  // ERC-1155 Skyweaver assets contract
  ISkyweaverAssets internal skyweaverAssets;

  /***********************************|
  |            Constructor            |
  |__________________________________*/

  /**
   * @notice Create factory & link skyweaver assets
   * @param _firstOwner Address of the first owner
   * @param _assetsAddr The address of the ERC-1155 Assets Token contract
   */
  constructor(address _firstOwner, address _assetsAddr) TieredOwnable(_firstOwner) public {
    require(
      _assetsAddr != address(0),
      "FreemintFactory#constructor: INVALID_INPUT"
    );
    skyweaverAssets = ISkyweaverAssets(_assetsAddr);
  }


  /***********************************|
  |         Minting Function          |
  |__________________________________*/

  /**
   * @notice Will mint a bundle of tokens to users
   * @param _recipients Arrays of addresses to mint _amounts of _ids
   * @param _ids        Array of Tokens ID that are minted
   * @param _amounts    Amount of Tokens id minted for each corresponding Token id in _ids
   */
  function batchMint(address[] calldata _recipients, uint256[] calldata _ids, uint256[] calldata _amounts)
    external onlyOwnerTier(1)
  {
    for (uint256 i = 0 ; i < _recipients.length; i++) {
      skyweaverAssets.batchMint(_recipients[i], _ids, _amounts, "");
    }
  }


  /***********************************|
  |          Misc Functions           |
  |__________________________________*/

  /**
   * @notice Returns the address of the  skyweaver assets contract
   */
  function getSkyweaverAssets() external view returns (address) {
    return address(skyweaverAssets);
  }

  /**
   * @notice Prevents receiving Ether, ERC-1155 or calls to unsuported methods
   */
  fallback () external {
    revert("FreemintFactory#_: UNSUPPORTED_METHOD");
  }

  /**
   * @notice Indicates whether a contract implements a given interface.
   * @param interfaceID The ERC-165 interface ID that is queried for support.
   * @return True if contract interface is supported.
   */
  function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return  interfaceID == type(IERC165).interfaceId;
  }
}

File 27 of 29 : TieredOwnableMock.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "../utils/TieredOwnable.sol";

contract TieredOwnableMock is TieredOwnable {

  constructor(address _firstOwner) TieredOwnable(_firstOwner) public {}

  function onlyMaxTier() external onlyOwnerTier(HIGHEST_OWNER_TIER) returns(bool) {
    return true;
  }

  function onlyTierFive() external onlyOwnerTier(5) returns(bool) {
    return true;
  }

  function onlyTierZero() external onlyOwnerTier(0) returns(bool) {
    return true;
  }

  function anyone() external returns(bool) {
    return true;
  }
}

File 28 of 29 : ERC1155Mock.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "@0xsequence/erc-1155/contracts/mocks/ERC1155MintBurnMock.sol";

contract ERC1155Mock is ERC1155MintBurnMock {

  constructor() ERC1155MintBurnMock('ERC1155Mock', "") {}

}

File 29 of 29 : OwnableMock.sol
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;


import "../utils/Ownable.sol";

contract OwnableMock is Ownable {

  constructor(address _firstOwner) Ownable(_firstOwner) public {}

  function call_onlyOwner() external onlyOwner() returns(bool) {
    return true;
  }
  function call_anyone() external returns(bool) {
    return true;
  }

  function call_throw() external returns(bool) {
    revert(":/");
    return true;
  }

  fallback() external {}
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 100000,
    "details": {
      "yul": true,
      "constantOptimizer": false
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_firstOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryShutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"newMaxIssuances","type":"uint256[]"}],"name":"MaxIssuancesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"new_range","type":"tuple"}],"name":"MintPermissionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"deleted_range","type":"tuple"}],"name":"MintPermissionRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"locked_range","type":"tuple"}],"name":"RangeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"activateFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint64","name":"_minRange","type":"uint64"},{"internalType":"uint64","name":"_maxRange","type":"uint64"},{"internalType":"uint64","name":"_startTime","type":"uint64"},{"internalType":"uint64","name":"_endTime","type":"uint64"}],"name":"addMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getCurrentIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryAccessRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getIDBinIndex","outputs":[{"internalType":"uint256","name":"bin","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getLockedRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getMaxIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_binValues","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getValueInBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"globalRoyaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"feeBasisPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange","name":"_range","type":"tuple"}],"name":"lockRangeMintPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"}],"name":"logURIs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint256","name":"_rangeIndex","type":"uint256"}],"name":"removeMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_saleCost","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseMetadataURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_royaltyBasisPoints","type":"uint256"}],"name":"setGlobalRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_newMaxIssuances","type":"uint256[]"}],"name":"setMaxIssuances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"shutdownFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620052dc380380620052dc8339810160408190526200003491620001c7565b604080518082018252600981527f536b797765617665720000000000000000000000000000000000000000000000602080830191825283519081019093526000835281518493916200008a91600391906200011b565b508051620000a09060029060208401906200011b565b5050600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519091506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505062000204565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200015357600085556200019e565b82601f106200016e57805160ff19168380011785556200019e565b828001600101855582156200019e579182015b828111156200019e57825182559160200191906001019062000181565b50620001ac929150620001b0565b5090565b5b80821115620001ac5760008155600101620001b1565b600060208284031215620001d9578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114620001fd578182fd5b9392505050565b6150c880620002146000396000f3fe608060405234801561001057600080fd5b50600436106102255760003560e01c80639136ce1f1161012a578063d46c069e116100bd578063e985e9c51161008c578063f242432a11610071578063f242432a146104eb578063f2fde38b146104fe578063f795ab751461051157610225565b8063e985e9c5146104c5578063eaec5f81146104d857610225565b8063d46c069e1461046b578063db90e83c1461047e578063e1a972721461049f578063e4b37d33146104b257610225565b8063adccc471116100f9578063adccc4711461042a578063b390c0ab1461043d578063b48ab8b614610450578063c9823cc61461046357610225565b80639136ce1f146103de57806393cfa682146103f1578063a22cb46514610404578063a36b3f291461041757610225565b80632eb2c2d6116101bd5780636c0360eb1161018c5780637c44a8bb116101715780637c44a8bb146103a35780637e518ec8146103b6578063893d20e8146103c957610225565b80636c0360eb14610388578063731133e91461039057610225565b80632eb2c2d61461032d578063458d2844146103405780634e1273f414610353578063657afa891461037357610225565b80630e89341c116101f95780630e89341c146102d357806315a08ab8146102e657806320ec271b146102f95780632a55205a1461030c57610225565b8062fdd58e1461026057806301ffc9a71461028957806306fdde03146102a957806307800c9b146102be575b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906148ce565b60405180910390fd5b61027361026e366004614298565b610524565b6040516102809190614c7e565b60405180910390f35b61029c6102973660046144f5565b61057b565b6040516102809190614798565b6102b161058e565b60405161028091906147a3565b6102d16102cc366004614327565b61063a565b005b6102b16102e13660046145df565b610a0f565b6102d16102f436600461448c565b610b62565b6102d161030736600461448c565b610d3c565b61031f61031a3660046145f7565b610db0565b6040516102809291906146ba565b6102d161033b3660046140c0565b610e12565b6102d161034e366004614298565b610f1d565b61036661036136600461438b565b611312565b6040516102809190614760565b61037b611591565b60405161028091906146e0565b6102b161164c565b6102d161039e3660046142c1565b6116c2565b6102d16103b1366004614074565b611790565b6102d16103c4366004614535565b611855565b6103d16118e9565b6040516102809190614699565b6102d16103ec366004614074565b611905565b6102d16103ff366004614298565b6119cd565b6102d161041236600461425e565b611a28565b61037b610425366004614074565b611ac1565b6102d1610438366004614569565b611b9f565b6102d161044b3660046145f7565b611d57565b6102d161045e3660046141c9565b611d62565b61031f611d78565b6102d161047936600461444c565b611d9a565b61049161048c3660046145df565b611e27565b604051610280929190614c87565b6103666104ad36600461444c565b611e34565b6103666104c036600461444c565b611ed5565b61029c6104d336600461408e565b611f6d565b6102736104e63660046145f7565b611fa8565b6102d16104f9366004614166565b611fbb565b6102d161050c366004614074565b6120bf565b61029c61051f366004614074565b6121d2565b600080600061053284611e27565b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832085845290915290205491935091506105709082611fa8565b925050505b92915050565b6000610586826121fd565b90505b919050565b6003805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505081565b60065473ffffffffffffffffffffffffffffffffffffffff16331461068b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b60008367ffffffffffffffff16116106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a79565b8267ffffffffffffffff168467ffffffffffffffff16111561071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614905565b8067ffffffffffffffff168267ffffffffffffffff161061076a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614b33565b60005b6009548110156108705761077f613de4565b6009828154811061078c57fe5b600091825260209182902060408051608081018252919092015467ffffffffffffffff8082168084526801000000000000000083048216958401959095527001000000000000000000000000000000008204811693830193909352780100000000000000000000000000000000000000000000000090048216606082015292508616108061083157508567ffffffffffffffff16816020015167ffffffffffffffff16105b610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a1c565b5060010161076d565b50610879613de4565b506040805160808101825267ffffffffffffffff808716825285811660208084019182528683168486019081528684166060860190815273ffffffffffffffffffffffffffffffffffffffff8c166000818152600885528881208054600181018255908252949020875194018054955193519251871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff938816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff95891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff979099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009098169790971795909516969096179290921693909317929092161790915591519091907f188968bccf857d854c73494ca4da4cc4ae2769e4b732db8f40dfa62b86b1c40a906109ff908490614c70565b60405180910390a2505050505050565b60606002610a1c8361225a565b6040516020018083805460018160011615610100020316600290048015610a7a5780601f10610a58576101008083540402835291820191610a7a565b820191906000526020600020905b815481529060010190602001808311610a66575b5050825160208401908083835b60208310610ac457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a87565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990911692169190911790527f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe50181526005909201905295945050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b828114610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614871565b60005b83811015610cf8576000600b6000878785818110610c0957fe5b905060200201358152602001908152602001600020541115610cb357828282818110610c3157fe5b905060200201356000108015610c7d5750600b6000868684818110610c5257fe5b90506020020135815260200190815260200160002054838383818110610c7457fe5b90506020020135105b610cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614ad6565b828282818110610cbf57fe5b90506020020135600b6000878785818110610cd657fe5b6020908102929092013583525081019190915260400160002055600101610bef565b507f91f9ea1e3a6a1fd246959c27978a42e04c0c3c954e7ffa52e3ed1509be4811be84848484604051610d2e949392919061472e565b60405180910390a150505050565b610daa338585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061238692505050565b50505050565b600080610dbb613e0b565b506040805180820190915260045473ffffffffffffffffffffffffffffffffffffffff1680825260055460208301819052610e05906103e890610dff90889061252f565b906125bf565b92509250505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff86161480610e3b5750610e3b8533611f6d565b610e90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180614e46603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614d11603d913960400191505060405180910390fd5b610f0885858585612643565b610f16858585855a86612a50565b5050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260409020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610fbe613de4565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600860205260409020805484908110610fef57fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff8082168452680100000000000000008204811694840194909452700100000000000000000000000000000000810484169183019190915278010000000000000000000000000000000000000000000000009004909116606082015290508183146112585761107e613de4565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090208054849081106110af57fe5b6000918252602080832060408051608081018252919093015467ffffffffffffffff80821683526801000000000000000082048116838501527001000000000000000000000000000000008204811683860152780100000000000000000000000000000000000000000000000090910416606082015273ffffffffffffffffffffffffffffffffffffffff8916845260089091529120805491925082918690811061115657fe5b60009182526020918290208351910180549284015160408501516060909501517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff938416177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000091841691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000948316949094029390931777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009190921602179055505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260086020526040902080548061128657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081019190915501905560405173ffffffffffffffffffffffffffffffffffffffff8516907f1bca5c143feb87c2d4e8d2d1fd73ba6f43f551ba73c58634f56bbe30701f06d490611304908490614c70565b60405180910390a250505050565b81518151606091908114611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614cd86039913960400191505060405180910390fd5b6000806113918560008151811061138457fe5b6020026020010151611e27565b915091506000806000886000815181106113a757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020549050600083905060608567ffffffffffffffff8111801561141b57600080fd5b50604051908082528060200260200182016040528015611445578160200160208202803683370190505b5090506114528385611fa8565b8160008151811061145f57fe5b602090810291909101015260015b868110156115845761148489828151811061138457fe5b909650945082861415806114ed575089818151811061149f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a60018303815181106114cc57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b1561155b576000808b838151811061150157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000205493508592505b6115658486611fa8565b82828151811061157157fe5b602090810291909101015260010161146d565b5098975050505050505050565b60606009805480602002602001604051908101604052809291908181526020016000905b82821015611643576000848152602090819020604080516080810182529185015467ffffffffffffffff80821684526801000000000000000082048116848601527001000000000000000000000000000000008204811692840192909252780100000000000000000000000000000000000000000000000090041660608201528252600190920191016115b5565b50505050905090565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b604080516001808252818301909252606091602080830190803683375050604080516001808252818301909252929350606092915060208083019080368337019050509050858260008151811061171557fe5b602002602001018181525050848160008151811061172f57fe5b6020026020010181815250506117458282612cc5565b61178787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fc192505050565b50505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f472ecaf428225ecdcc1f686a662ed1ba0627c365542e086b483bacca0fcfa5f99190a250565b60065473ffffffffffffffffffffffffffffffffffffffff1633146118a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303592505050565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff163314611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f672dbf7f8dabd5b1b39124540440a9ef2537a03c053f111f7e90850e57e2efb69190a250565b60065473ffffffffffffffffffffffffffffffffffffffff163314611a1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e58282613048565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860209081526040808320805482518185028101850190935280835260609492939192909184015b82821015611b94576000848152602090819020604080516080810182529185015467ffffffffffffffff8082168452680100000000000000008204811684860152700100000000000000000000000000000000820481169284019290925278010000000000000000000000000000000000000000000000009004166060820152825260019092019101611b06565b505050509050919050565b60065473ffffffffffffffffffffffffffffffffffffffff163314611bf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6009805460018101825560009190915281517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018054602084015160408086015160608701517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff968716177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000093871693909302929092177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928616929092029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490921693909302179055517f522c18973f048c2a178766b76cb19456e9dbd776f104c0b77c6166e582212f2c90611d4c908390614c70565b60405180910390a150565b6118e533838361315a565b611d6c8383612cc5565b610daa848484846131c4565b60045460055473ffffffffffffffffffffffffffffffffffffffff9091169082565b60065473ffffffffffffffffffffffffffffffffffffffff163314611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344e92505050565b6008810491600790911690565b606081818167ffffffffffffffff81118015611e4f57600080fd5b50604051908082528060200260200182016040528015611e79578160200160208202803683370190505b50905060005b82811015611ecc57600b6000878784818110611e9757fe5b90506020020135815260200190815260200160002054828281518110611eb957fe5b6020908102919091010152600101611e7f565b50949350505050565b606081818167ffffffffffffffff81118015611ef057600080fd5b50604051908082528060200260200182016040528015611f1a578160200160208202803683370190505b50905060005b82811015611ecc57600a6000878784818110611f3857fe5b90506020020135815260200190815260200160002054828281518110611f5a57fe5b6020908102919091010152600101611f20565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205460ff1690565b6020810282901c63ffffffff1692915050565b3373ffffffffffffffffffffffffffffffffffffffff86161480611fe45750611fe48533611f6d565b612039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180614d816037913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166120a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614fa66038913960400191505060405180910390fd5b6120b18585858561370f565b610f16858585855a866137b3565b60065473ffffffffffffffffffffffffffffffffffffffff163314612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811661215d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906149bf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821792839055604051919216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000141561225157506001610589565b610586826139a4565b60608161229b575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152610589565b818060005b82156122b457600101600a830492506122a0565b60608167ffffffffffffffff811180156122cd57600080fd5b506040519080825280601f01601f1916602001820160405280156122f8576020820181803683370190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b831561237c57600a840660300160f81b8282806001900393508151811061234257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8404935061231f565b5095945050505050565b8151815181146123e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614eb3603d913960400191505060405180910390fd5b60005b818110156124275761241f858583815181106123fc57fe5b602002602001015185848151811061241057fe5b60200260200101516001613a01565b6001016123e4565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156124d55781810151838201526020016124bd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125145781810151838201526020016124fc565b5050505090500194505050505060405180910390a450505050565b60008261253e57506000610575565b8282028284828161254b57fe5b04146125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236d756c3a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b9392505050565b600080821161262f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d617468236469763a204449564953494f4e5f42595f5a45524f0000604482015290519081900360640190fd5b600082848161263a57fe5b04949350505050565b81518151811461269e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180614db86042913960600191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141580156126da5750600081115b156128ac576000806126f28560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff891660009081526020818152604080832085845290915281205487519395509193509161274a919084908890859061273b57fe5b60200260200101516001613a88565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320878452909152812054875192935090916127a0919085908990859061279157fe5b60200260200101516000613a88565b90508360015b8681101561285a576127bd89828151811061138457fe5b909650945081861461282c5773ffffffffffffffffffffffffffffffffffffffff8b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61283d84868a848151811061273b57fe5b935061285083868a848151811061279157fe5b92506001016127a6565b505073ffffffffffffffffffffffffffffffffffffffff808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550612949565b60005b81811015612947578281815181106128c357fe5b60200260200101516128e8878684815181106128db57fe5b6020026020010151610524565b101561293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180614ef06036913960400191505060405180910390fd5b6001016128af565b505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156129f55781810151838201526020016129dd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a34578181015183820152602001612a1c565b5050505090500194505050505060405180910390a45050505050565b612a6f8573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015612b27578181015183820152602001612b0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015612b66578181015183820152602001612b4e565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612ba2578181015183820152602001612b8a565b50505050905090810190601f168015612bcf5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600088803b158015612bf457600080fd5b5087f1158015612c08573d6000803e3d6000fd5b50505050506040513d6020811015612c1f57600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c810000000000000000000000000000000000000000000000000000000014611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c815260200180614dfa604c913960600191505060405180910390fd5b505050505050565b3360009081526007602052604090205460ff16612d0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614814565b33600090815260086020526040902054612d26613de4565b3360009081526008602052604081208054909190612d4057fe5b6000918252602080832060408051608081018252939091015467ffffffffffffffff80821685526801000000000000000082048116938501939093527001000000000000000000000000000000008104831691840191909152780100000000000000000000000000000000000000000000000090041660608201529150805b8551811015612cbd576000868281518110612dd657fe5b602002602001015190506000868381518110612dee57fe5b602002602001015190506000600b60008481526020019081526020016000205490505b856040015167ffffffffffffffff16421080612e3a5750856060015167ffffffffffffffff1642115b80612e4f5750855167ffffffffffffffff1683105b80612e67575082866020015167ffffffffffffffff16105b15612f4b57600185019450868510612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614962565b336000908152600860205260409020805486908110612ec657fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff808216845268010000000000000000820481169484019490945270010000000000000000000000000000000081048416918301919091527801000000000000000000000000000000000000000000000000900490911660608201529550612e11565b8015612fb6576000838152600a6020526040812054612f6a9084613cd2565b905081811115612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614c13565b6000848152600a60205260409020555b505050600101612dbf565b612fce8484846000613a01565b6040805184815260208101849052815173ffffffffffffffffffffffffffffffffffffffff87169260009233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4610daa60008585855a866137b3565b80516118e5906002906020840190613e22565b73ffffffffffffffffffffffffffffffffffffffff82166130b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614e826031913960400191505060405180910390fd5b6103e881111561310f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614f266039913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9390931692909217909155600555565b6131678383836001613a01565b6040805183815260208101839052815160009273ffffffffffffffffffffffffffffffffffffffff87169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4505050565b815183511461321e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180615023603e913960400191505060405180910390fd5b82511561333e576000806132388560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320858452909152812054875193955091935091613281919084908890859061279157fe5b86519091508360015b82811015613305576132a189828151811061138457fe5b90965094508186146132ea5773ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320948352939052828120949094558584529220549184905b6132fb84868a848151811061279157fe5b935060010161328a565b50505073ffffffffffffffffffffffffffffffffffffffff87166000908152602081815260408083209583529490529290922091909155505b8373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156133eb5781810151838201526020016133d3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561342a578181015183820152602001613412565b5050505090500194505050505060405180910390a4610daa60008585855a86612a50565b60028054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156134f55780601f106134ca576101008083540402835291602001916134f5565b820191906000526020600020905b8154815290600101906020018083116134d857829003601f168201915b50505050509050606060005b8351811015610daa578261352785838151811061351a57fe5b602002602001015161225a565b6040516020018083805190602001908083835b6020831061357757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b602083106135fb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135be565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060050192505050604051602081830303815290604052915083818151811061366657fe5b60200260200101517f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b836040518080602001828103825283818151815260200191508051906020019080838360005b838110156136cd5781810151838201526020016136b5565b50505050905090810190601f1680156136fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2600101613501565b61371c8483836001613a01565b6137298383836000613a01565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051808381526020018281526020019250505060405180910390a450505050565b6137d28573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388b578181015183820152602001613873565b50505050905090810190601f1680156138b85780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600088803b1580156138db57600080fd5b5087f11580156138ef573d6000803e3d6000fd5b50505050506040513d602081101561390657600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e610000000000000000000000000000000000000000000000000000000014611787576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526047815260200180614f5f6047913960600191505060405180910390fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c0000000000000000000000000000000000000000000000000000000014156139f857506001610589565b61058682613d46565b600080613a0d85611e27565b73ffffffffffffffffffffffffffffffffffffffff88166000908152602081815260408083208584529091529020549193509150613a4d90828686613a88565b73ffffffffffffffffffffffffffffffffffffffff909616600090815260208181526040808320948352939052919091209490945550505050565b60006020840263ffffffff82846001811115613aa057fe5b1415613b6e5784821b8701925086831015613b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b64010000000087831c8216860110613b69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b613c91565b6001846001811115613b7c57fe5b1415613c405784821b8703925086831115613be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b84818389901c161015613b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526045815260200180614fde6045913960600191505060405180910390fd5b5050949350505050565b6000813f80158015906125b857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b6000828201838110156125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236164643a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001415613d9a57506001610589565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610586565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604080518082019091526000808252602082015290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e585760008555613e9e565b82601f10613e7157805160ff1916838001178555613e9e565b82800160010185558215613e9e579182015b82811115613e9e578251825591602001919060010190613e83565b50613eaa929150613eae565b5090565b5b80821115613eaa5760008155600101613eaf565b803573ffffffffffffffffffffffffffffffffffffffff8116811461058957600080fd5b60008083601f840112613ef8578081fd5b50813567ffffffffffffffff811115613f0f578182fd5b6020830191508360208083028501011115610e0b57600080fd5b600082601f830112613f39578081fd5b8135613f4c613f4782614cb9565b614c95565b818152915060208083019084810181840286018201871015613f6d57600080fd5b60005b84811015613f8c57813584529282019290820190600101613f70565b505050505092915050565b60008083601f840112613fa8578182fd5b50813567ffffffffffffffff811115613fbf578182fd5b602083019150836020828501011115610e0b57600080fd5b600082601f830112613fe7578081fd5b813567ffffffffffffffff811115613ffb57fe5b61402c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614c95565b915080825283602082850101111561404357600080fd5b8060208401602084013760009082016020015292915050565b803567ffffffffffffffff8116811461058957600080fd5b600060208284031215614085578081fd5b6125b882613ec3565b600080604083850312156140a0578081fd5b6140a983613ec3565b91506140b760208401613ec3565b90509250929050565b600080600080600060a086880312156140d7578081fd5b6140e086613ec3565b94506140ee60208701613ec3565b9350604086013567ffffffffffffffff8082111561410a578283fd5b61411689838a01613f29565b9450606088013591508082111561412b578283fd5b61413789838a01613f29565b9350608088013591508082111561414c578283fd5b5061415988828901613fd7565b9150509295509295909350565b600080600080600060a0868803121561417d578081fd5b61418686613ec3565b945061419460208701613ec3565b93506040860135925060608601359150608086013567ffffffffffffffff8111156141bd578182fd5b61415988828901613fd7565b600080600080608085870312156141de578384fd5b6141e785613ec3565b9350602085013567ffffffffffffffff80821115614203578485fd5b61420f88838901613f29565b94506040870135915080821115614224578384fd5b61423088838901613f29565b93506060870135915080821115614245578283fd5b5061425287828801613fd7565b91505092959194509250565b60008060408385031215614270578182fd5b61427983613ec3565b91506020830135801515811461428d578182fd5b809150509250929050565b600080604083850312156142aa578182fd5b6142b383613ec3565b946020939093013593505050565b6000806000806000608086880312156142d8578283fd5b6142e186613ec3565b94506020860135935060408601359250606086013567ffffffffffffffff81111561430a578182fd5b61431688828901613f97565b969995985093965092949392505050565b600080600080600060a0868803121561433e578283fd5b61434786613ec3565b94506143556020870161405c565b93506143636040870161405c565b92506143716060870161405c565b915061437f6080870161405c565b90509295509295909350565b6000806040838503121561439d578182fd5b823567ffffffffffffffff808211156143b4578384fd5b818501915085601f8301126143c7578384fd5b81356143d5613f4782614cb9565b80828252602080830192508086018a8283870289010111156143f5578889fd5b8896505b8487101561441e5761440a81613ec3565b8452600196909601959281019281016143f9565b509096508701359350505080821115614435578283fd5b5061444285828601613f29565b9150509250929050565b6000806020838503121561445e578182fd5b823567ffffffffffffffff811115614474578283fd5b61448085828601613ee7565b90969095509350505050565b600080600080604085870312156144a1578182fd5b843567ffffffffffffffff808211156144b8578384fd5b6144c488838901613ee7565b909650945060208701359150808211156144dc578384fd5b506144e987828801613ee7565b95989497509550505050565b600060208284031215614506578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146125b8578182fd5b60008060208385031215614547578182fd5b823567ffffffffffffffff81111561455d578283fd5b61448085828601613f97565b60006080828403121561457a578081fd5b6040516080810181811067ffffffffffffffff8211171561459757fe5b6040526145a38361405c565b81526145b16020840161405c565b60208201526145c26040840161405c565b60408201526145d36060840161405c565b60608201529392505050565b6000602082840312156145f0578081fd5b5035919050565b60008060408385031215614609578182fd5b50508035926020909101359150565b60008284527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614649578081fd5b6020830280836020870137939093016020019283525090919050565b805167ffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147225761470f838551614665565b92840192608092909201916001016146fc565b50909695505050505050565b600060408252614742604083018688614618565b8281036020840152614755818587614618565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147225783518352928401929184019160010161477c565b901515815260200190565b6000602080835283518082850152825b818110156147cf578581018301518582016040015282016147b3565b818111156147e05783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526032908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f464143544f52595f4e4f545f4143544956450000000000000000000000000000606082015260800190565b60208082526036908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4152524159535f4c454e47544800000000000000000000606082015260800190565b60208082526012908201527f554e535550504f525445445f4d4554484f440000000000000000000000000000604082015260600190565b60208082526030908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a20494e56414c49445f52414e474500000000000000000000000000000000606082015260800190565b6020808252602f908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f49445f4f55545f4f465f52414e47450000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4f776e61626c65237472616e736665724f776e6572736869703a20494e56414c60408201527f49445f4144445245535300000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204f5645524c41505f574954485f4c4f434b45445f52414e474500000000606082015260800190565b6020808252602d908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204e554c4c5f52414e474500000000000000000000000000000000000000606082015260800190565b60208082526039908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4e45575f4d41585f49535355414e434500000000000000606082015260800190565b60208082526049908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a2053544152545f54494d455f49535f4e4f545f4c45535345525f5448454e60608201527f5f454e445f54494d450000000000000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f4f776e61626c65236f6e6c794f776e65723a2053454e4445525f49535f4e4f5460408201527f5f4f574e45520000000000000000000000000000000000000000000000000000606082015260800190565b60208082526035908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f4d41585f49535355414e43455f45584345454445440000000000000000000000606082015260800190565b608081016105758284614665565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cb157fe5b604052919050565b600067ffffffffffffffff821115614ccd57fe5b506020908102019056fe455243313135355061636b656442616c616e63652362616c616e63654f6642617463683a20494e56414c49445f41525241595f4c454e475448455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20554e444552464c4f57455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f4f50455241544f52455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f63616c6c6f6e45524331313535426174636852656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f4f50455241544f5245524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a20524543495049454e545f49535f307830455243313135354d696e744275726e5061636b656442616c616e63652362617463684275726e3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20554e444552464c4f5745524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a204645455f49535f41424f56455f3130305f50455243454e54455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433131353552656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20494e56414c49445f42494e5f57524954455f4f5045524154494f4e455243313135354d696e744275726e5061636b656442616c616e6365235f62617463684d696e743a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a204f564552464c4f57a2646970667358221220fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e864736f6c63430007040033000000000000000000000000bd8ea13981ded8038224e9c32607131ac3d8492d

Deployed ByteCode Sourcemap

802:16008:25:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8925:28;;;;;;;;;;:::i;:::-;;;;;;;;9699:261:10;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16607:201:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;476:18:7:-;;;:::i;:::-;;;;;;;:::i;3968:1055:25:-;;;;;;:::i;:::-;;:::i;:::-;;999:147:7;;;;;;:::i;:::-;;:::i;7368:692:25:-;;;;;;:::i;:::-;;:::i;15497:146::-;;;;;;:::i;:::-;;:::i;1737:262:11:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3444:547:10:-;;;;;;:::i;:::-;;:::i;5272:859:25:-;;;;;;:::i;:::-;;:::i;10318:1013:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14675:101:25:-;;;:::i;:::-;;;;;;;:::i;451:21:7:-;;;:::i;10147:367:25:-;;;;;;:::i;:::-;;:::i;3363:144::-;;;;;;:::i;:::-;;:::i;15890:137::-;;;;;;:::i;:::-;;:::i;1280:73:27:-;;;:::i;:::-;;;;;;;:::i;3092:145:25:-;;;;;;:::i;:::-;;:::i;8529:163::-;;;;;;:::i;:::-;;:::i;8707:230:10:-;;;;;;:::i;:::-;;:::i;14469:138:25:-;;;;;;:::i;:::-;;:::i;6779:145::-;;;;;;:::i;:::-;;:::i;15141:110::-;;;;;;:::i;:::-;;:::i;9563:313::-;;;;;;:::i;:::-;;:::i;513:32:11:-;;;:::i;16177:98:25:-;;;;;;:::i;:::-;;:::i;14001:189:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;13143:352:25:-;;;;;;:::i;:::-;;:::i;13838:372::-;;;;;;:::i;:::-;;:::i;9199:160:10:-;;;;;;:::i;:::-;;:::i;14447:432::-;;;;;;:::i;:::-;;:::i;2360:598::-;;;;;;:::i;:::-;;:::i;993:224:27:-;;;;;;:::i;:::-;;:::i;14282:116:25:-;;;;;;:::i;:::-;;:::i;9699:261:10:-;9781:7;9798:11;9815:13;9881:18;9895:3;9881:13;:18::i;:::-;9926:16;;;:8;:16;;;;;;;;;;;:21;;;;;;;;;9866:33;;-1:-1:-1;9866:33:10;-1:-1:-1;9912:43:10;;9866:33;9912:13;:43::i;:::-;9905:50;;;;9699:261;;;;;:::o;16607:201:25:-;16747:4;16766:37;16790:12;16766:23;:37::i;:::-;16759:44;;16607:201;;;;:::o;476:18:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3968:1055:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;4132:1:25::1;4120:9;:13;;;4112:71;;;;;;;;;;;;:::i;:::-;4210:9;4197:22;;:9;:22;;;;4189:83;;;;;;;;;;;;:::i;:::-;4299:8;4286:21;;:10;:21;;;4278:107;;;;;;;;;;;;:::i;:::-;4510:9;4505:286;4529:12;:19:::0;4525:23;::::1;4505:286;;;4563:30;;:::i;:::-;4596:12;4609:1;4596:15;;;;;;;;;::::0;;;::::1;::::0;;;;4563:48:::1;::::0;;::::1;::::0;::::1;::::0;;4596:15;;;::::1;4563:48:::0;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;;;-1:-1:-1;4637:30:25;::::1;;::::0;4636:68:::1;;;4694:9;4673:30;;:12;:18;;;:30;;;4636:68;4619:165;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;4550:3:25::1;;4505:286;;;;4847:23;;:::i;:::-;-1:-1:-1::0;4873:54:25::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;4933:26:::1;::::0;::::1;-1:-1:-1::0;4933:26:25;;;:16:::1;:26:::0;;;;;:38;;::::1;::::0;::::1;::::0;;;;;;;;;;;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;;4982:36;;4873:54;;4933:26;4982:36:::1;::::0;::::1;::::0;4873:54;;4982:36:::1;:::i;:::-;;;;;;;;856:1:27;3968:1055:25::0;;;;;:::o;999:147:7:-;1055:13;1107:7;1116:14;1126:3;1116:9;:14::i;:::-;1090:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1090:50:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1090:50:7;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;999:147:7:o;7368:692:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;7490:38:25;;::::1;7482:105;;;;;;;;;;;;:::i;:::-;7681:9;7676:325;7696:15:::0;;::::1;7676:325;;;7754:1;7731:11;:20;7743:4;;7748:1;7743:7;;;;;;;;;;;;;7731:20;;;;;;;;;;;;:24;7727:218;;;7790:16;;7807:1;7790:19;;;;;;;;;;;;;7786:1;:23;:69;;;;;7835:11;:20;7847:4;;7852:1;7847:7;;;;;;;;;;;;;7835:20;;;;;;;;;;;;7813:16;;7830:1;7813:19;;;;;;;;;;;;;:42;7786:69;7767:169;;;;;;;;;;;;:::i;:::-;7975:16;;7992:1;7975:19;;;;;;;;;;;;;7952:11;:20;7964:4;;7969:1;7964:7;;;;;;;;::::0;;::::1;::::0;;;::::1;;7952:20:::0;;-1:-1:-1;7952:20:25;::::1;::::0;;;;;;-1:-1:-1;7952:20:25;:42;7713:3:::1;;7676:325;;;;8012:43;8032:4;;8038:16;;8012:43;;;;;;;;;:::i;:::-;;;;;;;;7368:692:::0;;;;:::o;15497:146::-;15600:38;15611:10;15623:4;;15600:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15600:38:25;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15629:8:25;;-1:-1:-1;15629:8:25;;;;15600:38;;;15629:8;;15600:38;15629:8;15600:38;;;;;;;;;-1:-1:-1;15600:10:25;;-1:-1:-1;;;15600:38:25:i;:::-;15497:146;;;;:::o;1737:262:11:-;1831:16;1849:21;1881:19;;:::i;:::-;-1:-1:-1;1881:39:11;;;;;;;;;1903:17;1881:39;;;;;;;;;;;;;;1949:44;;1988:4;;1949:34;;:9;;:13;:34::i;:::-;:38;;:44::i;:::-;1926:68;;;;;1737:262;;;;;;:::o;3444:547:10:-;3630:10;:19;;;;;3629:60;;;3654:35;3671:5;3678:10;3654:16;:35::i;:::-;3621:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3768:17;;;3760:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3857:50;3880:5;3887:3;3892:4;3898:8;3857:22;:50::i;:::-;3913:73;3941:5;3948:3;3953:4;3959:8;3969:9;3980:5;3913:27;:73::i;:::-;3444:547;;;;;:::o;5272:859:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;5518:26:25::1;::::0;::::1;5497:18;5518:26:::0;;;:16:::1;:26;::::0;;;;:33;:37;;5617:33:::1;;:::i;:::-;5653:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:39;;5680:11;;5653:39;::::1;;;;;;::::0;;;::::1;::::0;;;;5617:75:::1;::::0;;::::1;::::0;::::1;::::0;;5653:39;;;::::1;5617:75:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;;;-1:-1:-1;5721:25:25;;::::1;5717:272;;5756:28;;:::i;:::-;5787:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:38;;5814:10;;5787:38;::::1;;;;;;::::0;;;::::1;::::0;;;5756:69:::1;::::0;;::::1;::::0;::::1;::::0;;5787:38;;;::::1;5756:69:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;::::1;;::::0;;;;5874:26:::1;::::0;::::1;::::0;;5756:69:::1;5874:26:::0;;;;;:39;;5756:69;;-1:-1:-1;5756:69:25;;5901:11;;5874:39;::::1;;;;;;::::0;;;::::1;::::0;;;;:52;;:39;::::1;:52:::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;;;::::0;;-1:-1:-1;5717:272:25::1;6035:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:32;;;::::1;;;;;::::0;;;::::1;::::0;;;;;;;;;;;;;;;6078:48:::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;6110:15;;6078:48:::1;:::i;:::-;;;;;;;;856:1:27;;5272:859:25::0;;:::o;10318:1013:10:-;10470:14;;10510:11;;10425:16;;10470:14;10498:23;;10490:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10611:11;10624:13;10641:22;10655:4;10660:1;10655:7;;;;;;;;;;;;;;10641:13;:22::i;:::-;10610:53;;;;10669:19;10691:8;:20;10700:7;10708:1;10700:10;;;;;;;;;;;;;;10691:20;;;;;;;;;;;;;;;:25;10712:3;10691:25;;;;;;;;;;;;10669:47;;10722:16;10741:3;10722:22;;10773:30;10820:8;10806:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10806:23:10;;10773:56;;10854:33;10868:11;10881:5;10854:13;:33::i;:::-;10835:13;10849:1;10835:16;;;;;;;;;;;;;;;;;:52;10955:1;10938:362;10962:8;10958:1;:12;10938:362;;;11000:22;11014:4;11019:1;11014:7;;;;;;;11000:22;10985:37;;-1:-1:-1;10985:37:10;-1:-1:-1;11104:15:10;;;;;:45;;;11139:7;11147:1;11139:10;;;;;;;;;;;;;;11123:26;;:7;11133:1;11131;:3;11123:12;;;;;;;;;;;;;;:26;;;;11104:45;11100:133;;;11175:8;:20;11184:7;11192:1;11184:10;;;;;;;;;;;;;;11175:20;;;;;;;;;;;;;;;:25;11196:3;11175:25;;;;;;;;;;;;11161:39;;11221:3;11210:14;;11100:133;11260:33;11274:11;11287:5;11260:13;:33::i;:::-;11241:13;11255:1;11241:16;;;;;;;;;;;;;;;;;:52;10972:3;;10938:362;;;-1:-1:-1;11313:13:10;10318:1013;-1:-1:-1;;;;;;;;10318:1013:10:o;14675:101:25:-;14725:19;14759:12;14752:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14675:101;:::o;451:21:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10147:367:25;10303:16;;;10317:1;10303:16;;;;;;;;;10280:20;;10303:16;;;;;;;;;-1:-1:-1;;10352:16:25;;;10366:1;10352:16;;;;;;;;;10280:39;;-1:-1:-1;10325:24:25;;10352:16;-1:-1:-1;10352:16:25;;;;;;;;;;;-1:-1:-1;10352:16:25;10325:43;;10383:3;10374;10378:1;10374:6;;;;;;;;;;;;;:12;;;;;10405:7;10392;10400:1;10392:10;;;;;;;;;;;;;:20;;;;;10444:28;10459:3;10464:7;10444:14;:28::i;:::-;10478:31;10484:3;10489;10494:7;10503:5;;10478:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10478:5:25;;-1:-1:-1;;;10478:31:25:i;:::-;10147:367;;;;;;;:::o;3363:144::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3433:25:25::1;::::0;::::1;3461:5;3433:25:::0;;;:15:::1;:25;::::0;;;;;:33;;;::::1;::::0;;3477:25;::::1;::::0;3461:5;3477:25:::1;3363:144:::0;:::o;15890:137::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;15982:40:25::1;16002:19;;15982:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;15982:19:25::1;::::0;-1:-1:-1;;;15982:40:25:i:1;:::-;15890:137:::0;;:::o;1280:73:27:-;1343:5;;;;1280:73;:::o;3092:145:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3162:25:25::1;::::0;::::1;;::::0;;;:15:::1;:25;::::0;;;;;:32;;;::::1;3190:4;3162:32;::::0;;3205:27;::::1;::::0;3162:25;3205:27:::1;3092:145:::0;:::o;8529:163::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;8634:53:25::1;8656:9;8667:19;8634:21;:53::i;8707:230:10:-:0;8839:10;8829:21;;;;:9;:21;;;;;;;;;:32;;;;;;;;;;;;:44;;;;;;;;;;;;;8884:48;;;;;;;8829:32;;8839:10;8884:48;;;;;;;;;;;8707:230;;:::o;14469:138:25:-;14576:26;;;;;;;:16;:26;;;;;;;;14569:33;;;;;;;;;;;;;;;;;14542:19;;14569:33;;14576:26;;14569:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14469:138;;;:::o;6779:145::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;6864:12:25::1;:25:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;6864:25:25;;;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;6900:19;::::1;::::0;::::1;::::0;6864:25;;6900:19:::1;:::i;:::-;;;;;;;;6779:145:::0;:::o;15141:110::-;15215:31;15221:10;15233:3;15238:7;15215:5;:31::i;9563:313::-;9733:30;9748:4;9754:8;9733:14;:30::i;:::-;9833:38;9844:3;9849:4;9855:8;9865:5;9833:10;:38::i;513:32:11:-;;;;;;;;;;;:::o;16177:98:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;16251:19:25::1;16260:9;;16251:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;16251:8:25::1;::::0;-1:-1:-1;;;16251:19:25:i:1;14001:189:10:-:0;1505:19;14104:21;;;14139;;;;;14001:189::o;13143:352:25:-;13216:16;13255:4;13216:16;13255:4;13305:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13305:19:25;;13272:52;;13380:9;13375:89;13399:4;13395:1;:8;13375:89;;;13437:11;:20;13449:4;;13454:1;13449:7;;;;;;;;;;;;;13437:20;;;;;;;;;;;;13418:13;13432:1;13418:16;;;;;;;;;;;;;;;;;:39;13405:3;;13375:89;;;-1:-1:-1;13477:13:25;13143:352;-1:-1:-1;;;;13143:352:25:o;13838:372::-;13915:16;13954:4;13915:16;13954:4;14008:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14008:19:25;;13971:56;;14083:9;14078:97;14102:4;14098:1;:8;14078:97;;;14144:15;:24;14160:4;;14165:1;14160:7;;;;;;;;;;;;;14144:24;;;;;;;;;;;;14121:17;14139:1;14121:20;;;;;;;;;;;;;;;;;:47;14108:3;;14078:97;;9199:160:10;9326:17;;;;9294:15;9326:17;;;:9;:17;;;;;;;;:28;;;;;;;;;;;;;;;9199:160::o;14447:432::-;1395:2;14806:22;;14842:24;;;14725:33;14841;14447:432;;;;:::o;2360:598::-;2521:10;:19;;;;;2520:60;;;2545:35;2562:5;2569:10;2545:16;:35::i;:::-;2512:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2654:17;;;2646:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2838:43;2856:5;2863:3;2868;2873:7;2838:17;:43::i;:::-;2887:66;2910:5;2917:3;2922;2927:7;2936:9;2947:5;2887:22;:66::i;993:224:27:-;802:5;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;1070:23:::1;::::0;::::1;1062:78;;;;;;;;;;;;:::i;:::-;1146:5;:17:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;;1174:38:::1;::::0;1146:17;;1195:5:::1;::::0;1174:38:::1;::::0;-1:-1:-1;;1174:38:27::1;993:224:::0;:::o;14282:116:25:-;14368:25;;14349:4;14368:25;;;:15;:25;;;;;;;;;14282:116::o;2336:243:11:-;2439:4;2455:42;;;2471:26;2455:42;2451:74;;;-1:-1:-1;2514:4:11;2507:11;;2451:74;2537:37;2561:12;2537:23;:37::i;2843:513:7:-;2897:27;2936:7;2932:38;;-1:-1:-1;2953:10:7;;;;;;;;;;;;;;;;;;;2932:38;2988:2;;2976:9;3062:50;3069:6;;3062:50;;3085:5;;3103:2;3098:7;;;;3062:50;;;3118:17;3148:3;3138:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3138:14:7;-1:-1:-1;3118:34:7;-1:-1:-1;3170:7:7;;;3217:84;3224:7;;3217:84;;3274:2;3269;:7;3264:2;:12;3253:25;;3241:4;3246:3;;;;;;;3241:9;;;;;;;;;;;:37;;;;;;;;;;-1:-1:-1;3292:2:7;3286:8;;;;3217:84;;;-1:-1:-1;3346:4:7;2843:513;-1:-1:-1;;;;;2843:513:7:o;4124:589:9:-;4282:11;;4316:15;;4307:24;;4299:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4438:9;4433:173;4457:5;4453:1;:9;4433:173;;;4509:63;4526:5;4535:4;4540:1;4535:7;;;;;;;;;;;;;;4544:8;4553:1;4544:11;;;;;;;;;;;;;;4557:14;4509:16;:63::i;:::-;4464:3;;4433:173;;;;4687:3;4646:62;;4672:5;4646:62;;4660:10;4646:62;;;4693:4;4699:8;4646:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4124:589;;;;:::o;224:407:14:-;282:7;506:6;502:35;;-1:-1:-1;529:1:14;522:8;;502:35;555:5;;;559:1;555;:5;:1;574:5;;;;;:10;566:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;625:1;224:407;-1:-1:-1;;;224:407:14:o;753:308::-;811:7;900:1;896;:5;888:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;942:9;958:1;954;:5;;;;;;;753:308;-1:-1:-1;;;;753:308:14:o;5742:1939:10:-;5893:11;;5964:15;;5951:28;;5943:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6070:3;6061:12;;:5;:12;;;;:29;;;;;6089:1;6077:9;:13;6061:29;6057:1537;;;6169:11;6182:13;6199:22;6213:4;6218:1;6213:7;;;;;;;6199:22;6345:15;;;6307;6345;;;;;;;;;;;:20;;;;;;;;;6374:11;;6168:53;;-1:-1:-1;6168:53:10;;-1:-1:-1;6307:15:10;6325:77;;6345:20;6168:53;;6374:8;;6307:15;;6374:11;;;;;;;;;;6387:14;6325:19;:77::i;:::-;6446:13;;;6410;6446;;;;;;;;;;;:18;;;;;;;;;6473:11;;6307:95;;-1:-1:-1;6410:13:10;;6426:75;;6446:18;6466:5;;6473:8;;6410:13;;6473:11;;;;;;;;;;6486:14;6426:19;:75::i;:::-;6410:91;-1:-1:-1;6554:3:10;6583:1;6566:649;6590:9;6586:1;:13;6566:649;;;6631:22;6645:4;6650:1;6645:7;;;;;;;6631:22;6616:37;;-1:-1:-1;6616:37:10;-1:-1:-1;6690:14:10;;;6686:323;;6770:15;;;;:8;:15;;;;;;;;;;;:24;;;;;;;;;:34;;;;6816:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;6869:20;;;;;;;;;;6909:18;;;;;;;;;;6869:20;;6686:323;7062:64;7082:7;7091:5;7098:8;7107:1;7098:11;;;;;;;7062:64;7052:74;;7144:62;7164:5;7171;7178:8;7187:1;7178:11;;;;;;;7144:62;7136:70;-1:-1:-1;6601:3:10;;6566:649;;;-1:-1:-1;;7271:15:10;;;;:8;:15;;;;;;;;;;;:20;;;;;;;;:30;;;;7309:13;;;;;;;;;;;:18;;;;;;;;:26;;;;-1:-1:-1;6057:1537:10;;;7427:9;7422:166;7446:9;7442:1;:13;7422:166;;;7509:8;7518:1;7509:11;;;;;;;;;;;;;;7480:25;7490:5;7497:4;7502:1;7497:7;;;;;;;;;;;;;;7480:9;:25::i;:::-;:40;;7472:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7457:3;;7422:166;;;;6057:1537;7656:3;7623:53;;7649:5;7623:53;;7637:10;7623:53;;;7661:4;7667:8;7623:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5742:1939;;;;;:::o;7794:516::-;8015:16;:3;:14;;;:16::i;:::-;8011:295;;;8041:13;8079:3;8057:49;;;8112:9;8123:10;8135:5;8142:4;8148:8;8158:5;8057:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8057:107:10;;-1:-1:-1;8180:38:10;;;8190:28;8180:38;8172:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8011:295;7794:516;;;;;;:::o;11084:1593:25:-;11197:10;11181:27;;;;:15;:27;;;;;;;;11173:90;;;;;;;;;;;;:::i;:::-;11335:10;11299:16;11318:28;;;:16;:28;;;;;:35;11396:23;;:::i;:::-;11439:10;11422:28;;;;:16;:28;;;;;:31;;:28;;;:31;;;;;;;;;;;;11396:57;;;;;;;;11422:31;;;;11396:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11422:31:25;11596:1077;11620:4;:11;11616:1;:15;11596:1077;;;11646:10;11659:4;11664:1;11659:7;;;;;;;;;;;;;;11646:20;;11674:14;11691:8;11700:1;11691:11;;;;;;;;;;;;;;11674:28;;11710:20;11733:11;:15;11745:2;11733:15;;;;;;;;;;;;11710:38;;11965:384;11990:5;:15;;;11972:33;;:15;:33;:68;;;;12027:5;:13;;;12009:31;;:15;:31;11972:68;:88;;;-1:-1:-1;12049:11:25;;12044:16;;;;11972:88;:108;;;;12078:2;12064:5;:11;;;:16;;;11972:108;11965:384;;;12107:1;12092:16;;;;12221:8;12207:11;:22;12199:82;;;;;;;;;;;;:::i;:::-;12316:10;12299:28;;;;:16;:28;;;;;:41;;12328:11;;12299:41;;;;;;;;;;;;;;;12291:49;;;;;;;;12299:41;;;;12291:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11965:384:25;;;12404:16;;12400:267;;12432:28;12463:19;;;:15;:19;;;;;;:31;;12487:6;12463:23;:31::i;:::-;12432:62;;12536:12;12512:20;:36;;12504:102;;;;;;;;;;;;:::i;:::-;12616:19;;;;:15;:19;;;;;:42;12400:267;-1:-1:-1;;;11633:3:25;;11596:1077;;727:428:9;844:53;861:3;868;873:7;882:14;844:16;:53::i;:::-;954:59;;;;;;;;;;;;;;;;;;989:3;;969:10;;954:59;;;;;;;;;;;1077:73;1108:3;1114;1119;1124:7;1133:9;1144:5;1077:22;:73::i;1861:113:7:-;1940:29;;;;:7;;:29;;;;;:::i;884:393:11:-;986:25;;;978:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1102:4;1079:19;:27;;1071:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1174:17;:38;;;;;;;;;;;;;;;;1218:32;:54;884:393::o;3306:255:9:-;3412:53;3429:5;3436:3;3441:7;3450:14;3412:16;:53::i;:::-;3495:61;;;;;;;;;;;;;;3537:3;;3495:61;;;;3510:10;;3495:61;;;;;;;;;;;3306:255;;;:::o;1449:1512::-;1596:8;:15;1581:4;:11;:30;1573:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1689:11;;:15;1685:1036;;1783:11;1796:13;1813:22;1827:4;1832:1;1827:7;;;;;;;1813:22;1957:13;;;1921;1957;;;;;;;;;;;:18;;;;;;;;;1984:11;;1782:53;;-1:-1:-1;1782:53:9;;-1:-1:-1;1921:13:9;1937:75;;1957:18;1782:53;;1984:8;;1921:13;;1984:11;;;1937:75;2080:11;;1921:91;;-1:-1:-1;2144:3:9;2173:1;2156:476;2180:9;2176:1;:13;2156:476;;;2221:22;2235:4;2240:1;2235:7;;;;;;;2221:22;2206:37;;-1:-1:-1;2206:37:9;-1:-1:-1;2280:14:9;;;2276:234;;2360:13;;;:8;:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;2410:18;;;;;;;;;2276:234;2561:62;2581:5;2588;2595:8;2604:1;2595:11;;;;;;;2561:62;2553:70;-1:-1:-1;2191:3:9;;2156:476;;;-1:-1:-1;;;2688:13:9;;;:8;:13;;;;;;;;;;;:18;;;;;;;;;;:26;;;;-1:-1:-1;1685:1036:9;2792:3;2752:60;;2786:3;2752:60;;2766:10;2752:60;;;2797:4;2803:8;2752:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2876:80;2912:3;2918;2923:4;2929:8;2939:9;2950:5;2876:27;:80::i;1421:311:7:-;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:21;;:31;;1506:7;;1482:31;;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1519:22;1553:9;1548:180;1572:9;:16;1568:1;:20;1548:180;;;1638:7;1647:23;1657:9;1667:1;1657:12;;;;;;;;;;;;;;1647:9;:23::i;:::-;1621:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1621:59:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1603:78;;1708:9;1718:1;1708:12;;;;;;;;;;;;;;1694:27;1698:8;1694:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1590:3;;1548:180;;4381:385:10;4509:53;4526:5;4533:3;4538:7;4547:14;4509:16;:53::i;:::-;4599;4616:3;4623;4628:7;4637:14;4599:16;:53::i;:::-;4743:3;4709:52;;4736:5;4709:52;;4724:10;4709:52;;;4748:3;4753:7;4709:52;;;;;;;;;;;;;;;;;;;;;;;;4381:385;;;;:::o;4874:468::-;5066:16;:3;:14;;;:16::i;:::-;5062:276;;;5092:13;5130:3;5108:44;;;5157:9;5168:10;5180:5;5187:3;5192:7;5201:5;5108:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5108:99:10;;-1:-1:-1;5223:32:10;;;5233:22;5223:32;5215:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2379:234:7;2465:4;2481:50;;;2497:34;2481:50;2477:82;;;-1:-1:-1;2548:4:7;2541:11;;2477:82;2571:37;2595:12;2571:23;:37::i;11845:352:10:-;11963:11;11980:13;12047:18;12061:3;12047:13;:18::i;:::-;12140;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;12032:33;;-1:-1:-1;12032:33:10;-1:-1:-1;12120:72:10;;12032:33;12172:7;12181:10;12120:19;:72::i;:::-;12094:18;;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;;:98;;;;-1:-1:-1;;;;11845:352:10:o;12664:1162::-;12796:20;1395:2;12842:22;;12885:33;12796:20;12929:10;:28;;;;;;;;;12925:871;;;12996:16;;;12982:31;;;-1:-1:-1;13029:26:10;;;;13021:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13178:16;13137:19;;;13136:28;;13135:40;;:59;13118:181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12925:871;;;13331:14;13317:10;:28;;;;;;;;;13313:483;;;13384:16;;;13370:31;;;-1:-1:-1;13417:26:10;;;;13409:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13558:7;13549:4;13540:5;13526:10;:19;;13525:28;13524:41;;13507:164;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13693:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13802:19;;12664:1162;;;;;;:::o;541:398:12:-;602:4;854:21;;890:15;;;;;:43;;-1:-1:-1;206:66:12;909:24;;;882:52;-1:-1:-1;;541:398:12:o;1419:158:14:-;1477:7;1504:5;;;1523:6;;;;1515:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15216:243:10;15319:4;15335:42;;;15351:26;15335:42;15331:74;;;-1:-1:-1;15394:4:10;15387:11;;15331:74;427:31:13;411:47;;;;15417:37:10;306:157:13:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:198:29;84:20;;144:42;133:54;;123:65;;113:2;;202:1;199;192:12;217:400;;;350:3;343:4;335:6;331:17;327:27;317:2;;373:6;365;358:22;317:2;-1:-1:-1;401:20:29;;444:18;433:30;;430:2;;;483:8;473;466:26;430:2;527:4;519:6;515:17;503:29;;590:3;583:4;575;567:6;563:17;555:6;551:30;547:41;544:50;541:2;;;607:1;604;597:12;622:692;;735:3;728:4;720:6;716:17;712:27;702:2;;757:5;750;743:20;702:2;801:6;788:20;826:69;841:53;887:6;841:53;:::i;:::-;826:69;:::i;:::-;929:21;;;817:78;-1:-1:-1;969:4:29;989:14;;;;1023:15;;;1069;;;1057:28;;1053:37;;1050:46;-1:-1:-1;1047:2:29;;;1109:1;1106;1099:12;1047:2;1131:1;1141:167;1155:6;1152:1;1149:13;1141:167;;;1216:17;;1204:30;;1254:12;;;;1286;;;;1177:1;1170:9;1141:167;;;1145:3;;;;;692:622;;;;:::o;1319:377::-;;;1436:3;1429:4;1421:6;1417:17;1413:27;1403:2;;1461:8;1451;1444:26;1403:2;-1:-1:-1;1491:20:29;;1534:18;1523:30;;1520:2;;;1573:8;1563;1556:26;1520:2;1617:4;1609:6;1605:17;1593:29;;1669:3;1662:4;1653:6;1645;1641:19;1637:30;1634:39;1631:2;;;1686:1;1683;1676:12;1701:580;;1798:3;1791:4;1783:6;1779:17;1775:27;1765:2;;1820:5;1813;1806:20;1765:2;1864:6;1851:20;1894:18;1886:6;1883:30;1880:2;;;1916:9;1880:2;1945:117;2056:4;1987:66;1980:4;1972:6;1968:17;1964:90;1960:101;1945:117;:::i;:::-;1936:126;;2085:6;2078:5;2071:21;2139:3;2132:4;2123:6;2115;2111:19;2107:30;2104:39;2101:2;;;2156:1;2153;2146:12;2101:2;2219:6;2212:4;2204:6;2200:17;2193:4;2186:5;2182:16;2169:57;2273:1;2246:18;;;2266:4;2242:29;2235:40;2250:5;1755:526;-1:-1:-1;;1755:526:29:o;2286:173::-;2355:20;;2415:18;2404:30;;2394:41;;2384:2;;2449:1;2446;2439:12;2464:198;;2576:2;2564:9;2555:7;2551:23;2547:32;2544:2;;;2597:6;2589;2582:22;2544:2;2625:31;2646:9;2625:31;:::i;2667:274::-;;;2796:2;2784:9;2775:7;2771:23;2767:32;2764:2;;;2817:6;2809;2802:22;2764:2;2845:31;2866:9;2845:31;:::i;:::-;2835:41;;2895:40;2931:2;2920:9;2916:18;2895:40;:::i;:::-;2885:50;;2754:187;;;;;:::o;2946:1001::-;;;;;;3185:3;3173:9;3164:7;3160:23;3156:33;3153:2;;;3207:6;3199;3192:22;3153:2;3235:31;3256:9;3235:31;:::i;:::-;3225:41;;3285:40;3321:2;3310:9;3306:18;3285:40;:::i;:::-;3275:50;;3376:2;3365:9;3361:18;3348:32;3399:18;3440:2;3432:6;3429:14;3426:2;;;3461:6;3453;3446:22;3426:2;3489:67;3548:7;3539:6;3528:9;3524:22;3489:67;:::i;:::-;3479:77;;3609:2;3598:9;3594:18;3581:32;3565:48;;3638:2;3628:8;3625:16;3622:2;;;3659:6;3651;3644:22;3622:2;3687:69;3748:7;3737:8;3726:9;3722:24;3687:69;:::i;:::-;3677:79;;3809:3;3798:9;3794:19;3781:33;3765:49;;3839:2;3829:8;3826:16;3823:2;;;3860:6;3852;3845:22;3823:2;;3888:53;3933:7;3922:8;3911:9;3907:24;3888:53;:::i;:::-;3878:63;;;3143:804;;;;;;;;:::o;3952:632::-;;;;;;4141:3;4129:9;4120:7;4116:23;4112:33;4109:2;;;4163:6;4155;4148:22;4109:2;4191:31;4212:9;4191:31;:::i;:::-;4181:41;;4241:40;4277:2;4266:9;4262:18;4241:40;:::i;:::-;4231:50;;4328:2;4317:9;4313:18;4300:32;4290:42;;4379:2;4368:9;4364:18;4351:32;4341:42;;4434:3;4423:9;4419:19;4406:33;4462:18;4454:6;4451:30;4448:2;;;4499:6;4491;4484:22;4448:2;4527:51;4570:7;4561:6;4550:9;4546:22;4527:51;:::i;4589:924::-;;;;;4811:3;4799:9;4790:7;4786:23;4782:33;4779:2;;;4833:6;4825;4818:22;4779:2;4861:31;4882:9;4861:31;:::i;:::-;4851:41;;4943:2;4932:9;4928:18;4915:32;4966:18;5007:2;4999:6;4996:14;4993:2;;;5028:6;5020;5013:22;4993:2;5056:67;5115:7;5106:6;5095:9;5091:22;5056:67;:::i;:::-;5046:77;;5176:2;5165:9;5161:18;5148:32;5132:48;;5205:2;5195:8;5192:16;5189:2;;;5226:6;5218;5211:22;5189:2;5254:69;5315:7;5304:8;5293:9;5289:24;5254:69;:::i;:::-;5244:79;;5376:2;5365:9;5361:18;5348:32;5332:48;;5405:2;5395:8;5392:16;5389:2;;;5426:6;5418;5411:22;5389:2;;5454:53;5499:7;5488:8;5477:9;5473:24;5454:53;:::i;:::-;5444:63;;;4769:744;;;;;;;:::o;5518:369::-;;;5644:2;5632:9;5623:7;5619:23;5615:32;5612:2;;;5665:6;5657;5650:22;5612:2;5693:31;5714:9;5693:31;:::i;:::-;5683:41;;5774:2;5763:9;5759:18;5746:32;5821:5;5814:13;5807:21;5800:5;5797:32;5787:2;;5848:6;5840;5833:22;5787:2;5876:5;5866:15;;;5602:285;;;;;:::o;5892:266::-;;;6021:2;6009:9;6000:7;5996:23;5992:32;5989:2;;;6042:6;6034;6027:22;5989:2;6070:31;6091:9;6070:31;:::i;:::-;6060:41;6148:2;6133:18;;;;6120:32;;-1:-1:-1;;;5979:179:29:o;6163:644::-;;;;;;6345:3;6333:9;6324:7;6320:23;6316:33;6313:2;;;6367:6;6359;6352:22;6313:2;6395:31;6416:9;6395:31;:::i;:::-;6385:41;;6473:2;6462:9;6458:18;6445:32;6435:42;;6524:2;6513:9;6509:18;6496:32;6486:42;;6579:2;6568:9;6564:18;6551:32;6606:18;6598:6;6595:30;6592:2;;;6643:6;6635;6628:22;6592:2;6687:60;6739:7;6730:6;6719:9;6715:22;6687:60;:::i;:::-;6303:504;;;;-1:-1:-1;6303:504:29;;-1:-1:-1;6766:8:29;;6661:86;6303:504;-1:-1:-1;;;6303:504:29:o;6812:496::-;;;;;;6988:3;6976:9;6967:7;6963:23;6959:33;6956:2;;;7010:6;7002;6995:22;6956:2;7038:31;7059:9;7038:31;:::i;:::-;7028:41;;7088:39;7123:2;7112:9;7108:18;7088:39;:::i;:::-;7078:49;;7146:39;7181:2;7170:9;7166:18;7146:39;:::i;:::-;7136:49;;7204:39;7239:2;7228:9;7224:18;7204:39;:::i;:::-;7194:49;;7262:40;7297:3;7286:9;7282:19;7262:40;:::i;:::-;7252:50;;6946:362;;;;;;;;:::o;7313:1246::-;;;7492:2;7480:9;7471:7;7467:23;7463:32;7460:2;;;7513:6;7505;7498:22;7460:2;7558:9;7545:23;7587:18;7628:2;7620:6;7617:14;7614:2;;;7649:6;7641;7634:22;7614:2;7692:6;7681:9;7677:22;7667:32;;7737:7;7730:4;7726:2;7722:13;7718:27;7708:2;;7764:6;7756;7749:22;7708:2;7809;7796:16;7832:69;7847:53;7893:6;7847:53;:::i;7832:69::-;7923:3;7947:6;7942:3;7935:19;7973:4;8002:2;7997:3;7993:12;7986:19;;8033:2;8029;8025:11;8086:7;8081:2;8075;8067:6;8063:15;8059:2;8055:24;8051:33;8048:46;8045:2;;;8112:6;8104;8097:22;8045:2;8139:6;8130:15;;8154:175;8168:6;8165:1;8162:13;8154:175;;;8229:25;8250:3;8229:25;:::i;:::-;8217:38;;8190:1;8183:9;;;;;8275:12;;;;8307;;8154:175;;;-1:-1:-1;8348:5:29;;-1:-1:-1;8391:18:29;;8378:32;;-1:-1:-1;;;8422:16:29;;;8419:2;;;8456:6;8448;8441:22;8419:2;;8484:69;8545:7;8534:8;8523:9;8519:24;8484:69;:::i;:::-;8474:79;;;7450:1109;;;;;:::o;8564:463::-;;;8711:2;8699:9;8690:7;8686:23;8682:32;8679:2;;;8732:6;8724;8717:22;8679:2;8777:9;8764:23;8810:18;8802:6;8799:30;8796:2;;;8847:6;8839;8832:22;8796:2;8891:76;8959:7;8950:6;8939:9;8935:22;8891:76;:::i;:::-;8986:8;;8865:102;;-1:-1:-1;8669:358:29;-1:-1:-1;;;;8669:358:29:o;9032:815::-;;;;;9231:2;9219:9;9210:7;9206:23;9202:32;9199:2;;;9252:6;9244;9237:22;9199:2;9297:9;9284:23;9326:18;9367:2;9359:6;9356:14;9353:2;;;9388:6;9380;9373:22;9353:2;9432:76;9500:7;9491:6;9480:9;9476:22;9432:76;:::i;:::-;9527:8;;-1:-1:-1;9406:102:29;-1:-1:-1;9615:2:29;9600:18;;9587:32;;-1:-1:-1;9631:16:29;;;9628:2;;;9665:6;9657;9650:22;9628:2;;9709:78;9779:7;9768:8;9757:9;9753:24;9709:78;:::i;:::-;9189:658;;;;-1:-1:-1;9806:8:29;-1:-1:-1;;;;9189:658:29:o;9852:352::-;;9963:2;9951:9;9942:7;9938:23;9934:32;9931:2;;;9984:6;9976;9969:22;9931:2;10028:9;10015:23;10078:66;10071:5;10067:78;10060:5;10057:89;10047:2;;10165:6;10157;10150:22;10209:432;;;10341:2;10329:9;10320:7;10316:23;10312:32;10309:2;;;10362:6;10354;10347:22;10309:2;10407:9;10394:23;10440:18;10432:6;10429:30;10426:2;;;10477:6;10469;10462:22;10426:2;10521:60;10573:7;10564:6;10553:9;10549:22;10521:60;:::i;10646:670::-;;10786:3;10774:9;10765:7;10761:23;10757:33;10754:2;;;10808:6;10800;10793:22;10754:2;10846;10840:9;10888:3;10880:6;10876:16;10958:6;10946:10;10943:22;10922:18;10910:10;10907:34;10904:62;10901:2;;;10969:9;10901:2;10996;10989:22;11035:30;11055:9;11035:30;:::i;:::-;11027:6;11020:46;11099:39;11134:2;11123:9;11119:18;11099:39;:::i;:::-;11094:2;11086:6;11082:15;11075:64;11172:39;11207:2;11196:9;11192:18;11172:39;:::i;:::-;11167:2;11159:6;11155:15;11148:64;11245:39;11280:2;11269:9;11265:18;11245:39;:::i;:::-;11240:2;11228:15;;11221:64;11232:6;10744:572;-1:-1:-1;;;10744:572:29:o;11321:190::-;;11433:2;11421:9;11412:7;11408:23;11404:32;11401:2;;;11454:6;11446;11439:22;11401:2;-1:-1:-1;11482:23:29;;11391:120;-1:-1:-1;11391:120:29:o;11516:258::-;;;11645:2;11633:9;11624:7;11620:23;11616:32;11613:2;;;11666:6;11658;11651:22;11613:2;-1:-1:-1;;11694:23:29;;;11764:2;11749:18;;;11736:32;;-1:-1:-1;11603:171:29:o;11779:416::-;;11885:6;11880:3;11873:19;11915:66;11907:6;11904:78;11901:2;;;11997:3;11992;11985:16;11901:2;12040:4;12032:6;12028:17;12090:8;12083:5;12076:4;12071:3;12067:14;12054:45;12122:18;;;;12142:4;12118:29;12156:15;;;-1:-1:-1;12118:29:29;;11863:332;-1:-1:-1;11863:332:29:o;12200:339::-;12320:12;;12277:18;12316:21;;;12304:34;;12391:4;12380:16;;;12374:23;12370:32;;12354:14;;;12347:56;12456:4;12445:16;;;12439:23;12435:32;;12419:14;;;12412:56;12521:4;12510:16;;;12504:23;12500:32;12484:14;;12477:56;12257:282::o;12544:226::-;12720:42;12708:55;;;;12690:74;;12678:2;12663:18;;12645:125::o;12775:297::-;12979:42;12967:55;;;;12949:74;;13054:2;13039:18;;13032:34;12937:2;12922:18;;12904:168::o;13077:718::-;13304:2;13356:21;;;13426:13;;13329:18;;;13448:22;;;13077:718;;13304:2;13527:15;;;;13501:2;13486:18;;;13077:718;13573:196;13587:6;13584:1;13581:13;13573:196;;;13636:51;13683:3;13674:6;13668:13;13636:51;:::i;:::-;13744:15;;;;13716:4;13707:14;;;;;13609:1;13602:9;13573:196;;;-1:-1:-1;13786:3:29;;13284:511;-1:-1:-1;;;;;;13284:511:29:o;13800:531::-;;14077:2;14066:9;14059:21;14103:79;14178:2;14167:9;14163:18;14155:6;14147;14103:79;:::i;:::-;14230:9;14222:6;14218:22;14213:2;14202:9;14198:18;14191:50;14258:67;14318:6;14310;14302;14258:67;:::i;:::-;14250:75;14049:282;-1:-1:-1;;;;;;;14049:282:29:o;14336:635::-;14507:2;14559:21;;;14629:13;;14532:18;;;14651:22;;;14336:635;;14507:2;14730:15;;;;14704:2;14689:18;;;14336:635;14776:169;14790:6;14787:1;14784:13;14776:169;;;14851:13;;14839:26;;14920:15;;;;14885:12;;;;14812:1;14805:9;14776:169;;14976:187;15141:14;;15134:22;15116:41;;15104:2;15089:18;;15071:92::o;15168:662::-;;15309:2;15338;15327:9;15320:21;15370:6;15364:13;15413:6;15408:2;15397:9;15393:18;15386:34;15438:4;15451:140;15465:6;15462:1;15459:13;15451:140;;;15560:14;;;15556:23;;15550:30;15526:17;;;15545:2;15522:26;15515:66;15480:10;;15451:140;;;15609:6;15606:1;15603:13;15600:2;;;15679:4;15674:2;15665:6;15654:9;15650:22;15646:31;15639:45;15600:2;-1:-1:-1;15746:2:29;15734:15;15751:66;15730:88;15715:104;;;;15821:2;15711:113;;15289:541;-1:-1:-1;;;15289:541:29:o;15835:414::-;16037:2;16019:21;;;16076:2;16056:18;;;16049:30;16115:34;16110:2;16095:18;;16088:62;16186:20;16181:2;16166:18;;16159:48;16239:3;16224:19;;16009:240::o;16254:418::-;16456:2;16438:21;;;16495:2;16475:18;;;16468:30;16534:34;16529:2;16514:18;;16507:62;16605:24;16600:2;16585:18;;16578:52;16662:3;16647:19;;16428:244::o;16677:342::-;16879:2;16861:21;;;16918:2;16898:18;;;16891:30;16957:20;16952:2;16937:18;;16930:48;17010:2;16995:18;;16851:168::o;17024:412::-;17226:2;17208:21;;;17265:2;17245:18;;;17238:30;17304:34;17299:2;17284:18;;17277:62;17375:18;17370:2;17355:18;;17348:46;17426:3;17411:19;;17198:238::o;17441:411::-;17643:2;17625:21;;;17682:2;17662:18;;;17655:30;17721:34;17716:2;17701:18;;17694:62;17792:17;17787:2;17772:18;;17765:45;17842:3;17827:19;;17615:237::o;17857:406::-;18059:2;18041:21;;;18098:2;18078:18;;;18071:30;18137:34;18132:2;18117:18;;18110:62;18208:12;18203:2;18188:18;;18181:40;18253:3;18238:19;;18031:232::o;18268:424::-;18470:2;18452:21;;;18509:2;18489:18;;;18482:30;18548:34;18543:2;18528:18;;18521:62;18619:30;18614:2;18599:18;;18592:58;18682:3;18667:19;;18442:250::o;18697:409::-;18899:2;18881:21;;;18938:2;18918:18;;;18911:30;18977:34;18972:2;18957:18;;18950:62;19048:15;19043:2;19028:18;;19021:43;19096:3;19081:19;;18871:235::o;19111:421::-;19313:2;19295:21;;;19352:2;19332:18;;;19325:30;19391:34;19386:2;19371:18;;19364:62;19462:27;19457:2;19442:18;;19435:55;19522:3;19507:19;;19285:247::o;19537:477::-;19739:2;19721:21;;;19778:2;19758:18;;;19751:30;19817:34;19812:2;19797:18;;19790:62;19888:34;19883:2;19868:18;;19861:62;19960:11;19954:3;19939:19;;19932:40;20004:3;19989:19;;19711:303::o;20019:402::-;20221:2;20203:21;;;20260:2;20240:18;;;20233:30;20299:34;20294:2;20279:18;;20272:62;20370:8;20365:2;20350:18;;20343:36;20411:3;20396:19;;20193:228::o;20426:417::-;20628:2;20610:21;;;20667:2;20647:18;;;20640:30;20706:34;20701:2;20686:18;;20679:62;20777:23;20772:2;20757:18;;20750:51;20833:3;20818:19;;20600:243::o;20848:259::-;21038:3;21023:19;;21051:50;21027:9;21083:6;21051:50;:::i;21112:177::-;21258:25;;;21246:2;21231:18;;21213:76::o;21294:248::-;21468:25;;;21524:2;21509:18;;21502:34;21456:2;21441:18;;21423:119::o;21547:242::-;21617:2;21611:9;21647:17;;;21694:18;21679:34;;21715:22;;;21676:62;21673:2;;;21741:9;21673:2;21768;21761:22;21591:198;;-1:-1:-1;21591:198:29:o;21794:183::-;;21893:18;21885:6;21882:30;21879:2;;;21915:9;21879:2;-1:-1:-1;21966:4:29;21947:17;;;21943:28;;21869:108::o

Swarm Source

ipfs://fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e8
Loading