ETH Price: $3,237.13 (+2.66%)
Gas: 3 Gwei

Token

Immutables.art (][art)
 

Overview

Max Total Supply

0 ][art

Holders

706

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 ][art
0x9e4c7b957a8072357f847fa01333e2862eac3e35
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
ImmutablesArt

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 12 of 18: ImmutablesArt.sol
// SPDX-License-Identifier: UNLICENSED
// All Rights Reserved

// Contract is not audited.
// Use authorized deployments of this contract at your own risk.

/*
██╗███╗   ███╗███╗   ███╗██╗   ██╗████████╗ █████╗ ██████╗ ██╗     ███████╗███████╗    █████╗ ██████╗ ████████╗
██║████╗ ████║████╗ ████║██║   ██║╚══██╔══╝██╔══██╗██╔══██╗██║     ██╔════╝██╔════╝   ██╔══██╗██╔══██╗╚══██╔══╝
██║██╔████╔██║██╔████╔██║██║   ██║   ██║   ███████║██████╔╝██║     █████╗  ███████╗   ███████║██████╔╝   ██║
██║██║╚██╔╝██║██║╚██╔╝██║██║   ██║   ██║   ██╔══██║██╔══██╗██║     ██╔══╝  ╚════██║   ██╔══██║██╔══██╗   ██║
██║██║ ╚═╝ ██║██║ ╚═╝ ██║╚██████╔╝   ██║   ██║  ██║██████╔╝███████╗███████╗███████║██╗██║  ██║██║  ██║   ██║
╚═╝╚═╝     ╚═╝╚═╝     ╚═╝ ╚═════╝    ╚═╝   ╚═╝  ╚═╝╚═════╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝
*/

pragma solidity ^0.8.0;

import "./Strings.sol";
import "./Ownable.sol";
import "./ERC721.sol";
import "./IERC2981.sol";
import "./SafeERC20.sol";
import "./Clones.sol";
import "./Address.sol";
import "./ReentrancyGuard.sol";

import "./ImmutablesArtRoyaltyManager.sol";

/// @author Gutenblock.eth
/// @title ImmutablesAdmin
contract ImmutablesAdmin is Ownable, ReentrancyGuard {
  using Address for address payable;

  /// @dev Address of a third party curator.
  address public curator;
  /// @dev basis point (1/10,000th) share of third party curator on payout.
  uint16 public curatorPercent;

  /// @dev Address of a third party beneficiary.
  address public beneficiary;
  /// @dev basis point (1/10,000th) share of third party beneficiary on payout.
  uint16 public beneficiaryPercent;

  /// @dev Teammember administration mapping
  mapping(address => bool) public isTeammember;

  /// @dev MODIFIERS

  modifier onlyTeammember() {
      require(isTeammember[msg.sender], "team");
      _;
  }

  /// @dev EVENTS

  event AdminModifiedTeammembers(
    address indexed user,
    bool isTeammember
  );

  /** @dev Allows the contract owner to add a teammember.
    * @param _address of teammember to add.
    */
  function contractOwnerAddTeammember(address _address) external onlyOwner() {
      isTeammember[_address] = true;
      emit AdminModifiedTeammembers(_address, true);
  }

  /** @dev Allows the contract owner to remove a teammember.
    * @param _address of teammember to remove.
    */
  function contractOwnerRemoveTeammember(address _address) external onlyOwner() {
      isTeammember[_address] = false;
      emit AdminModifiedTeammembers(_address, false);
  }

  /// @dev FINANCIAL

  /** @dev Allows the contract owner to set a curator address and percentage.
    * @dev Force payout of any curator that was previously set
    * @dev so that funds paid with a curator set are paid out as promised.
    * @param _newCurator address of a curator teammember.
    * @param _newPercent the basis point (1/10,000th) share of contract revenue for the curator.
    */
  function contractOwnerUpdateCuratorAddressAndPercent(address _newCurator, uint16 _newPercent) external onlyOwner() {
    require(_newPercent <= (10000-beneficiaryPercent));
    withdraw();
    isTeammember[curator] = false;
    emit AdminModifiedTeammembers(curator, false);
    isTeammember[_newCurator] = true;
    emit AdminModifiedTeammembers(_newCurator, true);
    curator = _newCurator;
    curatorPercent = _newPercent;
  }

  /** @dev Allows the contract owner to set a beneficiary address and percentage.
    * @dev Force payout of any beneficiary that was previously set
    * @dev so that funds paid with a beneficiary set are paid out as promised.
    * @param _newBeneficiary address of a beneficiary.
    * @param _newPercent the basis point (1/10,000th) share of contract revenue for the beneficiary.
    */
  function contractOwnerUpdateBeneficiaryAddressAndPercent(address _newBeneficiary, uint16 _newPercent) external onlyOwner() {
    require(_newPercent <= (10000-curatorPercent));
    withdraw();
    beneficiary = _newBeneficiary;
    beneficiaryPercent = _newPercent;
  }

  /** @dev Allows the withdraw of funds.
    * @dev Everyone is paid and the contract balance is zeroed out.
    */
  function withdraw() public nonReentrant() {
    // checks
    // effects
    uint256 _startingBalance = address(this).balance;
    uint256 _curatorValue = _startingBalance * curatorPercent / 10000;
    uint256 _beneficiaryValue = _startingBalance * beneficiaryPercent / 10000;
    uint256 _contractValue = _startingBalance - _curatorValue - _beneficiaryValue;

    // interactions
    payable(this.owner()).sendValue(_contractValue);
    payable(curator).sendValue(_curatorValue);
    payable(beneficiary).sendValue(_beneficiaryValue);
  }

  /** @dev Allows the withdraw of funds.
    * @dev Everyone is paid and the contract balance is zeroed out.
    */
  function withdrawERC20(IERC20 token) external nonReentrant() {
    // checks
    uint256 _startingBalance = token.balanceOf(address(this));
    require(_startingBalance > 0, "no tokens");

    // effects
    uint256 _curatorValue = _startingBalance * curatorPercent / 10000;
    uint256 _beneficiaryValue = _startingBalance * beneficiaryPercent / 10000;
    uint256 _contractValue = _startingBalance - _curatorValue - _beneficiaryValue;

    // interactions
    SafeERC20.safeTransfer(token, this.owner(), _contractValue);
    if(curator != address(0) && _curatorValue > 0) {
      SafeERC20.safeTransfer(token, curator, _curatorValue);
    }
    if(beneficiary != address(0) && _beneficiaryValue > 0) {
      SafeERC20.safeTransfer(token, beneficiary, _beneficiaryValue);
    }
  }
}

/// @author Gutenblock.eth
/// @title ImmutablesAdminProject
contract ImmutablesAdminProject is ImmutablesAdmin {
  /// @dev The fee paid to the contract to create a project.
  uint256 public projectFee;
  /// @dev The last projectId created.
  uint256 public currentProjectId;
  /// @dev Featured project.
  uint256 public featuredProjectId;

  /// @dev basis point (1/10,000th) share the artist receives of each sale.
  uint16 public artistPercent;
  /// @dev whether or not artists need to be pre-screened.
  bool public artistScreeningEnabled = false;

  /// @dev Template Cloneable Royalty Manager Contract
  ImmutablesArtRoyaltyManager public implementation;

  struct Project {
    // Name of the project and the corresponding Immutables.co page name.
    string name;
    // Name of the artist.
    string artist;
    // Project description.
    string description;

    // Current highest minted edition number.
    uint256 currentEditionId;
    // Maximum number of editions that can be minted.
    uint256 maxEditions;

    // The maximum number of editions to display at once in the grid view.
    // For works that are easier to generate many may be shown at once.
    // For more processor intensive works the artist may want to limit the
    // number on screen at any given time to reduce lag.
    uint8 maxGridDimension;

    // The Immutables.co Post transaction hash containing the generative art
    // script to run.
    string scriptTransactionHash;
    // The type of script that is referenced in the transaction hash.
    // Used to tell Grid what type of Cell to use for the script.
    string scriptType;

    // A category that can be assigned by a Teammember for curation.
    string category;

    // Whether the project is Active and available for third parties to view.
    bool active;
    // Whether the project minting is paused to the public.
    bool paused;
    // Whether or not the main project attributes are locked from editing.
    bool locked;
  }

  /// @dev Mappings between the page string and tokenId.
  mapping(uint256 => Project) public projects;

  /// @dev Mappings between the projectId, Price, and Artist Payees
  mapping(uint256 => address) public projectIdToArtistAddress;
  mapping(uint256 => uint256) public projectIdToPricePerEditionInWei;
  mapping(uint256 => address) public projectIdToAdditionalPayee;
  mapping(uint256 => uint16) public projectIdToAdditionalPayeePercent;

  /// @dev Allow for a per-project royalty address
  mapping(uint256 => address) public projectIdToRoyaltyAddress;

  /// @dev EIP2981 royaltyInfo basis point (1/10,000th) share of secondary
  ///      sales (for all projects).
  uint16 public secondaryRoyaltyPercent;

  /// @dev A mapping from a project to a base URL like a IPFS CAR file CID
  ///     (e.g., that can be obtained from from nft.storage)
  mapping(uint256 => string) public projectIdToImageURLBase;
  /// @dev The file extension for the individual items in the CAR file
  ///      (e.g., ".png")
  mapping(uint256 => string) public projectIdToImageURLExt;
  /// @dev Whether to use the Image URL in the Grid View instead of live render.
  mapping(uint256 => bool) public projectIdUseImageURLInGridView;

  /// @dev Mapping of artists authorized to use the platform
  ///      if artist screening is enabled.
  mapping(address => bool) public isAuthorizedArtist;

  /// @dev MODIFIERS

  modifier onlyUnlocked(uint256 _projectId) {
      require(!projects[_projectId].locked, "locked");
      _;
  }

  modifier onlyArtist(uint256 _projectId) {
    require(msg.sender == projectIdToArtistAddress[_projectId], "artist");
    _;
  }

  modifier onlyArtistOrTeammember(uint256 _projectId) {
      require(isTeammember[msg.sender] || msg.sender == projectIdToArtistAddress[_projectId], "artistTeam");
      _;
  }

  modifier onlyAuthorizedArtist() {
    if(artistScreeningEnabled) {
      require(isAuthorizedArtist[msg.sender], "auth");
    }
    _;
  }

  /// @dev EVENTS

  event AddressCreatedProject(
    address indexed artist,
    uint256 indexed projectId,
    string projectName
  );

  event AdminUpdatedAuthorizedArtist(
    address indexed user,
    bool isAuthorizedArtist
  );

  event AdminUpdatedProjectCategory(
      uint256 indexed projectId,
      string category
  );

  event CreatedImmutablesArtRoyaltyManagerForProjectId(
      address indexed royaltyManager,
      uint256 indexed projectId
  );

  /// @dev CONSTRUCTOR

  constructor() {
    implementation = new ImmutablesArtRoyaltyManager();
    implementation.initialize(address(this), 1, address(this), artistPercent, address(0), 0);
  }

  /** @dev Allows the teammember to add an artist.
    * @param _address of artist to add
    */
  function teamAddAuthorizedArtist(address _address) external onlyTeammember() {
      isAuthorizedArtist[_address] = true;
      emit AdminUpdatedAuthorizedArtist(_address, true);
  }

  /** @dev Allows the teammember to remove an artist.
    * @param _address of artist to remove
    */
  function teamRemoveAuthorizedArtist(address _address) external onlyTeammember() {
      isAuthorizedArtist[_address] = false;
      emit AdminUpdatedAuthorizedArtist(_address, false);
  }

  /** @dev Allows the teammember to set a featured project id
    * @param _projectId of featured project
    */
  function teamUpdateFeaturedProject(uint256 _projectId) external onlyTeammember() {
    require(_projectId <= currentProjectId);
    featuredProjectId = _projectId;
  }

  /** @dev Allows the contract owner to update the project fee.
    * @param _newProjectFee The new project fee in Wei.
    */
  function contractOwnerUpdateProjectFee(uint256 _newProjectFee) external onlyOwner() {
    projectFee = _newProjectFee;
  }

  /** @dev Allows the contract owner to update the artist cut of sales.
    * @param _percent The new artist percentage
    */
  function contractOwnerUpdateArtistPercent(uint16 _percent) external onlyOwner() {
    require(_percent >= 5000, ">=5000");   // minimum amount an artist should get 50.00%
    require(_percent <= 10000, "<=10000"); // maximum amount artists should get 100.00%
    artistPercent = _percent;
  }

  /** @dev Allows the contract owner to unlock a project.
    * @param _projectId of the project to unlock
    */
  function contractOwnerUnlockProject(uint256 _projectId) external onlyOwner() {
    projects[_projectId].locked = false;
  }

  /** @dev Allows the contract owner to set the royalty percent.
    * @param _newPercent royalty percent
    */
  function contractOwnerUpdateGlobalSecondaryRoyaltyPercent(uint16 _newPercent) external onlyOwner() {
    secondaryRoyaltyPercent = _newPercent;
  }

  /// @dev ANYONE - CREATING A PROJECT AND PROJECT ADMINISTRATION

  /** @dev Allows anyone to create a project _projectName, with _pricePerTokenInWei and _maxEditions.
    * @param _projectName A name of a project
    * @param _pricePerTokenInWei The price for each mint
    * @param _maxEditions The total number of editions for this project
    */
  function anyoneCreateProject(
    string calldata _projectName,
    string calldata _artistName,
    string calldata _description,
    uint256 _pricePerTokenInWei,
    uint256 _maxEditions,
    string calldata _scriptTransactionHash,
    string calldata _scriptType
  ) external payable onlyAuthorizedArtist() {
      require(msg.value >= projectFee, "project fee");
      require(bytes(_projectName).length > 0);
      require(bytes(_artistName).length > 0);
      require(_maxEditions > 0 && _maxEditions <= 1000000);

      currentProjectId++;
      uint256 _projectId = currentProjectId;
      projects[_projectId].name = _projectName;
      projects[_projectId].artist = _artistName;
      projects[_projectId].description = _description;

      projectIdToArtistAddress[_projectId] = msg.sender;
      projectIdToPricePerEditionInWei[_projectId] = _pricePerTokenInWei;
      projects[_projectId].currentEditionId = 0;
      projects[_projectId].maxEditions = _maxEditions;

      projects[_projectId].maxGridDimension = 10;

      projects[_projectId].scriptTransactionHash = _scriptTransactionHash;
      projects[_projectId].scriptType = _scriptType;

      projects[_projectId].active = false;
      projects[_projectId].paused = true;
      projects[_projectId].locked = false;

      setupImmutablesArtRoyaltyManagerForProjectId(_projectId);

      emit AddressCreatedProject(msg.sender, _projectId, _projectName);
  }

  /** @dev Clones a Royalty Manager Contract for a new Project ID
    * @param _projectId the projectId.
    */
  function setupImmutablesArtRoyaltyManagerForProjectId(uint256 _projectId) internal {
      // checks
      require(projectIdToRoyaltyAddress[_projectId] == address(0), "royalty manager already exists for _projectId");

      // effects
      address _newManager = Clones.clone(address(implementation));
      projectIdToRoyaltyAddress[_projectId] = address(_newManager);

      // interactions
      ImmutablesArtRoyaltyManager(payable(_newManager)).initialize(address(this), _projectId, projectIdToArtistAddress[_projectId], artistPercent, address(0), 0);
      emit CreatedImmutablesArtRoyaltyManagerForProjectId(address(_newManager), _projectId);
  }

  /** @dev Releases funds from a Royalty Manager for a Project Id
    * @param _projectId the projectId.
    */
  function releaseRoyaltiesForProject(uint256 _projectId) external {
      ImmutablesArtRoyaltyManager(payable(projectIdToRoyaltyAddress[_projectId])).release();
  }

  /// @dev ARTIST UPDATE FUNCTIONS

  /** @dev Allows the artist to update the artist's Eth address in the contract, and in the Royalty Manager.
    * @param _projectId the projectId.
    * @param _newArtistAddress the new Eth address for the artist.
    */
  function artistUpdateProjectArtistAddress(uint256 _projectId, address _newArtistAddress) external onlyArtist(_projectId) {
      projectIdToArtistAddress[_projectId] = _newArtistAddress;
      ImmutablesArtRoyaltyManager(payable(projectIdToRoyaltyAddress[_projectId])).artistUpdateAddress(_newArtistAddress);
  }

  /** @dev Allows the artist to update project additional payee info.
    * @param _projectId the projectId.
    * @param _additionalPayee the additional payee address.
    * @param _additionalPayeePercent the basis point (1/10,000th) share of project for the _additionalPayee up to artistPercent (e.g., 5000 = 50.0%).
    */
  function artistUpdateProjectAdditionalPayeeInfo(uint256 _projectId, address _additionalPayee, uint16 _additionalPayeePercent) external onlyArtist(_projectId)  {
      // effects
      projectIdToAdditionalPayee[_projectId] = _additionalPayee;
      projectIdToAdditionalPayeePercent[_projectId] = _additionalPayeePercent;

      // interactions
      ImmutablesArtRoyaltyManager(payable(projectIdToRoyaltyAddress[_projectId])).artistUpdateAdditionalPayeeInfo(_additionalPayee, _additionalPayeePercent);
  }

  // ARTIST OR TEAMMEMBER UPDATE FUNCTIONS

  /** @dev Allows the artist or team to update the price per token in wei for a project.
    * @param _projectId the projectId.
    * @param _pricePerTokenInWei new price per token for projectId
    */
  function artistTeamUpdateProjectPricePerTokenInWei(uint256 _projectId, uint256 _pricePerTokenInWei) external onlyArtistOrTeammember(_projectId) {
      projectIdToPricePerEditionInWei[_projectId] = _pricePerTokenInWei;
  }

  /** @dev Allows the artist or team to update the maximum number of editions
    * @dev to display at once in the grid view.
    * @param _projectId the projectId.
    * @param _maxGridDimension the maximum number of editions per side of Grid View Square.
    */
  function artistTeamUpdateProjectMaxGridDimension(uint256 _projectId, uint8 _maxGridDimension) external onlyArtistOrTeammember(_projectId) {
      require(_maxGridDimension > 0);
      require(_maxGridDimension <= 255);
      projects[_projectId].maxGridDimension = _maxGridDimension;
  }

  /** @dev Allows the artist or team to update the maximum number of editions
    * @dev that can be minted for a project.
    * @param _projectId the projectId.
    * @param _maxEditions the maximum number of editions for a project.
    */
  function artistTeamUpdateProjectMaxEditions(uint256 _projectId, uint256 _maxEditions) onlyUnlocked(_projectId) external onlyArtistOrTeammember(_projectId) {
      require(_maxEditions >= projects[_projectId].currentEditionId);
      require(_maxEditions <= 1000000);
      projects[_projectId].maxEditions = _maxEditions;
  }

  /** @dev Allows the artist or team to update the project name.
    * @param _projectId the projectId.
    * @param _projectName the new project name.
    */
  function artistTeamUpdateProjectName(uint256 _projectId, string memory _projectName) onlyUnlocked(_projectId) external onlyArtistOrTeammember(_projectId) {
      projects[_projectId].name = _projectName;
  }

  /** @dev Allows the artist or team to update the artist's name.
    * @param _projectId the projectId.
    * @param _artistName the new artist name.
    */
  function artistTeamUpdateArtistName(uint256 _projectId, string memory _artistName) onlyUnlocked(_projectId) external onlyArtistOrTeammember(_projectId) {
      projects[_projectId].artist = _artistName;
  }

  /** @dev Allows the artist or team update project description.
    * @param _projectId the projectId.
    * @param _description the description for the project.
    */
  function artistTeamUpdateProjectDescription(uint256 _projectId, string calldata _description) onlyUnlocked(_projectId) external onlyArtistOrTeammember(_projectId) {
      projects[_projectId].description = _description;
  }

  /** @dev Allows the artist or team to update the project code transaction
    * @dev hash. The project code should be added to the referenced Immutables
    * @dev page as a Post starting with a line contaning three tick marks ```
    * @dev and ending with a line consisting of three tick marks ```.  The code
    * @dev will then be stored in a Post that has an Eth transaction hash.
    * @dev Add the transaction hash for the code Post to the project using this
    * @dev function. The code will then be pulled from this transaction hash
    * @dev for each render associated with this project.
    * @param _projectId the projectId.
    * @param _scriptTransactionHash the Ethereum transaction hash storing the code.
    */
  function artistTeamUpdateProjectScriptTransactionHash(uint256 _projectId, string memory _scriptTransactionHash) external onlyUnlocked(_projectId) onlyArtistOrTeammember(_projectId) {
      projects[_projectId].scriptTransactionHash = _scriptTransactionHash;
  }

  /** @dev Allows the artist or team to update the project script type.
    * @dev The code contained in the transaction hash will be interpreted
    * @dev by the front end based on the script type.
    * @param _projectId the projectId.
    * @param _scriptType the script type (e.g., p5js)
    */
  function artistTeamUpdateProjectScriptType(uint256 _projectId, string memory _scriptType) external onlyUnlocked(_projectId) onlyArtistOrTeammember(_projectId) {
         projects[_projectId].scriptType = _scriptType;
  }

  /** @dev Allows the artist or team toggle whether the project is paused.
    * @dev A paused project can only be minted by the artist or team.
    * @param _projectId the projectId.
    */
  function artistTeamToggleProjectIsPaused(uint256 _projectId) external onlyArtistOrTeammember(_projectId) {
      projects[_projectId].paused = !projects[_projectId].paused;
  }

  /** @dev Allows the artist or team to set an image URL and file extension.
    * @dev Once project editions are minted, an IPFS CAR file can be created.
    * @dev The CAR file can contain image files with filenames corresponding to
    * @dev the Immutables.art tokenIds for the project. The CAR file can be
    * @dev stored on IPFS, the conract updated with the _newImageURLBase and
    * @dev _newFileExtension and then token images can be found by going to:
    * @dev _newImageBase = ipfs://[cid for the car file]/
    * @dev _newImageURLExt = ".png"
    * @dev Resulting URL = ipfs://[cid for the car file]/[tokenId].png
    * @param _projectId the projectId.
    * @param _newImageURLBase the base for the image url (e.g., "ipfs://[cid]/" )
    * @param _newImageURLExt the file extension for the image file (e.g., ".png" , ".gif" , etc.).
    * @param _useImageURLInGridView bool whether to use the ImageURL in the Grid instead of a live render.
    */
  function artistTeamUpdateProjectImageURLInfo(uint256 _projectId,
                                      string calldata _newImageURLBase,
                                      string calldata _newImageURLExt,
                                      bool _useImageURLInGridView)
                                      external onlyArtistOrTeammember(_projectId) {
    projectIdToImageURLBase[_projectId] = _newImageURLBase;
    projectIdToImageURLExt[_projectId] = _newImageURLExt;
    projectIdUseImageURLInGridView[_projectId] = _useImageURLInGridView;
  }

  /** @dev Allows the artist or team to lock a project.
    * @dev Projects that are locked cannot have certain attributes modified.
    * @param _projectId the projectId.
    */
  function artistTeamLockProject(uint256 _projectId) external onlyUnlocked(_projectId) onlyArtistOrTeammember(_projectId) {
      projects[_projectId].locked = true;
  }

  // TEAMMEMBER ONLY UPDATE FUNCTIONS

  /** @dev Allows the team to set a category for a project.
    * @param _projectId the projectId.
    * @param _category string category name for the project.
    */
  function teamUpdateProjectCategory(uint256 _projectId, string calldata _category) external onlyTeammember() {
      projects[_projectId].category = _category;
      emit AdminUpdatedProjectCategory(_projectId, _category);
  }

  /** @dev Allows the team toggle whether the project is active.
    * @dev Only active projects are visible to the public.
    * @param _projectId the projectId.
    */
  function teamToggleProjectIsActive(uint256 _projectId) external onlyTeammember() {
      projects[_projectId].active = !projects[_projectId].active;
  }

  /** @dev Allows the team to toggle whether or not only approved artists are
    * @dev allowed to create projects.
    */
  function teamToggleArtistScreeningEnabled() external onlyTeammember() {
      artistScreeningEnabled = !artistScreeningEnabled;
  }
}

/// @author Gutenblock.eth
/// @title ImmutablesOptionalMetadataServer
contract ImmutablesOptionalMetadataServer is Ownable {
    /// @dev Stores the base web address for the Immutables web server.
    string public immutablesWEB;
    /// @dev Stores the base URI for the Immutables Metadata server.
    string public immutablesURI;
    /// @dev Whether to serve metadata from the server, or from the contract.
    bool public useMetadataServer;

    constructor () {
      immutablesWEB = "http://immutables.art/#/";
      immutablesURI = "http://nft.immutables.art/";
      useMetadataServer = false;
    }

    /** @dev Allows the contract owner to update the website URL.
      * @param _newImmutablesWEB The new website URL as a string.
      */
    function contractOwnerUpdateWebsite(string calldata _newImmutablesWEB) external onlyOwner() {
      immutablesWEB = _newImmutablesWEB;
    }

    /** @dev Allows the contract owner to update the metadata server URL.
      * @param _newImmutablesURI The new metadata server url as a string.
      */
    function contractOwnerUpdateAPIURL(string calldata _newImmutablesURI) external onlyOwner() {
      immutablesURI = _newImmutablesURI;
    }

    /** @dev Allows the contract owner to set the metadata source.
      * @param _shouldUseMetadataServer true or false
      */
    function contractOwnerUpdateUseMetadataServer(bool _shouldUseMetadataServer) external onlyOwner() {
      useMetadataServer = _shouldUseMetadataServer;
    }
}

/// @author Gutenblock.eth
/// @title ImmutablesArt
contract ImmutablesArt is ImmutablesAdminProject, ImmutablesOptionalMetadataServer, ERC721, IERC2981 {
    using Strings for uint256;
    using Address for address payable;

    /// @dev GLOBAL VARIABLES

    /// @dev The total suppliy of tokens (Editions of all Projects).
    uint256 public maxTotalSupply;
    /// @dev The last tokenId minted.
    uint256 public currentTokenId;

    /// @dev Mappings between the tokenId, projectId, editionIds, and Hashes
    mapping(uint256 => uint256) public tokenIdToProjectId;
    mapping(uint256 => uint256) public tokenIdToEditionId;
    mapping(uint256 => uint256[]) public projectIdToTokenIds;

    /// @dev MODIFIERS

    modifier onlyOwnerOfToken(uint256 _tokenId) {
      require(msg.sender == ownerOf(_tokenId), "must own");
      _;
    }

    modifier onlyArtistOrOwnerOfToken(uint256 _tokenId) {
      require(msg.sender == ownerOf(_tokenId) || msg.sender == projectIdToArtistAddress[tokenIdToProjectId[_tokenId]], "artistOwner");
      _;
    }

    /// @dev EVENTS

    event PaymentReceived(address from, uint256 amount);

    event AddressMintedProjectEditionAsToken(
      address indexed purchaser,
      uint256 indexed projectId,
      uint256 editionId,
      uint256 indexed tokenId
    );

    event TokenUpdatedWithMessage(
      address indexed user,
      uint256 indexed tokenId,
      string message
    );

    /// @dev CONTRACT CONSTRUCTOR

    constructor () ERC721("Immutables.art", "][art") ImmutablesOptionalMetadataServer() {
      projectFee = 0 ether;

      maxTotalSupply = ~uint256(0);
      currentTokenId = 0;

      currentProjectId = 0;

      artistScreeningEnabled = false;
      artistPercent = 9000; // 90.00%

      curator = address(0);
      curatorPercent = 0;

      beneficiary = address(0);
      beneficiaryPercent = 0;

      secondaryRoyaltyPercent = 1000; // 10.00%

      isTeammember[msg.sender] = true;

      emit AdminModifiedTeammembers(msg.sender, true);
    }

    /// @dev FINANCIAL

    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /// @dev HELPER FUNCTIONS

    /** @dev Returns a list of tokenIds for a given projectId.
      * @param _projectId the projectId.
      * @return _tokenIds an array of tokenIds for the given project.
      */
    function getTokenIdsForProjectId(uint256 _projectId) external view returns (uint256[] memory _tokenIds) {
        return projectIdToTokenIds[_projectId];
    }

    /** @dev Used if a web2.0 style metadata server is required for more full
      * @dev featured legacy marketplace compatability.
      * @return _ the metadata server baseURI if a metadata server is used.
      */
    function _baseURI() internal view override returns (string memory) {
      return immutablesURI;
    }

    /** @dev Returns a string from a uint256
      * @param value uint256 data type string
      * @return _ string data type.
      */
    function toString(uint256 value) internal pure returns (string memory) {
            if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /** @dev Returns an image reference for a tokenId.
      * @param _tokenId the tokenId.
      * @return _ an IPFS url to an image, or an SVG image if there is no IPFS image.
      */
    function getImageForTokenId(uint256 _tokenId) internal view returns (string memory) {
      string memory _base = projectIdToImageURLBase[tokenIdToProjectId[_tokenId]];
      string memory _ext = projectIdToImageURLExt[tokenIdToProjectId[_tokenId]];
      if(bytes(_base).length > 0 && bytes(_ext).length > 0) {
        return string(abi.encodePacked(_base,toString(_tokenId),_ext));
      } else {
        return string(abi.encodePacked("data:image/svg+xml;base64,", Base64.encode(bytes(getSVGForTokenId(_tokenId)))));
      }
    }

    /** @dev Returns an SVG string for a tokenId.
      * @param _tokenId the tokenId.
      * @return _ a SVG image string.
      */
    function getSVGForTokenId(uint256 _tokenId) public view returns (string memory) {
      string memory output = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style> .edition { fill: #ffffff; font-family: Open Sans; font-size: 12px; } .base { fill: #ffffff; font-family: Open Sans; font-size: 180px; } </style> <rect width="100%" height="100%" fill="#9400D3" /> <text class="edition" x="50%" y="5%" dominant-baseline="middle" text-anchor="middle">';
      output = string(abi.encodePacked(output, projects[tokenIdToProjectId[_tokenId]].name, ' # ', toString(tokenIdToEditionId[_tokenId])));
      output = string(abi.encodePacked(output,'</text><text class="edition" x="50%" y="10%" dominant-baseline="middle" text-anchor="middle">][art # ', toString(_tokenId)));
      output = string(abi.encodePacked(output,'</text><text class="base" x="50%" y = "50%" dominant-baseline="middle" text-anchor="middle">][</text></svg>'));
      return output;
    }

    /** @dev Returns a metadata attributes string for a tokenId.
      * @param _tokenId the tokenId.
      * @return _ a metadata attributes string.
      */
    function getMetadataAttributesStringForTokenId(uint256 _tokenId) internal view returns (string memory) {
      uint256 _projectId = tokenIdToProjectId[_tokenId];
      string memory output = string(
        abi.encodePacked(
          '"attributes": [',
                '{"trait_type": "Project", "value": "', projects[_projectId].name,'"},',
                '{"trait_type": "Artist", "value": "', projects[_projectId].artist,'"},',
                '{"trait_type": "Category","value": "', projects[_projectId].category,'"}',
          ']'
        )
      );
      return output;
    }

    /** @dev Returns a metadata string for a tokenId.
      * @param _tokenId the tokenId.
      * @return _ a metadata string.
      */
    function getMetadataStringForTokenId(uint256 _tokenId) internal view returns (string memory) {
      uint256 _projectId = tokenIdToProjectId[_tokenId];
      string memory _url = string(abi.encodePacked(immutablesWEB, toString(_projectId), '/', toString(tokenIdToEditionId[_tokenId])));
      //string memory _collection = string(abi.encodePacked(projects[_projectId].name, " by ", projects[_projectId].artist));
      string memory output = string(
        abi.encodePacked(
          '{"name": "', projects[_projectId].name, ' # ', toString(tokenIdToEditionId[_tokenId]),
          '", "description": "', projects[_projectId].description,
          '", "external_url": "', _url,
          '", ', getMetadataAttributesStringForTokenId(_tokenId)
        )
      );
      return output;
    }

    /** @dev Returns a tokenURI URL or Metadata string depending on useMetadataServer
      * @param _tokenId the _tokenId.
      * @return _ String of a URI or Base64 encoded metadata and image string.
      */
    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
      require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
      if(useMetadataServer) { // IF THE METADATA SERVER IS IN USE RETURN A URL
        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, _tokenId.toString())) : "";
      } else { // ELSE WE ARE SERVERLESS AND RETURN METADATA DIRECTLY h/t DEAFBEEF FIRST NFT
        string memory json = Base64.encode(
          bytes(
            string(
              abi.encodePacked(
                getMetadataStringForTokenId(_tokenId),
                ', "image": "',
                getImageForTokenId(_tokenId),
                '"}'
              )
            )
          )
        );
        json = string(abi.encodePacked('data:application/json;base64,', json));
        return json;
      }
    }

    /// @dev royaltiesAddress - IERC2981

    /** @dev Returns the ERC2981 royaltyInfo.
      * @param _tokenId the _tokenId.
      * @param _salePrice the sales price to use for the royalty calculation.
      * @return receiver the recipient of the royalty payment.
      * @return royaltyAmount the calcualted royalty amount.
      */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view override returns (address receiver, uint256 royaltyAmount) {
      require(_tokenId <= currentTokenId, "tokenId");
      return (projectIdToRoyaltyAddress[tokenIdToProjectId[_tokenId]], _salePrice * secondaryRoyaltyPercent / 10000);
    }

    /// @dev CONTRACT ADMINISTRATION

    /** @dev The artist or owner of a token can post a message associated with
      * @dev an edition of the project.
      * @param _tokenId the tokenId.
      * @param _message the message to add to the token.
      */
    function artistOwnerUpdateTokenWithMessage(uint256 _tokenId, string calldata _message) external onlyArtistOrOwnerOfToken(_tokenId) {
      require(bytes(_message).length > 0);
      emit TokenUpdatedWithMessage(msg.sender, _tokenId, _message);
    }

    /// @dev ANYONE - MINTING AN EDITION

    /** @dev Anyone can mint an edition of a project.
      * @param _projectId the projectId of the project to mint.
      */
    function anyoneMintProjectEdition(uint256 _projectId) external payable {
      // checks
      require(msg.value >= projectIdToPricePerEditionInWei[_projectId], "mint fee");
      require(projects[_projectId].currentEditionId < projects[_projectId].maxEditions, "sold out");
      // require project to be active or the artist or teammember to be trying to mint
      require(projects[_projectId].active || msg.sender == projectIdToArtistAddress[_projectId] || isTeammember[msg.sender], "not active");
      // require project to be unpaused or the artist or teammember to be trying to mint
      require(!projects[_projectId].paused || msg.sender == projectIdToArtistAddress[_projectId] || isTeammember[msg.sender], "paused");

      // effects
      uint256 _newTokenId = ++currentTokenId;
      uint256 _newEditionId = ++projects[_projectId].currentEditionId;

      tokenIdToProjectId[_newTokenId] = _projectId;
      tokenIdToEditionId[_newTokenId] = _newEditionId;
      projectIdToTokenIds[_projectId].push(_newTokenId);

      // interactions
      _mint(msg.sender, _newTokenId);
      //(bool success, ) = payable(projectIdToRoyaltyAddress[_projectId]).call{value:msg.value}("");
      //require(success, "Transfer to Royalty Manager contract failed.");
      payable(projectIdToRoyaltyAddress[_projectId]).sendValue(msg.value);

      emit AddressMintedProjectEditionAsToken(msg.sender, _projectId, _newEditionId, _newTokenId);
    }
}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

File 1 of 18: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 2 of 18: Clones.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create2(0, ptr, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
            mstore(add(ptr, 0x38), shl(0x60, deployer))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(address implementation, bytes32 salt)
        internal
        view
        returns (address predicted)
    {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

File 3 of 18: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 4 of 18: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 5 of 18: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 6 of 18: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 7 of 18: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 8 of 18: IERC2981.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard
 */
interface IERC2981 is IERC165 {
    /**
     * @dev 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 salePrice - the sale price 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 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 9 of 18: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 10 of 18: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 11 of 18: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 13 of 18: ImmutablesArtRoyaltyManager.sol
// SPDX-License-Identifier: UNLICENSED
// All Rights Reserved

// Contract is not audited.
// Use authorized deployments of this contract at your own risk.

/*
$$$$$$\ $$\      $$\ $$\      $$\ $$\   $$\ $$$$$$$$\  $$$$$$\  $$$$$$$\  $$\       $$$$$$$$\  $$$$$$\       $$$$$$\  $$$$$$$\ $$$$$$$$\
\_$$  _|$$$\    $$$ |$$$\    $$$ |$$ |  $$ |\__$$  __|$$  __$$\ $$  __$$\ $$ |      $$  _____|$$  __$$\     $$  __$$\ $$  __$$\\__$$  __|
  $$ |  $$$$\  $$$$ |$$$$\  $$$$ |$$ |  $$ |   $$ |   $$ /  $$ |$$ |  $$ |$$ |      $$ |      $$ /  \__|    $$ /  $$ |$$ |  $$ |  $$ |
  $$ |  $$\$$\$$ $$ |$$\$$\$$ $$ |$$ |  $$ |   $$ |   $$$$$$$$ |$$$$$$$\ |$$ |      $$$$$\    \$$$$$$\      $$$$$$$$ |$$$$$$$  |  $$ |
  $$ |  $$ \$$$  $$ |$$ \$$$  $$ |$$ |  $$ |   $$ |   $$  __$$ |$$  __$$\ $$ |      $$  __|    \____$$\     $$  __$$ |$$  __$$<   $$ |
  $$ |  $$ |\$  /$$ |$$ |\$  /$$ |$$ |  $$ |   $$ |   $$ |  $$ |$$ |  $$ |$$ |      $$ |      $$\   $$ |    $$ |  $$ |$$ |  $$ |  $$ |
$$$$$$\ $$ | \_/ $$ |$$ | \_/ $$ |\$$$$$$  |   $$ |   $$ |  $$ |$$$$$$$  |$$$$$$$$\ $$$$$$$$\ \$$$$$$  |$$\ $$ |  $$ |$$ |  $$ |  $$ |
\______|\__|     \__|\__|     \__| \______/    \__|   \__|  \__|\_______/ \________|\________| \______/ \__|\__|  \__|\__|  \__|  \__|
$$$$$$$\   $$$$$$\ $$\     $$\  $$$$$$\  $$\    $$$$$$$$\ $$\     $$\
$$  __$$\ $$  __$$\\$$\   $$  |$$  __$$\ $$ |   \__$$  __|\$$\   $$  |
$$ |  $$ |$$ /  $$ |\$$\ $$  / $$ /  $$ |$$ |      $$ |    \$$\ $$  /
$$$$$$$  |$$ |  $$ | \$$$$  /  $$$$$$$$ |$$ |      $$ |     \$$$$  /
$$  __$$< $$ |  $$ |  \$$  /   $$  __$$ |$$ |      $$ |      \$$  /
$$ |  $$ |$$ |  $$ |   $$ |    $$ |  $$ |$$ |      $$ |       $$ |
$$ |  $$ | $$$$$$  |   $$ |    $$ |  $$ |$$$$$$$$\ $$ |       $$ |
\__|  \__| \______/    \__|    \__|  \__|\________|\__|       \__|
$$\      $$\  $$$$$$\  $$\   $$\  $$$$$$\   $$$$$$\  $$$$$$$$\ $$$$$$$\
$$$\    $$$ |$$  __$$\ $$$\  $$ |$$  __$$\ $$  __$$\ $$  _____|$$  __$$\
$$$$\  $$$$ |$$ /  $$ |$$$$\ $$ |$$ /  $$ |$$ /  \__|$$ |      $$ |  $$ |
$$\$$\$$ $$ |$$$$$$$$ |$$ $$\$$ |$$$$$$$$ |$$ |$$$$\ $$$$$\    $$$$$$$  |
$$ \$$$  $$ |$$  __$$ |$$ \$$$$ |$$  __$$ |$$ |\_$$ |$$  __|   $$  __$$<
$$ |\$  /$$ |$$ |  $$ |$$ |\$$$ |$$ |  $$ |$$ |  $$ |$$ |      $$ |  $$ |
$$ | \_/ $$ |$$ |  $$ |$$ | \$$ |$$ |  $$ |\$$$$$$  |$$$$$$$$\ $$ |  $$ |
\__|     \__|\__|  \__|\__|  \__|\__|  \__| \______/ \________|\__|  \__|
*/

pragma solidity ^0.8.0;

/**
 * @author Gutenblock.eth
 * @title ImmutablesArtRoyaltyManager
 * @dev This contract allows to split Ether royalty payments between the
 * Immutables.art contract and an Immutables.art project artist.
 *
 * `ImmutablesArtRoyaltyManager` follows a _pull payment_ model. This means that payments
 * are not automatically forwarded to the accounts but kept in this contract,
 * and the actual transfer is triggered as a separate step by calling the
 * {release} function.
 *
 * The contract is written to serve as an implementation for minimal proxy clones.
 */

import "./Context.sol";
import "./Address.sol";
import "./SafeERC20.sol";
import "./Initializable.sol";
import "./ReentrancyGuard.sol";

contract ImmutablesArtRoyaltyManager is Context, Initializable, ReentrancyGuard {
    using Address for address payable;

    /// @dev The address of the ImmutablesArt contract.
    address public immutablesArtContract;
    /// @dev The projectId of the associated ImmutablesArt project.
    uint256 public immutablesArtProjectId;

    /// @dev The address of the artist.
    address public artist;
    /// @dev The address of the additionalPayee set by the artist.
    address public additionalPayee;
    /// @dev The artist's percentage of the total expressed in basis points
    ///      (1/10,000ths).  The artist can allot up to all of this to
    ///      an additionalPayee.
    uint16 public artistPercent;
    /// @dev The artist's percentage, after additional payee,
    ///      of the total expressed as basis points (1/10,000ths).
    uint16 public artistPercentMinusAdditionalPayeePercent;
    /// @dev The artist's additional payee percentae of the total
    /// @dev expressed in basis points (1/10,000ths).  Valid from 0 to artistPercent.
    uint16 public additionalPayeePercent;

    /// EVENTS

    event PayeeAdded(address indexed account, uint256 percent);
    event PayeeRemoved(address indexed account, uint256 percent);
    event PaymentReleased(address indexed to, uint256 amount);
    event PaymentReleasedERC20(IERC20 indexed token, address indexed to, uint256 amount);
    event PaymentReceived(address indexed from, uint256 amount);

    /**
     * @dev Creates an uninitialized instance of `ImmutablesArtRoyaltyManager`.
     */
    constructor() { }

    /**
     * @dev Initialized an instance of `ImmutablesArtRoyaltyManager`
     */
    function initialize(address _immutablesArtContract, uint256 _immutablesArtProjectId,
                        address _artist, uint16 _artistPercent,
                        address _additionalPayee, uint16 _additionalPayeePercent
                        ) public initializer() {
        immutablesArtContract = _immutablesArtContract;
        immutablesArtProjectId = _immutablesArtProjectId;

        artist = _artist;
        artistPercent = _artistPercent;
        additionalPayee = _additionalPayee;
        additionalPayeePercent = _additionalPayeePercent;
        artistPercentMinusAdditionalPayeePercent = _artistPercent - _additionalPayeePercent;

        emit PayeeAdded(immutablesArtContract, 10000 - artistPercent);
        emit PayeeAdded(artist, artistPercentMinusAdditionalPayeePercent);
        if(additionalPayee != address(0)) {
          emit PayeeAdded(additionalPayee, additionalPayeePercent);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    function artistUpdateAddress(address _newArtistAddress) public {
        // only the parent contract and the artist can call this function.
        // the parent contract only calls this function at the request of the artist.
        require(_msgSender() == immutablesArtContract || _msgSender() == artist, "auth");

        // update the artist address
        emit PayeeRemoved(artist, artistPercentMinusAdditionalPayeePercent);
        artist = _newArtistAddress;
        emit PayeeAdded(artist, artistPercentMinusAdditionalPayeePercent);
    }

    function artistUpdateAdditionalPayeeInfo(address _newAdditionalPayee, uint16 _newPercent) public {
        // only the parent contract and the artist can call this function.
        // the parent contract only calls this function at the request of the artist.
        require(_msgSender() == immutablesArtContract || _msgSender() == artist, "auth");

        // the maximum amount the artist can give to an additional payee is
        // the current artistPercent plus the current additionalPayeePercent.
        require(_newPercent <= artistPercent, "percent too big");

        // Before changing the additional payee information,
        // payout ETH to everyone as indicated when prior payments were made.
        // since we won't know what ERC20 token addresses if any are held,
        // by the contract, we cant force payout on additional payee change.
        release();

        // Change the additional payee and relevant percentages.
        emit PayeeRemoved(artist, artistPercentMinusAdditionalPayeePercent);
        if(additionalPayee != address(0)) {
          emit PayeeRemoved(additionalPayee, additionalPayeePercent);
        }

        additionalPayee = _newAdditionalPayee;
        additionalPayeePercent = _newPercent;
        artistPercentMinusAdditionalPayeePercent = artistPercent - _newPercent;

        emit PayeeAdded(artist, artistPercentMinusAdditionalPayeePercent);
        if(additionalPayee != address(0)) {
          emit PayeeAdded(additionalPayee, additionalPayeePercent);
        }
    }

    /**
     * @dev Triggers payout of all ETH royalties.
     */
    function release() public virtual nonReentrant() {
        // checks
        uint256 _startingBalance = address(this).balance;

        // Since this is called when there is a payee change,
        // we do not want to use require and cause a revert
        // if there is no balance.
        if(_startingBalance > 0) {
            // effects
            uint256 _artistAmount = _startingBalance * artistPercentMinusAdditionalPayeePercent / 10000;
            uint256 _additionalPayeeAmount = _startingBalance * additionalPayeePercent / 10000;
            uint256 _contractAmount = _startingBalance - _artistAmount - _additionalPayeeAmount;

            // interactions
            payable(immutablesArtContract).sendValue(_contractAmount);
            emit PaymentReleased(immutablesArtContract, _contractAmount);
            if(artist != address(0) && _artistAmount > 0) {
              payable(artist).sendValue(_artistAmount);
              emit PaymentReleased(artist, _artistAmount);
            }
            if(additionalPayee != address(0) && _additionalPayeeAmount > 0) {
              payable(additionalPayee).sendValue(_additionalPayeeAmount);
              emit PaymentReleased(additionalPayee, _additionalPayeeAmount);
            }
        }
    }

    /**
     * @dev Triggers payout of all ERC20 royalties.
     */
    function releaseERC20(IERC20 token) public virtual nonReentrant() {
        // checks
        uint256 _startingBalance = token.balanceOf(address(this));
        require(_startingBalance > 0, "no tokens");

        // effects
        uint256 _artistAmount = _startingBalance * artistPercentMinusAdditionalPayeePercent / 10000;
        uint256 _additionalPayeeAmount = _startingBalance * additionalPayeePercent / 10000;
        uint256 _contractAmount = _startingBalance - _artistAmount - _additionalPayeeAmount;

        // interactions
        SafeERC20.safeTransfer(token, immutablesArtContract, _contractAmount);
        emit PaymentReleasedERC20(token, immutablesArtContract, _contractAmount);
        if(artist != address(0) && _artistAmount > 0) {
          SafeERC20.safeTransfer(token, artist, _artistAmount);
          emit PaymentReleasedERC20(token, artist, _artistAmount);
        }
        if(additionalPayee != address(0) && _additionalPayeeAmount > 0) {
          SafeERC20.safeTransfer(token, additionalPayee, _additionalPayeeAmount);
          emit PaymentReleasedERC20(token, additionalPayee, _additionalPayeeAmount);
        }
    }
}

File 14 of 18: Initializable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }
}

File 15 of 18: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 16 of 18: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 17 of 18: SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 18 of 18: Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"artist","type":"address"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"string","name":"projectName","type":"string"}],"name":"AddressCreatedProject","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"purchaser","type":"address"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"editionId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"AddressMintedProjectEditionAsToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isTeammember","type":"bool"}],"name":"AdminModifiedTeammembers","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorizedArtist","type":"bool"}],"name":"AdminUpdatedAuthorizedArtist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"string","name":"category","type":"string"}],"name":"AdminUpdatedProjectCategory","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"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":"royaltyManager","type":"address"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"}],"name":"CreatedImmutablesArtRoyaltyManagerForProjectId","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":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"TokenUpdatedWithMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"_projectName","type":"string"},{"internalType":"string","name":"_artistName","type":"string"},{"internalType":"string","name":"_description","type":"string"},{"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"},{"internalType":"uint256","name":"_maxEditions","type":"uint256"},{"internalType":"string","name":"_scriptTransactionHash","type":"string"},{"internalType":"string","name":"_scriptType","type":"string"}],"name":"anyoneCreateProject","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"anyoneMintProjectEdition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_message","type":"string"}],"name":"artistOwnerUpdateTokenWithMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artistPercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"artistScreeningEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"artistTeamLockProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"artistTeamToggleProjectIsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_artistName","type":"string"}],"name":"artistTeamUpdateArtistName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_description","type":"string"}],"name":"artistTeamUpdateProjectDescription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_newImageURLBase","type":"string"},{"internalType":"string","name":"_newImageURLExt","type":"string"},{"internalType":"bool","name":"_useImageURLInGridView","type":"bool"}],"name":"artistTeamUpdateProjectImageURLInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_maxEditions","type":"uint256"}],"name":"artistTeamUpdateProjectMaxEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint8","name":"_maxGridDimension","type":"uint8"}],"name":"artistTeamUpdateProjectMaxGridDimension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_projectName","type":"string"}],"name":"artistTeamUpdateProjectName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"}],"name":"artistTeamUpdateProjectPricePerTokenInWei","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_scriptTransactionHash","type":"string"}],"name":"artistTeamUpdateProjectScriptTransactionHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_scriptType","type":"string"}],"name":"artistTeamUpdateProjectScriptType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_additionalPayee","type":"address"},{"internalType":"uint16","name":"_additionalPayeePercent","type":"uint16"}],"name":"artistUpdateProjectAdditionalPayeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_newArtistAddress","type":"address"}],"name":"artistUpdateProjectArtistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiaryPercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"contractOwnerAddTeammember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"contractOwnerRemoveTeammember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"contractOwnerUnlockProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newImmutablesURI","type":"string"}],"name":"contractOwnerUpdateAPIURL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_percent","type":"uint16"}],"name":"contractOwnerUpdateArtistPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newBeneficiary","type":"address"},{"internalType":"uint16","name":"_newPercent","type":"uint16"}],"name":"contractOwnerUpdateBeneficiaryAddressAndPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCurator","type":"address"},{"internalType":"uint16","name":"_newPercent","type":"uint16"}],"name":"contractOwnerUpdateCuratorAddressAndPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_newPercent","type":"uint16"}],"name":"contractOwnerUpdateGlobalSecondaryRoyaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newProjectFee","type":"uint256"}],"name":"contractOwnerUpdateProjectFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_shouldUseMetadataServer","type":"bool"}],"name":"contractOwnerUpdateUseMetadataServer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newImmutablesWEB","type":"string"}],"name":"contractOwnerUpdateWebsite","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"curator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curatorPercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentProjectId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"featuredProjectId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getSVGForTokenId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getTokenIdsForProjectId","outputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"immutablesURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"immutablesWEB","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"contract ImmutablesArtRoyaltyManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAuthorizedArtist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTeammember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToAdditionalPayee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToAdditionalPayeePercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToArtistAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToImageURLBase","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToImageURLExt","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToPricePerEditionInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToRoyaltyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdUseImageURLInGridView","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projects","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"artist","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint256","name":"currentEditionId","type":"uint256"},{"internalType":"uint256","name":"maxEditions","type":"uint256"},{"internalType":"uint8","name":"maxGridDimension","type":"uint8"},{"internalType":"string","name":"scriptTransactionHash","type":"string"},{"internalType":"string","name":"scriptType","type":"string"},{"internalType":"string","name":"category","type":"string"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"locked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"releaseRoyaltiesForProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondaryRoyaltyPercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"teamAddAuthorizedArtist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"teamRemoveAuthorizedArtist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"teamToggleArtistScreeningEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"teamToggleProjectIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"teamUpdateFeaturedProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"string","name":"_category","type":"string"}],"name":"teamUpdateProjectCategory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToEditionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToProjectId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"useMetadataServer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526008805462ff0000191690553480156200001d57600080fd5b506040518060400160405280600e81526020016d125b5b5d5d18589b195ccb985c9d60921b815250604051806040016040528060058152602001641756d85c9d60da1b8152506200007d62000077620002d460201b60201c565b620002d8565b600180556040516200008f9062000328565b604051809103906000f080158015620000ac573d6000803e3d6000fd5b50600880546001600160a01b0392831663010000009081026301000000600160b81b03198316811793849055604051632546562960e21b8152306004820181905260016024830152604482015261ffff9182169190931617606483015260006084830181905260a48301529091049091169063951958a49060c401600060405180830381600087803b1580156200014257600080fd5b505af115801562000157573d6000803e3d6000fd5b50506040805180820190915260188082527f687474703a2f2f696d6d757461626c65732e6172742f232f00000000000000006020909201918252620001a193506014925062000336565b5060408051808201909152601a8082527f687474703a2f2f6e66742e696d6d757461626c65732e6172742f0000000000006020909201918252620001e89160159162000336565b506016805460ff1916905581516200020890601790602085019062000336565b5080516200021e90601890602084019062000336565b505060006005819055600019601d55601e81905560068190556008805462ffffff1916612328179055600280546001600160b01b0319908116909155600380549091169055600f805461ffff19166103e8179055338082526004602052604091829020805460ff1916600190811790915591519092507f395c8250a24c0334974196af39013f5f036bc82eb5270ee99dffe50d48455ac491620002c691901515815260200190565b60405180910390a262000419565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6113b780620061a183390190565b8280546200034490620003dc565b90600052602060002090601f016020900481019282620003685760008555620003b3565b82601f106200038357805160ff1916838001178555620003b3565b82800160010185558215620003b3579182015b82811115620003b357825182559160200191906001019062000396565b50620003c1929150620003c5565b5090565b5b80821115620003c15760008155600101620003c6565b600181811c90821680620003f157607f821691505b602082108114156200041357634e487b7160e01b600052602260045260246000fd5b50919050565b615d7880620004296000396000f3fe6080604052600436106104ac5760003560e01c80637bd806261161026b578063cbe5b9381161014f578063e66f53b7116100c1578063f4c9d86c11610085578063f4c9d86c14610fb1578063f4f3b20014610fd1578063f85a5a9714610ff1578063fd0c459a14611011578063fd8be44f14611024578063ff29ab4e1461105157600080fd5b8063e66f53b714610eed578063e985e9c514610f0d578063ea75794614610f56578063f2fde38b14610f71578063f337968e14610f9157600080fd5b8063d7b044b611610113578063d7b044b614610e06578063d815d0b214610e3c578063dd733ea714610e68578063dfa674a014610e88578063e25edbb314610ea8578063e6545a8614610ed857600080fd5b8063cbe5b93814610d7d578063cd00c1f914610d9d578063d0dcd5a214610dbd578063d0ee265e14610dd0578063d58f2f2714610df057600080fd5b8063a47d29cb116101e8578063b72216cd116101ac578063b72216cd14610cc7578063b83a2e8e14610ce7578063b88d4fde14610d07578063c2b3b6d114610d27578063c87b56dd14610d47578063c92f695b14610d6757600080fd5b8063a47d29cb14610c11578063a83572aa14610c47578063afd9e4f314610c67578063b03c128814610c87578063b15a9a9b14610ca757600080fd5b8063990cede81161022f578063990cede814610b715780639a5f79ad14610b915780639ddcd85914610bb1578063a0e16a3a14610bd1578063a22cb46514610bf157600080fd5b80637bd8062614610ac85780638da5cb5b14610afe5780639521a42c14610b1c57806395d89b4114610b3c5780639735b4d814610b5157600080fd5b806338af3eed116103925780635c60da1b1161030f5780636eb86599116102d35780636eb8659914610a0257806370a0823114610a22578063715018a614610a425780637878707214610a5757806378fa524814610a7757806379a84bb914610a9757600080fd5b80635c60da1b146109615780635ff82791146109885780636352211e146109a8578063641d4e38146109c85780636dc78f0c146109e857600080fd5b80634624aea4116103565780634624aea4146108d157806346c94c36146108f1578063472cad9914610911578063479767731461092c5780635961d1191461094c57600080fd5b806338af3eed1461083a5780633b1c9b681461085a5780633ccfd60b1461087c57806342842e0e146108915780634529cf18146108b157600080fd5b80631a5206b91161042b57806323b872dd116103ef57806323b872dd1461077a5780632969be221461079a5780632a08313e146107b05780632a55205a146107d05780632ab4d0521461080f5780633219bdcf1461082557600080fd5b80631a5206b9146106a85780631b689c0b146106dd5780631c0970071461070a5780631cbb4e391461072a5780632290bd4c1461074a57600080fd5b8063081812fc11610472578063081812fc146105c9578063095ea7b314610601578063107046bd1461062357806316967c0b1461065b5780631a3ef1381461067b57600080fd5b806233f9ee146104fa5780629a9b7b1461053057806301ffc9a71461055457806306fdde031461058457806307b62c001461059957600080fd5b366104f5577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561050657600080fd5b5061051a610515366004614a81565b611071565b6040516105279190614af2565b60405180910390f35b34801561053c57600080fd5b50610546601e5481565b604051908152602001610527565b34801561056057600080fd5b5061057461056f366004614b1b565b61113b565b6040519015158152602001610527565b34801561059057600080fd5b5061051a61118d565b3480156105a557600080fd5b506105746105b4366004614b4d565b60046020526000908152604090205460ff1681565b3480156105d557600080fd5b506105e96105e4366004614a81565b61121f565b6040516001600160a01b039091168152602001610527565b34801561060d57600080fd5b5061062161061c366004614b6a565b6112b9565b005b34801561062f57600080fd5b5061064361063e366004614a81565b6113cf565b6040516105279c9b9a99989796959493929190614b96565b34801561066757600080fd5b50610621610676366004614c6e565b61176a565b34801561068757600080fd5b50610546610696366004614a81565b600b6020526000908152604090205481565b3480156106b457600080fd5b506002546106ca90600160a01b900461ffff1681565b60405161ffff9091168152602001610527565b3480156106e957600080fd5b506105466106f8366004614a81565b601f6020526000908152604090205481565b34801561071657600080fd5b50610621610725366004614c6e565b61182b565b34801561073657600080fd5b50610621610745366004614cca565b61186d565b34801561075657600080fd5b50610574610765366004614a81565b60126020526000908152604090205460ff1681565b34801561078657600080fd5b50610621610795366004614d15565b6118f8565b3480156107a657600080fd5b5061054660065481565b3480156107bc57600080fd5b506106216107cb366004614b4d565b611929565b3480156107dc57600080fd5b506107f06107eb366004614d56565b6119ae565b604080516001600160a01b039093168352602083019190915201610527565b34801561081b57600080fd5b50610546601d5481565b34801561083157600080fd5b50610621611a40565b34801561084657600080fd5b506003546105e9906001600160a01b031681565b34801561086657600080fd5b506003546106ca90600160a01b900461ffff1681565b34801561088857600080fd5b50610621611a8e565b34801561089d57600080fd5b506106216108ac366004614d15565b611c12565b3480156108bd57600080fd5b506106216108cc366004614a81565b611c2d565b3480156108dd57600080fd5b506106216108ec366004614b4d565b611c5c565b3480156108fd57600080fd5b5061062161090c366004614d56565b611ccb565b34801561091d57600080fd5b506008546106ca9061ffff1681565b34801561093857600080fd5b50610621610947366004614a81565b611d9d565b34801561095857600080fd5b5061051a611e04565b34801561096d57600080fd5b506008546105e990630100000090046001600160a01b031681565b34801561099457600080fd5b506106216109a3366004614a81565b611e92565b3480156109b457600080fd5b506105e96109c3366004614a81565b611ed5565b3480156109d457600080fd5b506106216109e3366004614e03565b611f4c565b3480156109f457600080fd5b506016546105749060ff1681565b348015610a0e57600080fd5b50610621610a1d366004614e03565b611ff8565b348015610a2e57600080fd5b50610546610a3d366004614b4d565b6120aa565b348015610a4e57600080fd5b50610621612131565b348015610a6357600080fd5b50610621610a72366004614e5d565b612167565b348015610a8357600080fd5b50610621610a92366004614b4d565b61228c565b348015610aa357600080fd5b506106ca610ab2366004614a81565b600d6020526000908152604090205461ffff1681565b348015610ad457600080fd5b506105e9610ae3366004614a81565b600e602052600090815260409020546001600160a01b031681565b348015610b0a57600080fd5b506000546001600160a01b03166105e9565b348015610b2857600080fd5b5061051a610b37366004614a81565b612312565b348015610b4857600080fd5b5061051a61232b565b348015610b5d57600080fd5b50610621610b6c366004614cca565b61233a565b348015610b7d57600080fd5b50610621610b8c366004614e03565b612414565b348015610b9d57600080fd5b50610621610bac366004614cca565b6124c6565b348015610bbd57600080fd5b50610621610bcc366004614e92565b612577565b348015610bdd57600080fd5b50610621610bec366004614ec8565b612610565b348015610bfd57600080fd5b50610621610c0c366004614f14565b612711565b348015610c1d57600080fd5b506105e9610c2c366004614a81565b600a602052600090815260409020546001600160a01b031681565b348015610c5357600080fd5b50610621610c62366004614a81565b6127d6565b348015610c7357600080fd5b50610621610c82366004614a81565b612888565b348015610c9357600080fd5b50610621610ca2366004614b4d565b612908565b348015610cb357600080fd5b50610546610cc2366004614d56565b61296f565b348015610cd357600080fd5b50610621610ce2366004614a81565b6129a0565b348015610cf357600080fd5b50610621610d02366004614f42565b6129f3565b348015610d1357600080fd5b50610621610d22366004614f67565b612ad4565b348015610d3357600080fd5b50610621610d42366004614a81565b612b0c565b348015610d5357600080fd5b5061051a610d62366004614a81565b612b54565b348015610d7357600080fd5b5061054660075481565b348015610d8957600080fd5b5061051a610d98366004614a81565b612c8e565b348015610da957600080fd5b50610621610db8366004614e03565b612ca7565b610621610dcb366004614fe6565b612d59565b348015610ddc57600080fd5b50610621610deb366004615104565b612f86565b348015610dfc57600080fd5b5061054660055481565b348015610e1257600080fd5b506105e9610e21366004614a81565b600c602052600090815260409020546001600160a01b031681565b348015610e4857600080fd5b50610546610e57366004614a81565b602080526000908152604090205481565b348015610e7457600080fd5b50610621610e83366004614e5d565b612fbc565b348015610e9457600080fd5b50610621610ea3366004615104565b61304c565b348015610eb457600080fd5b50610574610ec3366004614b4d565b60136020526000908152604090205460ff1681565b348015610ee457600080fd5b5061051a613082565b348015610ef957600080fd5b506002546105e9906001600160a01b031681565b348015610f1957600080fd5b50610574610f28366004615145565b6001600160a01b039182166000908152601c6020908152604080832093909416825291909152205460ff1690565b348015610f6257600080fd5b50600f546106ca9061ffff1681565b348015610f7d57600080fd5b50610621610f8c366004614b4d565b61308f565b348015610f9d57600080fd5b506008546105749062010000900460ff1681565b348015610fbd57600080fd5b50610621610fcc366004615173565b61312a565b348015610fdd57600080fd5b50610621610fec366004614b4d565b6131d6565b348015610ffd57600080fd5b5061062161100c3660046151fe565b61344a565b61062161101f366004614a81565b613487565b34801561103057600080fd5b5061104461103f366004614a81565b613724565b604051610527919061521b565b34801561105d57600080fd5b5061062161106c366004614d56565b613786565b60606000604051806101c001604052806101838152602001615b6061018391396000848152601f60209081526040808320548352600982528083208784529180529091205491925082916110c4906137eb565b6040516020016110d693929190615334565b6040516020818303038152906040529050806110f1846137eb565b60405160200161110292919061537d565b6040516020818303038152906040529050806040516020016111249190615430565b60408051601f198184030181529190529392505050565b60006001600160e01b031982166380ac58cd60e01b148061116c57506001600160e01b03198216635b5e139f60e01b145b8061118757506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606017805461119c9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546111c89061525f565b80156112155780601f106111ea57610100808354040283529160200191611215565b820191906000526020600020905b8154815290600101906020018083116111f857829003601f168201915b5050505050905090565b6000818152601960205260408120546001600160a01b031661129d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152601b60205260409020546001600160a01b031690565b60006112c482611ed5565b9050806001600160a01b0316836001600160a01b031614156113325760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401611294565b336001600160a01b038216148061134e575061134e8133610f28565b6113c05760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401611294565b6113ca83836138f0565b505050565b6009602052600090815260409020805481906113ea9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546114169061525f565b80156114635780601f1061143857610100808354040283529160200191611463565b820191906000526020600020905b81548152906001019060200180831161144657829003601f168201915b5050505050908060010180546114789061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546114a49061525f565b80156114f15780601f106114c6576101008083540402835291602001916114f1565b820191906000526020600020905b8154815290600101906020018083116114d457829003601f168201915b5050505050908060020180546115069061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546115329061525f565b801561157f5780601f106115545761010080835404028352916020019161157f565b820191906000526020600020905b81548152906001019060200180831161156257829003601f168201915b5050506003840154600485015460058601546006870180549697939692955060ff9091169350906115af9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546115db9061525f565b80156116285780601f106115fd57610100808354040283529160200191611628565b820191906000526020600020905b81548152906001019060200180831161160b57829003601f168201915b50505050509080600701805461163d9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546116699061525f565b80156116b65780601f1061168b576101008083540402835291602001916116b6565b820191906000526020600020905b81548152906001019060200180831161169957829003601f168201915b5050505050908060080180546116cb9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546116f79061525f565b80156117445780601f1061171957610100808354040283529160200191611744565b820191906000526020600020905b81548152906001019060200180831161172757829003601f168201915b5050506009909301549192505060ff80821691610100810482169162010000909104168c565b6000546001600160a01b031633146117945760405162461bcd60e51b8152600401611294906154d1565b6113888161ffff1610156117d35760405162461bcd60e51b815260206004820152600660248201526503e3d353030360d41b6044820152606401611294565b6127108161ffff1611156118135760405162461bcd60e51b815260206004820152600760248201526603c3d31303030360cc1b6044820152606401611294565b6008805461ffff191661ffff92909216919091179055565b6000546001600160a01b031633146118555760405162461bcd60e51b8152600401611294906154d1565b600f805461ffff191661ffff92909216919091179055565b3360009081526004602052604090205460ff1661189c5760405162461bcd60e51b815260040161129490615506565b60008381526009602052604090206118b8906008018383614974565b50827f0ead99b16970b21b06560d282fb889ff21e4b0319cf089a240eb235861d9c71383836040516118eb929190615524565b60405180910390a2505050565b611902338261395e565b61191e5760405162461bcd60e51b815260040161129490615553565b6113ca838383613a51565b3360009081526004602052604090205460ff166119585760405162461bcd60e51b815260040161129490615506565b6001600160a01b0381166000818152601360209081526040808320805460ff19169055519182527f20aa4ef1fb91d08c6d77207eacda99d5bd43dcc49f5f3c3c9521192759d1723691015b60405180910390a250565b600080601e548411156119ed5760405162461bcd60e51b81526020600482015260076024820152661d1bdad95b925960ca1b6044820152606401611294565b6000848152601f60209081526040808320548352600e909152902054600f546001600160a01b039091169061271090611a2a9061ffff16866155ba565b611a3491906155ef565b915091505b9250929050565b3360009081526004602052604090205460ff16611a6f5760405162461bcd60e51b815260040161129490615506565b6008805462ff0000198116620100009182900460ff1615909102179055565b60026001541415611ae15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611294565b6002600181905554479060009061271090611b0790600160a01b900461ffff16846155ba565b611b1191906155ef565b60035490915060009061271090611b3390600160a01b900461ffff16856155ba565b611b3d91906155ef565b9050600081611b4c8486615603565b611b569190615603565b9050611bdc81306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9557600080fd5b505afa158015611ba9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcd919061561a565b6001600160a01b031690613bf1565b600254611bf2906001600160a01b031684613bf1565b600354611c08906001600160a01b031683613bf1565b5050600180555050565b6113ca83838360405180602001604052806000815250612ad4565b6000546001600160a01b03163314611c575760405162461bcd60e51b8152600401611294906154d1565b600555565b6000546001600160a01b03163314611c865760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b038116600081815260046020908152604091829020805460ff191660019081179091559151918252600080516020615d2383398151915291016119a3565b60008281526009602081905260409091200154829062010000900460ff1615611d065760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680611d3c57506000818152600a60205260409020546001600160a01b031633145b611d585760405162461bcd60e51b815260040161129490615657565b600084815260096020526040902060030154831015611d7657600080fd5b620f4240831115611d8657600080fd5b505060009182526009602052604090912060040155565b6000818152600e60205260408082205481516386d1a69f60e01b815291516001600160a01b03909116926386d1a69f926004808201939182900301818387803b158015611de957600080fd5b505af1158015611dfd573d6000803e3d6000fd5b5050505050565b60148054611e119061525f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3d9061525f565b8015611e8a5780601f10611e5f57610100808354040283529160200191611e8a565b820191906000526020600020905b815481529060010190602001808311611e6d57829003601f168201915b505050505081565b3360009081526004602052604090205460ff16611ec15760405162461bcd60e51b815260040161129490615506565b600654811115611ed057600080fd5b600755565b6000818152601960205260408120546001600160a01b0316806111875760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401611294565b60008281526009602081905260409091200154829062010000900460ff1615611f875760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680611fbd57506000818152600a60205260409020546001600160a01b031633145b611fd95760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd928601906149f8565b60008281526009602081905260409091200154829062010000900460ff16156120335760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff168061206957506000818152600a60205260409020546001600160a01b031633145b6120855760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926007909201918601906149f8565b60006001600160a01b0382166121155760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401611294565b506001600160a01b03166000908152601a602052604090205490565b6000546001600160a01b0316331461215b5760405162461bcd60e51b8152600401611294906154d1565b6121656000613d0a565b565b6000546001600160a01b031633146121915760405162461bcd60e51b8152600401611294906154d1565b6003546121ab90600160a01b900461ffff1661271061567b565b61ffff168161ffff1611156121bf57600080fd5b6121c7611a8e565b600280546001600160a01b039081166000908152600460209081526040808320805460ff19169055935493519182529290911691600080516020615d23833981519152910160405180910390a26001600160a01b038216600081815260046020908152604091829020805460ff191660019081179091559151918252600080516020615d23833981519152910160405180910390a26002805461ffff909216600160a01b026001600160b01b03199092166001600160a01b0390931692909217179055565b3360009081526004602052604090205460ff166122bb5760405162461bcd60e51b815260040161129490615506565b6001600160a01b038116600081815260136020908152604091829020805460ff1916600190811790915591519182527f20aa4ef1fb91d08c6d77207eacda99d5bd43dcc49f5f3c3c9521192759d1723691016119a3565b60116020526000908152604090208054611e119061525f565b60606018805461119c9061525f565b8261234481611ed5565b6001600160a01b0316336001600160a01b0316148061238657506000818152601f60209081526040808320548352600a9091529020546001600160a01b031633145b6123c05760405162461bcd60e51b815260206004820152600b60248201526a30b93a34b9ba27bbb732b960a91b6044820152606401611294565b816123ca57600080fd5b83336001600160a01b03167f6bf78aac9400f5646828d4ec69efbb0b134dc78f211f851d8ddf5336d6de1e2e8585604051612406929190615524565b60405180910390a350505050565b60008281526009602081905260409091200154829062010000900460ff161561244f5760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff168061248557506000818152600a60205260409020546001600160a01b031633145b6124a15760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926006909201918601906149f8565b60008381526009602081905260409091200154839062010000900460ff16156125015760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054849060ff168061253757506000818152600a60205260409020546001600160a01b031633145b6125535760405162461bcd60e51b815260040161129490615657565b600085815260096020526040902061256f906002018585614974565b505050505050565b33600090815260046020526040902054829060ff16806125ad57506000818152600a60205260409020546001600160a01b031633145b6125c95760405162461bcd60e51b815260040161129490615657565b60008260ff16116125d957600080fd5b60ff8260ff1611156125ea57600080fd5b50600091825260096020526040909120600501805460ff191660ff909216919091179055565b6000838152600a602052604090205483906001600160a01b031633146126615760405162461bcd60e51b8152602060048201526006602482015265185c9d1a5cdd60d21b6044820152606401611294565b6000848152600c6020908152604080832080546001600160a01b0319166001600160a01b03888116918217909255600d8452828520805461ffff191661ffff8916908117909155600e90945293829020549151630b44cc2360e31b8152600481019490945260248401929092521690635a26611890604401600060405180830381600087803b1580156126f357600080fd5b505af1158015612707573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03821633141561276a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401611294565b336000818152601c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008181526009602081905260409091200154819062010000900460ff16156128115760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054829060ff168061284757506000818152600a60205260409020546001600160a01b031633145b6128635760405162461bcd60e51b815260040161129490615657565b5050600090815260096020819052604090912001805462ff0000191662010000179055565b33600090815260046020526040902054819060ff16806128be57506000818152600a60205260409020546001600160a01b031633145b6128da5760405162461bcd60e51b815260040161129490615657565b50600090815260096020819052604090912001805461ff001981166101009182900460ff1615909102179055565b6000546001600160a01b031633146129325760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b0381166000818152600460209081526040808320805460ff1916905551918252600080516020615d2383398151915291016119a3565b6021602052816000526040600020818154811061298b57600080fd5b90600052602060002001600091509150505481565b3360009081526004602052604090205460ff166129cf5760405162461bcd60e51b815260040161129490615506565b600090815260096020819052604090912001805460ff19811660ff90911615179055565b6000828152600a602052604090205482906001600160a01b03163314612a445760405162461bcd60e51b8152602060048201526006602482015265185c9d1a5cdd60d21b6044820152606401611294565b6000838152600a6020908152604080832080546001600160a01b0319166001600160a01b03878116918217909255600e90935292819020549051632541519f60e01b8152600481019290925290911690632541519f90602401600060405180830381600087803b158015612ab757600080fd5b505af1158015612acb573d6000803e3d6000fd5b50505050505050565b612ade338361395e565b612afa5760405162461bcd60e51b815260040161129490615553565b612b0684848484613d5a565b50505050565b6000546001600160a01b03163314612b365760405162461bcd60e51b8152600401611294906154d1565b600090815260096020819052604090912001805462ff000019169055565b6000818152601960205260409020546060906001600160a01b0316612bd35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401611294565b60165460ff1615612c3a576000612be8613d8d565b90506000815111612c085760405180602001604052806000815250612c33565b80612c1284613d9c565b604051602001612c2392919061569e565b6040516020818303038152906040525b9392505050565b6000612c76612c4884613e99565b612c5185613f5d565b604051602001612c629291906156cd565b604051602081830303815290604052614120565b9050806040516020016111249190615723565b919050565b60106020526000908152604090208054611e119061525f565b60008281526009602081905260409091200154829062010000900460ff1615612ce25760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680612d1857506000818152600a60205260409020546001600160a01b031633145b612d345760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926001909201918601906149f8565b60085462010000900460ff1615612db2573360009081526013602052604090205460ff16612db25760405162461bcd60e51b8152600401611294906020808252600490820152630c2eae8d60e31b604082015260600190565b600554341015612df25760405162461bcd60e51b815260206004820152600b60248201526a70726f6a6563742066656560a81b6044820152606401611294565b8a612dfc57600080fd5b88612e0657600080fd5b600085118015612e195750620f42408511155b612e2257600080fd5b60068054906000612e3283615768565b90915550506006546000818152600960205260409020612e53908e8e614974565b506000818152600960205260409020612e70906001018c8c614974565b506000818152600960205260409020612e8d906002018a8a614974565b506000818152600a6020818152604080842080546001600160a01b03191633179055600b82528084208b90556009909152822060038101929092556004820188905560058201805460ff19169091179055612eec906006018686614974565b506000818152600960205260409020612f09906007018484614974565b50600081815260096020819052604090912001805462ffffff1916610100179055612f3381614285565b80336001600160a01b03167f5c140d52cf47197b4d624d765c480f3363ad0fc2ccf9115197cdfe2add9e877e8f8f604051612f6f929190615524565b60405180910390a350505050505050505050505050565b6000546001600160a01b03163314612fb05760405162461bcd60e51b8152600401611294906154d1565b6113ca60158383614974565b6000546001600160a01b03163314612fe65760405162461bcd60e51b8152600401611294906154d1565b60025461300090600160a01b900461ffff1661271061567b565b61ffff168161ffff16111561301457600080fd5b61301c611a8e565b6003805461ffff909216600160a01b026001600160b01b03199092166001600160a01b0390931692909217179055565b6000546001600160a01b031633146130765760405162461bcd60e51b8152600401611294906154d1565b6113ca60148383614974565b60158054611e119061525f565b6000546001600160a01b031633146130b95760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b03811661311e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611294565b61312781613d0a565b50565b33600090815260046020526040902054869060ff168061316057506000818152600a60205260409020546001600160a01b031633145b61317c5760405162461bcd60e51b815260040161129490615657565b6000878152601060205260409020613195908787614974565b5060008781526011602052604090206131af908585614974565b5050600095865260126020526040909520805460ff19169515159590951790945550505050565b600260015414156132295760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611294565b60026001556040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561327057600080fd5b505afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190615783565b9050600081116132e65760405162461bcd60e51b81526020600482015260096024820152686e6f20746f6b656e7360b81b6044820152606401611294565b6002546000906127109061330590600160a01b900461ffff16846155ba565b61330f91906155ef565b6003549091506000906127109061333190600160a01b900461ffff16856155ba565b61333b91906155ef565b905060008161334a8486615603565b6133549190615603565b90506133d185306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561339357600080fd5b505afa1580156133a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cb919061561a565b8361440b565b6002546001600160a01b0316158015906133eb5750600083115b15613408576002546134089086906001600160a01b03168561440b565b6003546001600160a01b0316158015906134225750600082115b1561343f5760035461343f9086906001600160a01b03168461440b565b505060018055505050565b6000546001600160a01b031633146134745760405162461bcd60e51b8152600401611294906154d1565b6016805460ff1916911515919091179055565b6000818152600b60205260409020543410156134d05760405162461bcd60e51b81526020600482015260086024820152676d696e742066656560c01b6044820152606401611294565b60008181526009602052604090206004810154600390910154106135215760405162461bcd60e51b81526020600482015260086024820152671cdbdb19081bdd5d60c21b6044820152606401611294565b6000818152600960208190526040909120015460ff168061355857506000818152600a60205260409020546001600160a01b031633145b8061357257503360009081526004602052604090205460ff165b6135ab5760405162461bcd60e51b815260206004820152600a6024820152696e6f742061637469766560b01b6044820152606401611294565b60008181526009602081905260409091200154610100900460ff1615806135e857506000818152600a60205260409020546001600160a01b031633145b8061360257503360009081526004602052604090205460ff165b6136375760405162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b6044820152606401611294565b6000601e6000815461364890615768565b9182905550600083815260096020526040812060030180549293509091829061367090615768565b91829055506000838152601f60209081526040808320879055818052808320849055868352602182528220805460018101825590835291200183905590506136b8338361445d565b6000838152600e60205260409020546136da906001600160a01b031634613bf1565b8183336001600160a01b03167f35d0381720eeb0a767201805f38d34425c787d27861d1210e5086ad17df7de038460405161371791815260200190565b60405180910390a4505050565b60008181526021602090815260409182902080548351818402810184019094528084526060939283018282801561377a57602002820191906000526020600020905b815481526020019060010190808311613766575b50505050509050919050565b33600090815260046020526040902054829060ff16806137bc57506000818152600a60205260409020546001600160a01b031633145b6137d85760405162461bcd60e51b815260040161129490615657565b506000918252600b602052604090912055565b60608161380f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613839578061382381615768565b91506138329050600a836155ef565b9150613813565b6000816001600160401b0381111561385357613853614d78565b6040519080825280601f01601f19166020018201604052801561387d576020820181803683370190505b5090505b84156138e857613892600183615603565b915061389f600a8661579c565b6138aa9060306157b0565b60f81b8183815181106138bf576138bf6157c8565b60200101906001600160f81b031916908160001a9053506138e1600a866155ef565b9450613881565b949350505050565b6000818152601b6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061392582611ed5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152601960205260408120546001600160a01b03166139d75760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401611294565b60006139e283611ed5565b9050806001600160a01b0316846001600160a01b03161480613a1d5750836001600160a01b0316613a128461121f565b6001600160a01b0316145b806138e857506001600160a01b038082166000908152601c602090815260408083209388168352929052205460ff166138e8565b826001600160a01b0316613a6482611ed5565b6001600160a01b031614613acc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401611294565b6001600160a01b038216613b2e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401611294565b613b396000826138f0565b6001600160a01b0383166000908152601a60205260408120805460019290613b62908490615603565b90915550506001600160a01b0382166000908152601a60205260408120805460019290613b909084906157b0565b909155505060008181526019602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b80471015613c415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611294565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c8e576040519150601f19603f3d011682016040523d82523d6000602084013e613c93565b606091505b50509050806113ca5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611294565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b613d65848484613a51565b613d718484848461459f565b612b065760405162461bcd60e51b8152600401611294906157de565b60606015805461119c9061525f565b606081613dc05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613dea5780613dd481615768565b9150613de39050600a836155ef565b9150613dc4565b6000816001600160401b03811115613e0457613e04614d78565b6040519080825280601f01601f191660200182016040528015613e2e576020820181803683370190505b5090505b84156138e857613e43600183615603565b9150613e50600a8661579c565b613e5b9060306157b0565b60f81b818381518110613e7057613e706157c8565b60200101906001600160f81b031916908160001a905350613e92600a866155ef565b9450613e32565b6000818152601f60205260408120546060916014613eb6836137eb565b6000868152602080526040902054613ecd906137eb565b604051602001613edf93929190615830565b60408051601f198184030181529181526000848152600960209081528282208883529080529181205492935091613f15906137eb565b600085815260096020526040902060020184613f30896146ac565b604051602001613f44959493929190615876565b60408051601f1981840301815291905295945050505050565b6000818152601f602090815260408083205483526010909152812080546060929190613f889061525f565b80601f0160208091040260200160405190810160405280929190818152602001828054613fb49061525f565b80156140015780601f10613fd657610100808354040283529160200191614001565b820191906000526020600020905b815481529060010190602001808311613fe457829003601f168201915b5050506000868152601f602090815260408083205483526011909152812080549495509093909250614033915061525f565b80601f016020809104026020016040519081016040528092919081815260200182805461405f9061525f565b80156140ac5780601f10614081576101008083540402835291602001916140ac565b820191906000526020600020905b81548152906001019060200180831161408f57829003601f168201915b50505050509050600082511180156140c5575060008151115b156140ff57816140d4856137eb565b826040516020016140e793929190615942565b60405160208183030381529060405292505050919050565b61411061410b85611071565b614120565b6040516020016140e79190615985565b805160609080614140575050604080516020810190915260008152919050565b6000600361414f8360026157b0565b61415991906155ef565b6141649060046155ba565b905060006141738260206157b0565b6001600160401b0381111561418a5761418a614d78565b6040519080825280601f01601f1916602001820160405280156141b4576020820181803683370190505b5090506000604051806060016040528060408152602001615ce3604091399050600181016020830160005b86811015614240576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016141df565b50600386066001811461425a576002811461426b57614277565b613d3d60f01b600119830152614277565b603d60f81b6000198301525b505050918152949350505050565b6000818152600e60205260409020546001600160a01b0316156143005760405162461bcd60e51b815260206004820152602d60248201527f726f79616c7479206d616e6167657220616c726561647920657869737473206660448201526c1bdc8817dc1c9bda9958dd1259609a1b6064820152608401611294565b60085460009061431f90630100000090046001600160a01b03166146ff565b6000838152600e6020908152604080832080546001600160a01b0319166001600160a01b03868116918217909255600a909352818420546008549251632546562960e21b8152306004820152602481018990529116604482015261ffff90911660648201526084810183905260a481019290925291925063951958a49060c401600060405180830381600087803b1580156143b957600080fd5b505af11580156143cd573d6000803e3d6000fd5b50506040518492506001600160a01b03841691507f429754bcf618a929bf6c4c1c01b1d381eb920cf0445093c8e7e0aa4b2af457c390600090a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113ca908490614797565b6001600160a01b0382166144b35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401611294565b6000818152601960205260409020546001600160a01b0316156145185760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611294565b6001600160a01b0382166000908152601a602052604081208054600192906145419084906157b0565b909155505060008181526019602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b156146a157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906145e39033908990889088906004016159ca565b602060405180830381600087803b1580156145fd57600080fd5b505af192505050801561462d575060408051601f3d908101601f1916820190925261462a91810190615a07565b60015b614687573d80801561465b576040519150601f19603f3d011682016040523d82523d6000602084013e614660565b606091505b50805161467f5760405162461bcd60e51b8152600401611294906157de565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506138e8565b506001949350505050565b6000818152601f6020908152604080832054808452600983528184209151606094919391926146e79290916001830191600884019101615a24565b60408051601f19818403018152919052949350505050565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b038116612c895760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b6044820152606401611294565b60006147ec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148699092919063ffffffff16565b8051909150156113ca578080602001905181019061480a9190615b26565b6113ca5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611294565b60606138e8848460008585843b6148c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611294565b600080866001600160a01b031685876040516148de9190615b43565b60006040518083038185875af1925050503d806000811461491b576040519150601f19603f3d011682016040523d82523d6000602084013e614920565b606091505b509150915061493082828661493b565b979650505050505050565b6060831561494a575081612c33565b82511561495a5782518084602001fd5b8160405162461bcd60e51b81526004016112949190614af2565b8280546149809061525f565b90600052602060002090601f0160209004810192826149a257600085556149e8565b82601f106149bb5782800160ff198235161785556149e8565b828001600101855582156149e8579182015b828111156149e85782358255916020019190600101906149cd565b506149f4929150614a6c565b5090565b828054614a049061525f565b90600052602060002090601f016020900481019282614a2657600085556149e8565b82601f10614a3f57805160ff19168380011785556149e8565b828001600101855582156149e8579182015b828111156149e8578251825591602001919060010190614a51565b5b808211156149f45760008155600101614a6d565b600060208284031215614a9357600080fd5b5035919050565b60005b83811015614ab5578181015183820152602001614a9d565b83811115612b065750506000910152565b60008151808452614ade816020860160208601614a9a565b601f01601f19169290920160200192915050565b602081526000612c336020830184614ac6565b6001600160e01b03198116811461312757600080fd5b600060208284031215614b2d57600080fd5b8135612c3381614b05565b6001600160a01b038116811461312757600080fd5b600060208284031215614b5f57600080fd5b8135612c3381614b38565b60008060408385031215614b7d57600080fd5b8235614b8881614b38565b946020939093013593505050565b61018081526000614bab61018083018f614ac6565b8281036020840152614bbd818f614ac6565b90508281036040840152614bd1818e614ac6565b90508b60608401528a6080840152614bee60a084018b60ff169052565b82810360c0840152614c00818a614ac6565b905082810360e0840152614c148189614ac6565b9050828103610100840152614c298188614ac6565b915050614c3b61012083018615159052565b921515610140820152901515610160909101529a9950505050505050505050565b803561ffff81168114612c8957600080fd5b600060208284031215614c8057600080fd5b612c3382614c5c565b60008083601f840112614c9b57600080fd5b5081356001600160401b03811115614cb257600080fd5b602083019150836020828501011115611a3957600080fd5b600080600060408486031215614cdf57600080fd5b8335925060208401356001600160401b03811115614cfc57600080fd5b614d0886828701614c89565b9497909650939450505050565b600080600060608486031215614d2a57600080fd5b8335614d3581614b38565b92506020840135614d4581614b38565b929592945050506040919091013590565b60008060408385031215614d6957600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115614da857614da8614d78565b604051601f8501601f19908116603f01168101908282118183101715614dd057614dd0614d78565b81604052809350858152868686011115614de957600080fd5b858560208301376000602087830101525050509392505050565b60008060408385031215614e1657600080fd5b8235915060208301356001600160401b03811115614e3357600080fd5b8301601f81018513614e4457600080fd5b614e5385823560208401614d8e565b9150509250929050565b60008060408385031215614e7057600080fd5b8235614e7b81614b38565b9150614e8960208401614c5c565b90509250929050565b60008060408385031215614ea557600080fd5b82359150602083013560ff81168114614ebd57600080fd5b809150509250929050565b600080600060608486031215614edd57600080fd5b833592506020840135614eef81614b38565b9150614efd60408501614c5c565b90509250925092565b801515811461312757600080fd5b60008060408385031215614f2757600080fd5b8235614f3281614b38565b91506020830135614ebd81614f06565b60008060408385031215614f5557600080fd5b823591506020830135614ebd81614b38565b60008060008060808587031215614f7d57600080fd5b8435614f8881614b38565b93506020850135614f9881614b38565b92506040850135915060608501356001600160401b03811115614fba57600080fd5b8501601f81018713614fcb57600080fd5b614fda87823560208401614d8e565b91505092959194509250565b60008060008060008060008060008060008060e08d8f03121561500857600080fd5b6001600160401b038d35111561501d57600080fd5b61502a8e8e358f01614c89565b909c509a506001600160401b0360208e0135111561504757600080fd5b6150578e60208f01358f01614c89565b909a5098506001600160401b0360408e0135111561507457600080fd5b6150848e60408f01358f01614c89565b909850965060608d0135955060808d013594506001600160401b0360a08e013511156150af57600080fd5b6150bf8e60a08f01358f01614c89565b90945092506001600160401b0360c08e013511156150dc57600080fd5b6150ec8e60c08f01358f01614c89565b81935080925050509295989b509295989b509295989b565b6000806020838503121561511757600080fd5b82356001600160401b0381111561512d57600080fd5b61513985828601614c89565b90969095509350505050565b6000806040838503121561515857600080fd5b823561516381614b38565b91506020830135614ebd81614b38565b6000806000806000806080878903121561518c57600080fd5b8635955060208701356001600160401b03808211156151aa57600080fd5b6151b68a838b01614c89565b909750955060408901359150808211156151cf57600080fd5b506151dc89828a01614c89565b90945092505060608701356151f081614f06565b809150509295509295509295565b60006020828403121561521057600080fd5b8135612c3381614f06565b6020808252825182820181905260009190848201906040850190845b8181101561525357835183529284019291840191600101615237565b50909695505050505050565b600181811c9082168061527357607f821691505b6020821081141561529457634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c90808316806152b457607f831692505b60208084108214156152d657634e487b7160e01b600052602260045260246000fd5b8180156152ea57600181146152fb57615328565b60ff19861689528489019650615328565b60008881526020902060005b868110156153205781548b820152908501908301615307565b505084890196505b50505050505092915050565b60008451615346818460208901614a9a565b6153528184018661529a565b90506201011960ed1b81528351615370816003840160208801614a9a565b0160030195945050505050565b6000835161538f818460208801614a9a565b80830190507f3c2f746578743e3c7465787420636c6173733d2265646974696f6e2220783d2281527f3530252220793d223130252220646f6d696e616e742d626173656c696e653d2260208201527f6d6964646c652220746578742d616e63686f723d226d6964646c65223e5d5b616040820152640393a1011960dd1b60608201528351615424816065840160208801614a9a565b01606501949350505050565b60008251615442818460208701614a9a565b7f3c2f746578743e3c7465787420636c6173733d22626173652220783d223530259201918252507f222079203d20223530252220646f6d696e616e742d626173656c696e653d226d60208201527f6964646c652220746578742d616e63686f723d226d6964646c65223e5d5b3c2f60408201526a3a32bc3a1f1e17b9bb339f60a91b6060820152606b01919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600490820152637465616d60e01b604082015260600190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156155d4576155d46155a4565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826155fe576155fe6155d9565b500490565b600082821015615615576156156155a4565b500390565b60006020828403121561562c57600080fd5b8151612c3381614b38565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b6020808252600a90820152696172746973745465616d60b01b604082015260600190565b600061ffff83811690831681811015615696576156966155a4565b039392505050565b600083516156b0818460208801614a9a565b8351908301906156c4818360208801614a9a565b01949350505050565b600083516156df818460208801614a9a565b6b16101134b6b0b3b2911d101160a11b908301908152835161570881600c840160208801614a9a565b61227d60f01b600c9290910191820152600e01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161575b81601d850160208701614a9a565b91909101601d0192915050565b600060001982141561577c5761577c6155a4565b5060010190565b60006020828403121561579557600080fd5b5051919050565b6000826157ab576157ab6155d9565b500690565b600082198211156157c3576157c36155a4565b500190565b634e487b7160e01b600052603260045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600061583c828661529a565b845161584c818360208901614a9a565b602f60f81b91019081528351615869816001840160208801614a9a565b0160010195945050505050565b693d913730b6b2911d101160b11b81526000615895600a83018861529a565b6201011960ed1b815286516158b1816003840160208b01614a9a565b72111610113232b9b1b934b83a34b7b7111d101160691b600392909101918201526158df601682018761529a565b731116101132bc3a32b93730b62fbab936111d101160611b8152855190915061590f816014840160208901614a9a565b6201116160ed1b601492909101918201528351615933816017840160208801614a9a565b01601701979650505050505050565b60008451615954818460208901614a9a565b845190830190615968818360208901614a9a565b845191019061597b818360208801614a9a565b0195945050505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000008152600082516159bd81601a850160208701614a9a565b91909101601a0192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906159fd90830184614ac6565b9695505050505050565b600060208284031215615a1957600080fd5b8151612c3381614b05565b6e2261747472696275746573223a205b60881b81527f7b2274726169745f74797065223a202250726f6a656374222c202276616c7565600f82015263111d101160e11b602f8201819052600090615a7e603384018761529a565b62089f4b60ea1b8082527f7b2274726169745f74797065223a2022417274697374222c202276616c7565226003830152621d101160e91b6023830152615ac7602683018861529a565b9150808252507f7b2274726169745f74797065223a202243617465676f7279222c2276616c75656003820152816023820152615b06602782018661529a565b61227d60f01b8152605d60f81b6002820152600301979650505050505050565b600060208284031215615b3857600080fd5b8151612c3381614f06565b60008251615b55818460208701614a9a565b919091019291505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e202e65646974696f6e207b2066696c6c3a20236666666666663b20666f6e742d66616d696c793a204f70656e2053616e733b20666f6e742d73697a653a20313270783b207d202e62617365207b2066696c6c3a20236666666666663b20666f6e742d66616d696c793a204f70656e2053616e733b20666f6e742d73697a653a2031383070783b207d203c2f7374796c653e203c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d222339343030443322202f3e203c7465787420636c6173733d2265646974696f6e2220783d223530252220793d2235252220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c65223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f395c8250a24c0334974196af39013f5f036bc82eb5270ee99dffe50d48455ac4a2646970667358221220fc456a27ca0a426c7859bc559500cb05254a855e0a4d1e7b8c83b60318e64cc764736f6c63430008090033608060405234801561001057600080fd5b5060018055611393806100246000396000f3fe6080604052600436106100ab5760003560e01c80635a266118116100645780635a266118146101e057806386d1a69f14610200578063951958a4146102155780639b562c5914610235578063f447566b14610257578063fc94e54e1461027957600080fd5b80632437abfa146100ec5780632541519f1461010e57806343bc16121461012e578063472cad991461016b57806351b68370146101a057806359748cb2146101c057600080fd5b366100e75760405134815233907f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be7709060200160405180910390a2005b600080fd5b3480156100f857600080fd5b5061010c610107366004611116565b61029d565b005b34801561011a57600080fd5b5061010c610129366004611116565b610585565b34801561013a57600080fd5b5060045461014e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017757600080fd5b5060055461018d90600160a01b900461ffff1681565b60405161ffff9091168152602001610162565b3480156101ac57600080fd5b5060025461014e906001600160a01b031681565b3480156101cc57600080fd5b5060055461014e906001600160a01b031681565b3480156101ec57600080fd5b5061010c6101fb36600461114a565b61068f565b34801561020c57600080fd5b5061010c6108ef565b34801561022157600080fd5b5061010c61023036600461117f565b610b12565b34801561024157600080fd5b5060055461018d90600160c01b900461ffff1681565b34801561026357600080fd5b5060055461018d90600160b01b900461ffff1681565b34801561028557600080fd5b5061028f60035481565b604051908152602001610162565b600260015414156102f55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026001556040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561033c57600080fd5b505afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037491906111f2565b9050600081116103b25760405162461bcd60e51b81526020600482015260096024820152686e6f20746f6b656e7360b81b60448201526064016102ec565b600554600090612710906103d190600160b01b900461ffff1684611221565b6103db9190611240565b600554909150600090612710906103fd90600160c01b900461ffff1685611221565b6104079190611240565b90506000816104168486611262565b6104209190611262565b60025490915061043b9086906001600160a01b031683610d42565b6002546040518281526001600160a01b03918216918716907f8bdce7585b0e3cc7225a864f2c9e8e4e08b7f89e20a5bac39917b68a0a3fb5e39060200160405180910390a36004546001600160a01b03161580159061049a5750600083115b156104fd576004546104b79086906001600160a01b031685610d42565b6004546040518481526001600160a01b03918216918716907f8bdce7585b0e3cc7225a864f2c9e8e4e08b7f89e20a5bac39917b68a0a3fb5e39060200160405180910390a35b6005546001600160a01b0316158015906105175750600082115b1561057a576005546105349086906001600160a01b031684610d42565b6005546040518381526001600160a01b03918216918716907f8bdce7585b0e3cc7225a864f2c9e8e4e08b7f89e20a5bac39917b68a0a3fb5e39060200160405180910390a35b505060018055505050565b6002546001600160a01b0316336001600160a01b031614806105ba57506004546001600160a01b0316336001600160a01b0316145b6105ef5760405162461bcd60e51b81526004016102ec906020808252600490820152630c2eae8d60e31b604082015260600190565b600454600554604051600160b01b90910461ffff1681526001600160a01b03909116907f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb9060200160405180910390a2600480546001600160a01b0319166001600160a01b038316908117909155600554604051600160b01b90910461ffff16815260008051602061133e8339815191529060200160405180910390a250565b6002546001600160a01b0316336001600160a01b031614806106c457506004546001600160a01b0316336001600160a01b0316145b6106f95760405162461bcd60e51b81526004016102ec906020808252600490820152630c2eae8d60e31b604082015260600190565b60055461ffff600160a01b9091048116908216111561074c5760405162461bcd60e51b815260206004820152600f60248201526e70657263656e7420746f6f2062696760881b60448201526064016102ec565b6107546108ef565b600454600554604051600160b01b90910461ffff1681526001600160a01b03909116907f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb9060200160405180910390a26005546001600160a01b03161561080257600554604051600160c01b820461ffff1681526001600160a01b03909116907f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb9060200160405180910390a25b6005805461ffff808416600160c01b02600165ffff0000000160a01b03199092166001600160a01b03861617919091179182905561084a918391600160a01b90910416611279565b6005805461ffff60b01b1916600160b01b61ffff938416810291909117918290556004546040519190920490921682526001600160a01b03169060008051602061133e8339815191529060200160405180910390a26005546001600160a01b0316156108eb57600554604051600160c01b820461ffff1681526001600160a01b039091169060008051602061133e8339815191529060200160405180910390a25b5050565b600260015414156109425760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102ec565b6002600155478015610b0b576005546000906127109061096d90600160b01b900461ffff1684611221565b6109779190611240565b6005549091506000906127109061099990600160c01b900461ffff1685611221565b6109a39190611240565b90506000816109b28486611262565b6109bc9190611262565b6002549091506109d5906001600160a01b031682610d99565b6002546040518281526001600160a01b03909116907fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0569060200160405180910390a26004546001600160a01b031615801590610a315750600083115b15610a8f57600454610a4c906001600160a01b031684610d99565b6004546040518481526001600160a01b03909116907fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0569060200160405180910390a25b6005546001600160a01b031615801590610aa95750600082115b15610b0757600554610ac4906001600160a01b031683610d99565b6005546040518381526001600160a01b03909116907fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0569060200160405180910390a25b5050505b5060018055565b600054610100900460ff1680610b2b575060005460ff16155b610b8e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102ec565b600054610100900460ff16158015610bb0576000805461ffff19166101011790555b600280546001600160a01b03808a166001600160a01b03199283161790925560038890556004805488841692169190911790556005805461ffff858116600160c01b02600165ffff0000000160a01b0319918916600160a01b0291909116600163ffff000160b01b03199092169190911792861692909217919091179055610c388285611279565b6005805461ffff60b01b1916600160b01b61ffff9384160217908190556002546001600160a01b03169160008051602061133e83398151915291610c8791600160a01b90910416612710611279565b60405161ffff909116815260200160405180910390a2600454600554604051600160b01b90910461ffff1681526001600160a01b039091169060008051602061133e8339815191529060200160405180910390a26005546001600160a01b031615610d2757600554604051600160c01b820461ffff1681526001600160a01b039091169060008051602061133e8339815191529060200160405180910390a25b8015610d39576000805461ff00191690555b50505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610d94908490610eb2565b505050565b80471015610de95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016102ec565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610e36576040519150601f19603f3d011682016040523d82523d6000602084013e610e3b565b606091505b5050905080610d945760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016102ec565b6000610f07826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610f849092919063ffffffff16565b805190915015610d945780806020019051810190610f25919061129c565b610d945760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102ec565b6060610f938484600085610f9d565b90505b9392505050565b606082471015610ffe5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016102ec565b843b61104c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102ec565b600080866001600160a01b0316858760405161106891906112ee565b60006040518083038185875af1925050503d80600081146110a5576040519150601f19603f3d011682016040523d82523d6000602084013e6110aa565b606091505b50915091506110ba8282866110c5565b979650505050505050565b606083156110d4575081610f96565b8251156110e45782518084602001fd5b8160405162461bcd60e51b81526004016102ec919061130a565b6001600160a01b038116811461111357600080fd5b50565b60006020828403121561112857600080fd5b8135610f96816110fe565b803561ffff8116811461114557600080fd5b919050565b6000806040838503121561115d57600080fd5b8235611168816110fe565b915061117660208401611133565b90509250929050565b60008060008060008060c0878903121561119857600080fd5b86356111a3816110fe565b95506020870135945060408701356111ba816110fe565b93506111c860608801611133565b925060808701356111d8816110fe565b91506111e660a08801611133565b90509295509295509295565b60006020828403121561120457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561123b5761123b61120b565b500290565b60008261125d57634e487b7160e01b600052601260045260246000fd5b500490565b6000828210156112745761127461120b565b500390565b600061ffff838116908316818110156112945761129461120b565b039392505050565b6000602082840312156112ae57600080fd5b81518015158114610f9657600080fd5b60005b838110156112d95781810151838201526020016112c1565b838111156112e8576000848401525b50505050565b600082516113008184602087016112be565b9190910192915050565b60208152600082518060208401526113298160408501602087016112be565b601f01601f1916919091016040019291505056fe40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905faca264697066735822122096772b62db352165086235cb24be2231481653d0ff6e366d1f6ad784e0c3411964736f6c63430008090033

Deployed Bytecode

0x6080604052600436106104ac5760003560e01c80637bd806261161026b578063cbe5b9381161014f578063e66f53b7116100c1578063f4c9d86c11610085578063f4c9d86c14610fb1578063f4f3b20014610fd1578063f85a5a9714610ff1578063fd0c459a14611011578063fd8be44f14611024578063ff29ab4e1461105157600080fd5b8063e66f53b714610eed578063e985e9c514610f0d578063ea75794614610f56578063f2fde38b14610f71578063f337968e14610f9157600080fd5b8063d7b044b611610113578063d7b044b614610e06578063d815d0b214610e3c578063dd733ea714610e68578063dfa674a014610e88578063e25edbb314610ea8578063e6545a8614610ed857600080fd5b8063cbe5b93814610d7d578063cd00c1f914610d9d578063d0dcd5a214610dbd578063d0ee265e14610dd0578063d58f2f2714610df057600080fd5b8063a47d29cb116101e8578063b72216cd116101ac578063b72216cd14610cc7578063b83a2e8e14610ce7578063b88d4fde14610d07578063c2b3b6d114610d27578063c87b56dd14610d47578063c92f695b14610d6757600080fd5b8063a47d29cb14610c11578063a83572aa14610c47578063afd9e4f314610c67578063b03c128814610c87578063b15a9a9b14610ca757600080fd5b8063990cede81161022f578063990cede814610b715780639a5f79ad14610b915780639ddcd85914610bb1578063a0e16a3a14610bd1578063a22cb46514610bf157600080fd5b80637bd8062614610ac85780638da5cb5b14610afe5780639521a42c14610b1c57806395d89b4114610b3c5780639735b4d814610b5157600080fd5b806338af3eed116103925780635c60da1b1161030f5780636eb86599116102d35780636eb8659914610a0257806370a0823114610a22578063715018a614610a425780637878707214610a5757806378fa524814610a7757806379a84bb914610a9757600080fd5b80635c60da1b146109615780635ff82791146109885780636352211e146109a8578063641d4e38146109c85780636dc78f0c146109e857600080fd5b80634624aea4116103565780634624aea4146108d157806346c94c36146108f1578063472cad9914610911578063479767731461092c5780635961d1191461094c57600080fd5b806338af3eed1461083a5780633b1c9b681461085a5780633ccfd60b1461087c57806342842e0e146108915780634529cf18146108b157600080fd5b80631a5206b91161042b57806323b872dd116103ef57806323b872dd1461077a5780632969be221461079a5780632a08313e146107b05780632a55205a146107d05780632ab4d0521461080f5780633219bdcf1461082557600080fd5b80631a5206b9146106a85780631b689c0b146106dd5780631c0970071461070a5780631cbb4e391461072a5780632290bd4c1461074a57600080fd5b8063081812fc11610472578063081812fc146105c9578063095ea7b314610601578063107046bd1461062357806316967c0b1461065b5780631a3ef1381461067b57600080fd5b806233f9ee146104fa5780629a9b7b1461053057806301ffc9a71461055457806306fdde031461058457806307b62c001461059957600080fd5b366104f5577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561050657600080fd5b5061051a610515366004614a81565b611071565b6040516105279190614af2565b60405180910390f35b34801561053c57600080fd5b50610546601e5481565b604051908152602001610527565b34801561056057600080fd5b5061057461056f366004614b1b565b61113b565b6040519015158152602001610527565b34801561059057600080fd5b5061051a61118d565b3480156105a557600080fd5b506105746105b4366004614b4d565b60046020526000908152604090205460ff1681565b3480156105d557600080fd5b506105e96105e4366004614a81565b61121f565b6040516001600160a01b039091168152602001610527565b34801561060d57600080fd5b5061062161061c366004614b6a565b6112b9565b005b34801561062f57600080fd5b5061064361063e366004614a81565b6113cf565b6040516105279c9b9a99989796959493929190614b96565b34801561066757600080fd5b50610621610676366004614c6e565b61176a565b34801561068757600080fd5b50610546610696366004614a81565b600b6020526000908152604090205481565b3480156106b457600080fd5b506002546106ca90600160a01b900461ffff1681565b60405161ffff9091168152602001610527565b3480156106e957600080fd5b506105466106f8366004614a81565b601f6020526000908152604090205481565b34801561071657600080fd5b50610621610725366004614c6e565b61182b565b34801561073657600080fd5b50610621610745366004614cca565b61186d565b34801561075657600080fd5b50610574610765366004614a81565b60126020526000908152604090205460ff1681565b34801561078657600080fd5b50610621610795366004614d15565b6118f8565b3480156107a657600080fd5b5061054660065481565b3480156107bc57600080fd5b506106216107cb366004614b4d565b611929565b3480156107dc57600080fd5b506107f06107eb366004614d56565b6119ae565b604080516001600160a01b039093168352602083019190915201610527565b34801561081b57600080fd5b50610546601d5481565b34801561083157600080fd5b50610621611a40565b34801561084657600080fd5b506003546105e9906001600160a01b031681565b34801561086657600080fd5b506003546106ca90600160a01b900461ffff1681565b34801561088857600080fd5b50610621611a8e565b34801561089d57600080fd5b506106216108ac366004614d15565b611c12565b3480156108bd57600080fd5b506106216108cc366004614a81565b611c2d565b3480156108dd57600080fd5b506106216108ec366004614b4d565b611c5c565b3480156108fd57600080fd5b5061062161090c366004614d56565b611ccb565b34801561091d57600080fd5b506008546106ca9061ffff1681565b34801561093857600080fd5b50610621610947366004614a81565b611d9d565b34801561095857600080fd5b5061051a611e04565b34801561096d57600080fd5b506008546105e990630100000090046001600160a01b031681565b34801561099457600080fd5b506106216109a3366004614a81565b611e92565b3480156109b457600080fd5b506105e96109c3366004614a81565b611ed5565b3480156109d457600080fd5b506106216109e3366004614e03565b611f4c565b3480156109f457600080fd5b506016546105749060ff1681565b348015610a0e57600080fd5b50610621610a1d366004614e03565b611ff8565b348015610a2e57600080fd5b50610546610a3d366004614b4d565b6120aa565b348015610a4e57600080fd5b50610621612131565b348015610a6357600080fd5b50610621610a72366004614e5d565b612167565b348015610a8357600080fd5b50610621610a92366004614b4d565b61228c565b348015610aa357600080fd5b506106ca610ab2366004614a81565b600d6020526000908152604090205461ffff1681565b348015610ad457600080fd5b506105e9610ae3366004614a81565b600e602052600090815260409020546001600160a01b031681565b348015610b0a57600080fd5b506000546001600160a01b03166105e9565b348015610b2857600080fd5b5061051a610b37366004614a81565b612312565b348015610b4857600080fd5b5061051a61232b565b348015610b5d57600080fd5b50610621610b6c366004614cca565b61233a565b348015610b7d57600080fd5b50610621610b8c366004614e03565b612414565b348015610b9d57600080fd5b50610621610bac366004614cca565b6124c6565b348015610bbd57600080fd5b50610621610bcc366004614e92565b612577565b348015610bdd57600080fd5b50610621610bec366004614ec8565b612610565b348015610bfd57600080fd5b50610621610c0c366004614f14565b612711565b348015610c1d57600080fd5b506105e9610c2c366004614a81565b600a602052600090815260409020546001600160a01b031681565b348015610c5357600080fd5b50610621610c62366004614a81565b6127d6565b348015610c7357600080fd5b50610621610c82366004614a81565b612888565b348015610c9357600080fd5b50610621610ca2366004614b4d565b612908565b348015610cb357600080fd5b50610546610cc2366004614d56565b61296f565b348015610cd357600080fd5b50610621610ce2366004614a81565b6129a0565b348015610cf357600080fd5b50610621610d02366004614f42565b6129f3565b348015610d1357600080fd5b50610621610d22366004614f67565b612ad4565b348015610d3357600080fd5b50610621610d42366004614a81565b612b0c565b348015610d5357600080fd5b5061051a610d62366004614a81565b612b54565b348015610d7357600080fd5b5061054660075481565b348015610d8957600080fd5b5061051a610d98366004614a81565b612c8e565b348015610da957600080fd5b50610621610db8366004614e03565b612ca7565b610621610dcb366004614fe6565b612d59565b348015610ddc57600080fd5b50610621610deb366004615104565b612f86565b348015610dfc57600080fd5b5061054660055481565b348015610e1257600080fd5b506105e9610e21366004614a81565b600c602052600090815260409020546001600160a01b031681565b348015610e4857600080fd5b50610546610e57366004614a81565b602080526000908152604090205481565b348015610e7457600080fd5b50610621610e83366004614e5d565b612fbc565b348015610e9457600080fd5b50610621610ea3366004615104565b61304c565b348015610eb457600080fd5b50610574610ec3366004614b4d565b60136020526000908152604090205460ff1681565b348015610ee457600080fd5b5061051a613082565b348015610ef957600080fd5b506002546105e9906001600160a01b031681565b348015610f1957600080fd5b50610574610f28366004615145565b6001600160a01b039182166000908152601c6020908152604080832093909416825291909152205460ff1690565b348015610f6257600080fd5b50600f546106ca9061ffff1681565b348015610f7d57600080fd5b50610621610f8c366004614b4d565b61308f565b348015610f9d57600080fd5b506008546105749062010000900460ff1681565b348015610fbd57600080fd5b50610621610fcc366004615173565b61312a565b348015610fdd57600080fd5b50610621610fec366004614b4d565b6131d6565b348015610ffd57600080fd5b5061062161100c3660046151fe565b61344a565b61062161101f366004614a81565b613487565b34801561103057600080fd5b5061104461103f366004614a81565b613724565b604051610527919061521b565b34801561105d57600080fd5b5061062161106c366004614d56565b613786565b60606000604051806101c001604052806101838152602001615b6061018391396000848152601f60209081526040808320548352600982528083208784529180529091205491925082916110c4906137eb565b6040516020016110d693929190615334565b6040516020818303038152906040529050806110f1846137eb565b60405160200161110292919061537d565b6040516020818303038152906040529050806040516020016111249190615430565b60408051601f198184030181529190529392505050565b60006001600160e01b031982166380ac58cd60e01b148061116c57506001600160e01b03198216635b5e139f60e01b145b8061118757506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606017805461119c9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546111c89061525f565b80156112155780601f106111ea57610100808354040283529160200191611215565b820191906000526020600020905b8154815290600101906020018083116111f857829003601f168201915b5050505050905090565b6000818152601960205260408120546001600160a01b031661129d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152601b60205260409020546001600160a01b031690565b60006112c482611ed5565b9050806001600160a01b0316836001600160a01b031614156113325760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401611294565b336001600160a01b038216148061134e575061134e8133610f28565b6113c05760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401611294565b6113ca83836138f0565b505050565b6009602052600090815260409020805481906113ea9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546114169061525f565b80156114635780601f1061143857610100808354040283529160200191611463565b820191906000526020600020905b81548152906001019060200180831161144657829003601f168201915b5050505050908060010180546114789061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546114a49061525f565b80156114f15780601f106114c6576101008083540402835291602001916114f1565b820191906000526020600020905b8154815290600101906020018083116114d457829003601f168201915b5050505050908060020180546115069061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546115329061525f565b801561157f5780601f106115545761010080835404028352916020019161157f565b820191906000526020600020905b81548152906001019060200180831161156257829003601f168201915b5050506003840154600485015460058601546006870180549697939692955060ff9091169350906115af9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546115db9061525f565b80156116285780601f106115fd57610100808354040283529160200191611628565b820191906000526020600020905b81548152906001019060200180831161160b57829003601f168201915b50505050509080600701805461163d9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546116699061525f565b80156116b65780601f1061168b576101008083540402835291602001916116b6565b820191906000526020600020905b81548152906001019060200180831161169957829003601f168201915b5050505050908060080180546116cb9061525f565b80601f01602080910402602001604051908101604052809291908181526020018280546116f79061525f565b80156117445780601f1061171957610100808354040283529160200191611744565b820191906000526020600020905b81548152906001019060200180831161172757829003601f168201915b5050506009909301549192505060ff80821691610100810482169162010000909104168c565b6000546001600160a01b031633146117945760405162461bcd60e51b8152600401611294906154d1565b6113888161ffff1610156117d35760405162461bcd60e51b815260206004820152600660248201526503e3d353030360d41b6044820152606401611294565b6127108161ffff1611156118135760405162461bcd60e51b815260206004820152600760248201526603c3d31303030360cc1b6044820152606401611294565b6008805461ffff191661ffff92909216919091179055565b6000546001600160a01b031633146118555760405162461bcd60e51b8152600401611294906154d1565b600f805461ffff191661ffff92909216919091179055565b3360009081526004602052604090205460ff1661189c5760405162461bcd60e51b815260040161129490615506565b60008381526009602052604090206118b8906008018383614974565b50827f0ead99b16970b21b06560d282fb889ff21e4b0319cf089a240eb235861d9c71383836040516118eb929190615524565b60405180910390a2505050565b611902338261395e565b61191e5760405162461bcd60e51b815260040161129490615553565b6113ca838383613a51565b3360009081526004602052604090205460ff166119585760405162461bcd60e51b815260040161129490615506565b6001600160a01b0381166000818152601360209081526040808320805460ff19169055519182527f20aa4ef1fb91d08c6d77207eacda99d5bd43dcc49f5f3c3c9521192759d1723691015b60405180910390a250565b600080601e548411156119ed5760405162461bcd60e51b81526020600482015260076024820152661d1bdad95b925960ca1b6044820152606401611294565b6000848152601f60209081526040808320548352600e909152902054600f546001600160a01b039091169061271090611a2a9061ffff16866155ba565b611a3491906155ef565b915091505b9250929050565b3360009081526004602052604090205460ff16611a6f5760405162461bcd60e51b815260040161129490615506565b6008805462ff0000198116620100009182900460ff1615909102179055565b60026001541415611ae15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611294565b6002600181905554479060009061271090611b0790600160a01b900461ffff16846155ba565b611b1191906155ef565b60035490915060009061271090611b3390600160a01b900461ffff16856155ba565b611b3d91906155ef565b9050600081611b4c8486615603565b611b569190615603565b9050611bdc81306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9557600080fd5b505afa158015611ba9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcd919061561a565b6001600160a01b031690613bf1565b600254611bf2906001600160a01b031684613bf1565b600354611c08906001600160a01b031683613bf1565b5050600180555050565b6113ca83838360405180602001604052806000815250612ad4565b6000546001600160a01b03163314611c575760405162461bcd60e51b8152600401611294906154d1565b600555565b6000546001600160a01b03163314611c865760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b038116600081815260046020908152604091829020805460ff191660019081179091559151918252600080516020615d2383398151915291016119a3565b60008281526009602081905260409091200154829062010000900460ff1615611d065760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680611d3c57506000818152600a60205260409020546001600160a01b031633145b611d585760405162461bcd60e51b815260040161129490615657565b600084815260096020526040902060030154831015611d7657600080fd5b620f4240831115611d8657600080fd5b505060009182526009602052604090912060040155565b6000818152600e60205260408082205481516386d1a69f60e01b815291516001600160a01b03909116926386d1a69f926004808201939182900301818387803b158015611de957600080fd5b505af1158015611dfd573d6000803e3d6000fd5b5050505050565b60148054611e119061525f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3d9061525f565b8015611e8a5780601f10611e5f57610100808354040283529160200191611e8a565b820191906000526020600020905b815481529060010190602001808311611e6d57829003601f168201915b505050505081565b3360009081526004602052604090205460ff16611ec15760405162461bcd60e51b815260040161129490615506565b600654811115611ed057600080fd5b600755565b6000818152601960205260408120546001600160a01b0316806111875760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401611294565b60008281526009602081905260409091200154829062010000900460ff1615611f875760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680611fbd57506000818152600a60205260409020546001600160a01b031633145b611fd95760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd928601906149f8565b60008281526009602081905260409091200154829062010000900460ff16156120335760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff168061206957506000818152600a60205260409020546001600160a01b031633145b6120855760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926007909201918601906149f8565b60006001600160a01b0382166121155760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401611294565b506001600160a01b03166000908152601a602052604090205490565b6000546001600160a01b0316331461215b5760405162461bcd60e51b8152600401611294906154d1565b6121656000613d0a565b565b6000546001600160a01b031633146121915760405162461bcd60e51b8152600401611294906154d1565b6003546121ab90600160a01b900461ffff1661271061567b565b61ffff168161ffff1611156121bf57600080fd5b6121c7611a8e565b600280546001600160a01b039081166000908152600460209081526040808320805460ff19169055935493519182529290911691600080516020615d23833981519152910160405180910390a26001600160a01b038216600081815260046020908152604091829020805460ff191660019081179091559151918252600080516020615d23833981519152910160405180910390a26002805461ffff909216600160a01b026001600160b01b03199092166001600160a01b0390931692909217179055565b3360009081526004602052604090205460ff166122bb5760405162461bcd60e51b815260040161129490615506565b6001600160a01b038116600081815260136020908152604091829020805460ff1916600190811790915591519182527f20aa4ef1fb91d08c6d77207eacda99d5bd43dcc49f5f3c3c9521192759d1723691016119a3565b60116020526000908152604090208054611e119061525f565b60606018805461119c9061525f565b8261234481611ed5565b6001600160a01b0316336001600160a01b0316148061238657506000818152601f60209081526040808320548352600a9091529020546001600160a01b031633145b6123c05760405162461bcd60e51b815260206004820152600b60248201526a30b93a34b9ba27bbb732b960a91b6044820152606401611294565b816123ca57600080fd5b83336001600160a01b03167f6bf78aac9400f5646828d4ec69efbb0b134dc78f211f851d8ddf5336d6de1e2e8585604051612406929190615524565b60405180910390a350505050565b60008281526009602081905260409091200154829062010000900460ff161561244f5760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff168061248557506000818152600a60205260409020546001600160a01b031633145b6124a15760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926006909201918601906149f8565b60008381526009602081905260409091200154839062010000900460ff16156125015760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054849060ff168061253757506000818152600a60205260409020546001600160a01b031633145b6125535760405162461bcd60e51b815260040161129490615657565b600085815260096020526040902061256f906002018585614974565b505050505050565b33600090815260046020526040902054829060ff16806125ad57506000818152600a60205260409020546001600160a01b031633145b6125c95760405162461bcd60e51b815260040161129490615657565b60008260ff16116125d957600080fd5b60ff8260ff1611156125ea57600080fd5b50600091825260096020526040909120600501805460ff191660ff909216919091179055565b6000838152600a602052604090205483906001600160a01b031633146126615760405162461bcd60e51b8152602060048201526006602482015265185c9d1a5cdd60d21b6044820152606401611294565b6000848152600c6020908152604080832080546001600160a01b0319166001600160a01b03888116918217909255600d8452828520805461ffff191661ffff8916908117909155600e90945293829020549151630b44cc2360e31b8152600481019490945260248401929092521690635a26611890604401600060405180830381600087803b1580156126f357600080fd5b505af1158015612707573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03821633141561276a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401611294565b336000818152601c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008181526009602081905260409091200154819062010000900460ff16156128115760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054829060ff168061284757506000818152600a60205260409020546001600160a01b031633145b6128635760405162461bcd60e51b815260040161129490615657565b5050600090815260096020819052604090912001805462ff0000191662010000179055565b33600090815260046020526040902054819060ff16806128be57506000818152600a60205260409020546001600160a01b031633145b6128da5760405162461bcd60e51b815260040161129490615657565b50600090815260096020819052604090912001805461ff001981166101009182900460ff1615909102179055565b6000546001600160a01b031633146129325760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b0381166000818152600460209081526040808320805460ff1916905551918252600080516020615d2383398151915291016119a3565b6021602052816000526040600020818154811061298b57600080fd5b90600052602060002001600091509150505481565b3360009081526004602052604090205460ff166129cf5760405162461bcd60e51b815260040161129490615506565b600090815260096020819052604090912001805460ff19811660ff90911615179055565b6000828152600a602052604090205482906001600160a01b03163314612a445760405162461bcd60e51b8152602060048201526006602482015265185c9d1a5cdd60d21b6044820152606401611294565b6000838152600a6020908152604080832080546001600160a01b0319166001600160a01b03878116918217909255600e90935292819020549051632541519f60e01b8152600481019290925290911690632541519f90602401600060405180830381600087803b158015612ab757600080fd5b505af1158015612acb573d6000803e3d6000fd5b50505050505050565b612ade338361395e565b612afa5760405162461bcd60e51b815260040161129490615553565b612b0684848484613d5a565b50505050565b6000546001600160a01b03163314612b365760405162461bcd60e51b8152600401611294906154d1565b600090815260096020819052604090912001805462ff000019169055565b6000818152601960205260409020546060906001600160a01b0316612bd35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401611294565b60165460ff1615612c3a576000612be8613d8d565b90506000815111612c085760405180602001604052806000815250612c33565b80612c1284613d9c565b604051602001612c2392919061569e565b6040516020818303038152906040525b9392505050565b6000612c76612c4884613e99565b612c5185613f5d565b604051602001612c629291906156cd565b604051602081830303815290604052614120565b9050806040516020016111249190615723565b919050565b60106020526000908152604090208054611e119061525f565b60008281526009602081905260409091200154829062010000900460ff1615612ce25760405162461bcd60e51b815260040161129490615637565b33600090815260046020526040902054839060ff1680612d1857506000818152600a60205260409020546001600160a01b031633145b612d345760405162461bcd60e51b815260040161129490615657565b60008481526009602090815260409091208451611dfd926001909201918601906149f8565b60085462010000900460ff1615612db2573360009081526013602052604090205460ff16612db25760405162461bcd60e51b8152600401611294906020808252600490820152630c2eae8d60e31b604082015260600190565b600554341015612df25760405162461bcd60e51b815260206004820152600b60248201526a70726f6a6563742066656560a81b6044820152606401611294565b8a612dfc57600080fd5b88612e0657600080fd5b600085118015612e195750620f42408511155b612e2257600080fd5b60068054906000612e3283615768565b90915550506006546000818152600960205260409020612e53908e8e614974565b506000818152600960205260409020612e70906001018c8c614974565b506000818152600960205260409020612e8d906002018a8a614974565b506000818152600a6020818152604080842080546001600160a01b03191633179055600b82528084208b90556009909152822060038101929092556004820188905560058201805460ff19169091179055612eec906006018686614974565b506000818152600960205260409020612f09906007018484614974565b50600081815260096020819052604090912001805462ffffff1916610100179055612f3381614285565b80336001600160a01b03167f5c140d52cf47197b4d624d765c480f3363ad0fc2ccf9115197cdfe2add9e877e8f8f604051612f6f929190615524565b60405180910390a350505050505050505050505050565b6000546001600160a01b03163314612fb05760405162461bcd60e51b8152600401611294906154d1565b6113ca60158383614974565b6000546001600160a01b03163314612fe65760405162461bcd60e51b8152600401611294906154d1565b60025461300090600160a01b900461ffff1661271061567b565b61ffff168161ffff16111561301457600080fd5b61301c611a8e565b6003805461ffff909216600160a01b026001600160b01b03199092166001600160a01b0390931692909217179055565b6000546001600160a01b031633146130765760405162461bcd60e51b8152600401611294906154d1565b6113ca60148383614974565b60158054611e119061525f565b6000546001600160a01b031633146130b95760405162461bcd60e51b8152600401611294906154d1565b6001600160a01b03811661311e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611294565b61312781613d0a565b50565b33600090815260046020526040902054869060ff168061316057506000818152600a60205260409020546001600160a01b031633145b61317c5760405162461bcd60e51b815260040161129490615657565b6000878152601060205260409020613195908787614974565b5060008781526011602052604090206131af908585614974565b5050600095865260126020526040909520805460ff19169515159590951790945550505050565b600260015414156132295760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611294565b60026001556040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561327057600080fd5b505afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190615783565b9050600081116132e65760405162461bcd60e51b81526020600482015260096024820152686e6f20746f6b656e7360b81b6044820152606401611294565b6002546000906127109061330590600160a01b900461ffff16846155ba565b61330f91906155ef565b6003549091506000906127109061333190600160a01b900461ffff16856155ba565b61333b91906155ef565b905060008161334a8486615603565b6133549190615603565b90506133d185306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561339357600080fd5b505afa1580156133a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cb919061561a565b8361440b565b6002546001600160a01b0316158015906133eb5750600083115b15613408576002546134089086906001600160a01b03168561440b565b6003546001600160a01b0316158015906134225750600082115b1561343f5760035461343f9086906001600160a01b03168461440b565b505060018055505050565b6000546001600160a01b031633146134745760405162461bcd60e51b8152600401611294906154d1565b6016805460ff1916911515919091179055565b6000818152600b60205260409020543410156134d05760405162461bcd60e51b81526020600482015260086024820152676d696e742066656560c01b6044820152606401611294565b60008181526009602052604090206004810154600390910154106135215760405162461bcd60e51b81526020600482015260086024820152671cdbdb19081bdd5d60c21b6044820152606401611294565b6000818152600960208190526040909120015460ff168061355857506000818152600a60205260409020546001600160a01b031633145b8061357257503360009081526004602052604090205460ff165b6135ab5760405162461bcd60e51b815260206004820152600a6024820152696e6f742061637469766560b01b6044820152606401611294565b60008181526009602081905260409091200154610100900460ff1615806135e857506000818152600a60205260409020546001600160a01b031633145b8061360257503360009081526004602052604090205460ff165b6136375760405162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b6044820152606401611294565b6000601e6000815461364890615768565b9182905550600083815260096020526040812060030180549293509091829061367090615768565b91829055506000838152601f60209081526040808320879055818052808320849055868352602182528220805460018101825590835291200183905590506136b8338361445d565b6000838152600e60205260409020546136da906001600160a01b031634613bf1565b8183336001600160a01b03167f35d0381720eeb0a767201805f38d34425c787d27861d1210e5086ad17df7de038460405161371791815260200190565b60405180910390a4505050565b60008181526021602090815260409182902080548351818402810184019094528084526060939283018282801561377a57602002820191906000526020600020905b815481526020019060010190808311613766575b50505050509050919050565b33600090815260046020526040902054829060ff16806137bc57506000818152600a60205260409020546001600160a01b031633145b6137d85760405162461bcd60e51b815260040161129490615657565b506000918252600b602052604090912055565b60608161380f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613839578061382381615768565b91506138329050600a836155ef565b9150613813565b6000816001600160401b0381111561385357613853614d78565b6040519080825280601f01601f19166020018201604052801561387d576020820181803683370190505b5090505b84156138e857613892600183615603565b915061389f600a8661579c565b6138aa9060306157b0565b60f81b8183815181106138bf576138bf6157c8565b60200101906001600160f81b031916908160001a9053506138e1600a866155ef565b9450613881565b949350505050565b6000818152601b6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061392582611ed5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152601960205260408120546001600160a01b03166139d75760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401611294565b60006139e283611ed5565b9050806001600160a01b0316846001600160a01b03161480613a1d5750836001600160a01b0316613a128461121f565b6001600160a01b0316145b806138e857506001600160a01b038082166000908152601c602090815260408083209388168352929052205460ff166138e8565b826001600160a01b0316613a6482611ed5565b6001600160a01b031614613acc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401611294565b6001600160a01b038216613b2e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401611294565b613b396000826138f0565b6001600160a01b0383166000908152601a60205260408120805460019290613b62908490615603565b90915550506001600160a01b0382166000908152601a60205260408120805460019290613b909084906157b0565b909155505060008181526019602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b80471015613c415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611294565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c8e576040519150601f19603f3d011682016040523d82523d6000602084013e613c93565b606091505b50509050806113ca5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611294565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b613d65848484613a51565b613d718484848461459f565b612b065760405162461bcd60e51b8152600401611294906157de565b60606015805461119c9061525f565b606081613dc05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613dea5780613dd481615768565b9150613de39050600a836155ef565b9150613dc4565b6000816001600160401b03811115613e0457613e04614d78565b6040519080825280601f01601f191660200182016040528015613e2e576020820181803683370190505b5090505b84156138e857613e43600183615603565b9150613e50600a8661579c565b613e5b9060306157b0565b60f81b818381518110613e7057613e706157c8565b60200101906001600160f81b031916908160001a905350613e92600a866155ef565b9450613e32565b6000818152601f60205260408120546060916014613eb6836137eb565b6000868152602080526040902054613ecd906137eb565b604051602001613edf93929190615830565b60408051601f198184030181529181526000848152600960209081528282208883529080529181205492935091613f15906137eb565b600085815260096020526040902060020184613f30896146ac565b604051602001613f44959493929190615876565b60408051601f1981840301815291905295945050505050565b6000818152601f602090815260408083205483526010909152812080546060929190613f889061525f565b80601f0160208091040260200160405190810160405280929190818152602001828054613fb49061525f565b80156140015780601f10613fd657610100808354040283529160200191614001565b820191906000526020600020905b815481529060010190602001808311613fe457829003601f168201915b5050506000868152601f602090815260408083205483526011909152812080549495509093909250614033915061525f565b80601f016020809104026020016040519081016040528092919081815260200182805461405f9061525f565b80156140ac5780601f10614081576101008083540402835291602001916140ac565b820191906000526020600020905b81548152906001019060200180831161408f57829003601f168201915b50505050509050600082511180156140c5575060008151115b156140ff57816140d4856137eb565b826040516020016140e793929190615942565b60405160208183030381529060405292505050919050565b61411061410b85611071565b614120565b6040516020016140e79190615985565b805160609080614140575050604080516020810190915260008152919050565b6000600361414f8360026157b0565b61415991906155ef565b6141649060046155ba565b905060006141738260206157b0565b6001600160401b0381111561418a5761418a614d78565b6040519080825280601f01601f1916602001820160405280156141b4576020820181803683370190505b5090506000604051806060016040528060408152602001615ce3604091399050600181016020830160005b86811015614240576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016141df565b50600386066001811461425a576002811461426b57614277565b613d3d60f01b600119830152614277565b603d60f81b6000198301525b505050918152949350505050565b6000818152600e60205260409020546001600160a01b0316156143005760405162461bcd60e51b815260206004820152602d60248201527f726f79616c7479206d616e6167657220616c726561647920657869737473206660448201526c1bdc8817dc1c9bda9958dd1259609a1b6064820152608401611294565b60085460009061431f90630100000090046001600160a01b03166146ff565b6000838152600e6020908152604080832080546001600160a01b0319166001600160a01b03868116918217909255600a909352818420546008549251632546562960e21b8152306004820152602481018990529116604482015261ffff90911660648201526084810183905260a481019290925291925063951958a49060c401600060405180830381600087803b1580156143b957600080fd5b505af11580156143cd573d6000803e3d6000fd5b50506040518492506001600160a01b03841691507f429754bcf618a929bf6c4c1c01b1d381eb920cf0445093c8e7e0aa4b2af457c390600090a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113ca908490614797565b6001600160a01b0382166144b35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401611294565b6000818152601960205260409020546001600160a01b0316156145185760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611294565b6001600160a01b0382166000908152601a602052604081208054600192906145419084906157b0565b909155505060008181526019602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b156146a157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906145e39033908990889088906004016159ca565b602060405180830381600087803b1580156145fd57600080fd5b505af192505050801561462d575060408051601f3d908101601f1916820190925261462a91810190615a07565b60015b614687573d80801561465b576040519150601f19603f3d011682016040523d82523d6000602084013e614660565b606091505b50805161467f5760405162461bcd60e51b8152600401611294906157de565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506138e8565b506001949350505050565b6000818152601f6020908152604080832054808452600983528184209151606094919391926146e79290916001830191600884019101615a24565b60408051601f19818403018152919052949350505050565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b038116612c895760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b6044820152606401611294565b60006147ec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148699092919063ffffffff16565b8051909150156113ca578080602001905181019061480a9190615b26565b6113ca5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611294565b60606138e8848460008585843b6148c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611294565b600080866001600160a01b031685876040516148de9190615b43565b60006040518083038185875af1925050503d806000811461491b576040519150601f19603f3d011682016040523d82523d6000602084013e614920565b606091505b509150915061493082828661493b565b979650505050505050565b6060831561494a575081612c33565b82511561495a5782518084602001fd5b8160405162461bcd60e51b81526004016112949190614af2565b8280546149809061525f565b90600052602060002090601f0160209004810192826149a257600085556149e8565b82601f106149bb5782800160ff198235161785556149e8565b828001600101855582156149e8579182015b828111156149e85782358255916020019190600101906149cd565b506149f4929150614a6c565b5090565b828054614a049061525f565b90600052602060002090601f016020900481019282614a2657600085556149e8565b82601f10614a3f57805160ff19168380011785556149e8565b828001600101855582156149e8579182015b828111156149e8578251825591602001919060010190614a51565b5b808211156149f45760008155600101614a6d565b600060208284031215614a9357600080fd5b5035919050565b60005b83811015614ab5578181015183820152602001614a9d565b83811115612b065750506000910152565b60008151808452614ade816020860160208601614a9a565b601f01601f19169290920160200192915050565b602081526000612c336020830184614ac6565b6001600160e01b03198116811461312757600080fd5b600060208284031215614b2d57600080fd5b8135612c3381614b05565b6001600160a01b038116811461312757600080fd5b600060208284031215614b5f57600080fd5b8135612c3381614b38565b60008060408385031215614b7d57600080fd5b8235614b8881614b38565b946020939093013593505050565b61018081526000614bab61018083018f614ac6565b8281036020840152614bbd818f614ac6565b90508281036040840152614bd1818e614ac6565b90508b60608401528a6080840152614bee60a084018b60ff169052565b82810360c0840152614c00818a614ac6565b905082810360e0840152614c148189614ac6565b9050828103610100840152614c298188614ac6565b915050614c3b61012083018615159052565b921515610140820152901515610160909101529a9950505050505050505050565b803561ffff81168114612c8957600080fd5b600060208284031215614c8057600080fd5b612c3382614c5c565b60008083601f840112614c9b57600080fd5b5081356001600160401b03811115614cb257600080fd5b602083019150836020828501011115611a3957600080fd5b600080600060408486031215614cdf57600080fd5b8335925060208401356001600160401b03811115614cfc57600080fd5b614d0886828701614c89565b9497909650939450505050565b600080600060608486031215614d2a57600080fd5b8335614d3581614b38565b92506020840135614d4581614b38565b929592945050506040919091013590565b60008060408385031215614d6957600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115614da857614da8614d78565b604051601f8501601f19908116603f01168101908282118183101715614dd057614dd0614d78565b81604052809350858152868686011115614de957600080fd5b858560208301376000602087830101525050509392505050565b60008060408385031215614e1657600080fd5b8235915060208301356001600160401b03811115614e3357600080fd5b8301601f81018513614e4457600080fd5b614e5385823560208401614d8e565b9150509250929050565b60008060408385031215614e7057600080fd5b8235614e7b81614b38565b9150614e8960208401614c5c565b90509250929050565b60008060408385031215614ea557600080fd5b82359150602083013560ff81168114614ebd57600080fd5b809150509250929050565b600080600060608486031215614edd57600080fd5b833592506020840135614eef81614b38565b9150614efd60408501614c5c565b90509250925092565b801515811461312757600080fd5b60008060408385031215614f2757600080fd5b8235614f3281614b38565b91506020830135614ebd81614f06565b60008060408385031215614f5557600080fd5b823591506020830135614ebd81614b38565b60008060008060808587031215614f7d57600080fd5b8435614f8881614b38565b93506020850135614f9881614b38565b92506040850135915060608501356001600160401b03811115614fba57600080fd5b8501601f81018713614fcb57600080fd5b614fda87823560208401614d8e565b91505092959194509250565b60008060008060008060008060008060008060e08d8f03121561500857600080fd5b6001600160401b038d35111561501d57600080fd5b61502a8e8e358f01614c89565b909c509a506001600160401b0360208e0135111561504757600080fd5b6150578e60208f01358f01614c89565b909a5098506001600160401b0360408e0135111561507457600080fd5b6150848e60408f01358f01614c89565b909850965060608d0135955060808d013594506001600160401b0360a08e013511156150af57600080fd5b6150bf8e60a08f01358f01614c89565b90945092506001600160401b0360c08e013511156150dc57600080fd5b6150ec8e60c08f01358f01614c89565b81935080925050509295989b509295989b509295989b565b6000806020838503121561511757600080fd5b82356001600160401b0381111561512d57600080fd5b61513985828601614c89565b90969095509350505050565b6000806040838503121561515857600080fd5b823561516381614b38565b91506020830135614ebd81614b38565b6000806000806000806080878903121561518c57600080fd5b8635955060208701356001600160401b03808211156151aa57600080fd5b6151b68a838b01614c89565b909750955060408901359150808211156151cf57600080fd5b506151dc89828a01614c89565b90945092505060608701356151f081614f06565b809150509295509295509295565b60006020828403121561521057600080fd5b8135612c3381614f06565b6020808252825182820181905260009190848201906040850190845b8181101561525357835183529284019291840191600101615237565b50909695505050505050565b600181811c9082168061527357607f821691505b6020821081141561529457634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c90808316806152b457607f831692505b60208084108214156152d657634e487b7160e01b600052602260045260246000fd5b8180156152ea57600181146152fb57615328565b60ff19861689528489019650615328565b60008881526020902060005b868110156153205781548b820152908501908301615307565b505084890196505b50505050505092915050565b60008451615346818460208901614a9a565b6153528184018661529a565b90506201011960ed1b81528351615370816003840160208801614a9a565b0160030195945050505050565b6000835161538f818460208801614a9a565b80830190507f3c2f746578743e3c7465787420636c6173733d2265646974696f6e2220783d2281527f3530252220793d223130252220646f6d696e616e742d626173656c696e653d2260208201527f6d6964646c652220746578742d616e63686f723d226d6964646c65223e5d5b616040820152640393a1011960dd1b60608201528351615424816065840160208801614a9a565b01606501949350505050565b60008251615442818460208701614a9a565b7f3c2f746578743e3c7465787420636c6173733d22626173652220783d223530259201918252507f222079203d20223530252220646f6d696e616e742d626173656c696e653d226d60208201527f6964646c652220746578742d616e63686f723d226d6964646c65223e5d5b3c2f60408201526a3a32bc3a1f1e17b9bb339f60a91b6060820152606b01919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600490820152637465616d60e01b604082015260600190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156155d4576155d46155a4565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826155fe576155fe6155d9565b500490565b600082821015615615576156156155a4565b500390565b60006020828403121561562c57600080fd5b8151612c3381614b38565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b6020808252600a90820152696172746973745465616d60b01b604082015260600190565b600061ffff83811690831681811015615696576156966155a4565b039392505050565b600083516156b0818460208801614a9a565b8351908301906156c4818360208801614a9a565b01949350505050565b600083516156df818460208801614a9a565b6b16101134b6b0b3b2911d101160a11b908301908152835161570881600c840160208801614a9a565b61227d60f01b600c9290910191820152600e01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161575b81601d850160208701614a9a565b91909101601d0192915050565b600060001982141561577c5761577c6155a4565b5060010190565b60006020828403121561579557600080fd5b5051919050565b6000826157ab576157ab6155d9565b500690565b600082198211156157c3576157c36155a4565b500190565b634e487b7160e01b600052603260045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600061583c828661529a565b845161584c818360208901614a9a565b602f60f81b91019081528351615869816001840160208801614a9a565b0160010195945050505050565b693d913730b6b2911d101160b11b81526000615895600a83018861529a565b6201011960ed1b815286516158b1816003840160208b01614a9a565b72111610113232b9b1b934b83a34b7b7111d101160691b600392909101918201526158df601682018761529a565b731116101132bc3a32b93730b62fbab936111d101160611b8152855190915061590f816014840160208901614a9a565b6201116160ed1b601492909101918201528351615933816017840160208801614a9a565b01601701979650505050505050565b60008451615954818460208901614a9a565b845190830190615968818360208901614a9a565b845191019061597b818360208801614a9a565b0195945050505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000008152600082516159bd81601a850160208701614a9a565b91909101601a0192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906159fd90830184614ac6565b9695505050505050565b600060208284031215615a1957600080fd5b8151612c3381614b05565b6e2261747472696275746573223a205b60881b81527f7b2274726169745f74797065223a202250726f6a656374222c202276616c7565600f82015263111d101160e11b602f8201819052600090615a7e603384018761529a565b62089f4b60ea1b8082527f7b2274726169745f74797065223a2022417274697374222c202276616c7565226003830152621d101160e91b6023830152615ac7602683018861529a565b9150808252507f7b2274726169745f74797065223a202243617465676f7279222c2276616c75656003820152816023820152615b06602782018661529a565b61227d60f01b8152605d60f81b6002820152600301979650505050505050565b600060208284031215615b3857600080fd5b8151612c3381614f06565b60008251615b55818460208701614a9a565b919091019291505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e202e65646974696f6e207b2066696c6c3a20236666666666663b20666f6e742d66616d696c793a204f70656e2053616e733b20666f6e742d73697a653a20313270783b207d202e62617365207b2066696c6c3a20236666666666663b20666f6e742d66616d696c793a204f70656e2053616e733b20666f6e742d73697a653a2031383070783b207d203c2f7374796c653e203c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d222339343030443322202f3e203c7465787420636c6173733d2265646974696f6e2220783d223530252220793d2235252220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c65223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f395c8250a24c0334974196af39013f5f036bc82eb5270ee99dffe50d48455ac4a2646970667358221220fc456a27ca0a426c7859bc559500cb05254a855e0a4d1e7b8c83b60318e64cc764736f6c63430008090033

Deployed Bytecode Sourcemap

27216:11204:11:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29337:40;666:10:2;29337:40:11;;;-1:-1:-1;;;;;206:32:18;;;188:51;;29367:9:11;270:2:18;255:18;;248:34;161:18;29337:40:11;;;;;;;27216:11204;;;;;31679:1007;;;;;;;;;;-1:-1:-1;31679:1007:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27576:29;;;;;;;;;;;;;;;;;;;1375:25:18;;;1363:2;1348:18;27576:29:11;1229:177:18;1431:300:4;;;;;;;;;;-1:-1:-1;1431:300:4;;;;;:::i;:::-;;:::i;:::-;;;2058:14:18;;2051:22;2033:41;;2021:2;2006:18;1431:300:4;1893:187:18;2349:98:4;;;;;;;;;;;;;:::i;2764:44:11:-;;;;;;;;;;-1:-1:-1;2764:44:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;3860:217:4;;;;;;;;;;-1:-1:-1;3860:217:4;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2637:32:18;;;2619:51;;2607:2;2592:18;3860:217:4;2473:203:18;3398:401:4;;;;;;;;;;-1:-1:-1;3398:401:4;;;;;:::i;:::-;;:::i;:::-;;8884:43:11;;;;;;;;;;-1:-1:-1;8884:43:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;12810:296::-;;;;;;;;;;-1:-1:-1;12810:296:11;;;;;:::i;:::-;;:::i;9067:66::-;;;;;;;;;;-1:-1:-1;9067:66:11;;;;;:::i;:::-;;;;;;;;;;;;;;2482:28;;;;;;;;;;-1:-1:-1;2482:28:11;;;;-1:-1:-1;;;2482:28:11;;;;;;;;;5103:6:18;5091:19;;;5073:38;;5061:2;5046:18;2482:28:11;4929:188:18;27692:53:11;;;;;;;;;;-1:-1:-1;27692:53:11;;;;;:::i;:::-;;;;;;;;;;;;;;13476:149;;;;;;;;;;-1:-1:-1;13476:149:11;;;;;:::i;:::-;;:::i;24795:228::-;;;;;;;;;;-1:-1:-1;24795:228:11;;;;;:::i;:::-;;:::i;9997:62::-;;;;;;;;;;-1:-1:-1;9997:62:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;4724:330:4;;;;;;;;;;-1:-1:-1;4724:330:4;;;;;:::i;:::-;;:::i;7028:31:11:-;;;;;;;;;;;;;;;;11932:190;;;;;;;;;;-1:-1:-1;11932:190:11;;;;;:::i;:::-;;:::i;35926:314::-;;;;;;;;;;-1:-1:-1;35926:314:11;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;206:32:18;;;188:51;;270:2;255:18;;248:34;;;;161:18;35926:314:11;14:274:18;27501:29:11;;;;;;;;;;;;;;;;25490:133;;;;;;;;;;;;;:::i;2567:26::-;;;;;;;;;;-1:-1:-1;2567:26:11;;;;-1:-1:-1;;;;;2567:26:11;;;2679:32;;;;;;;;;;-1:-1:-1;2679:32:11;;;;-1:-1:-1;;;2679:32:11;;;;;;5294:551;;;;;;;;;;;;;:::i;5120:179:4:-;;;;;;;;;;-1:-1:-1;5120:179:4;;;;;:::i;:::-;;:::i;12550:124:11:-;;;;;;;;;;-1:-1:-1;12550:124:11;;;;;:::i;:::-;;:::i;3163:173::-;;;;;;;;;;-1:-1:-1;3163:173:11;;;;;:::i;:::-;;:::i;19261:329::-;;;;;;;;;;-1:-1:-1;19261:329:11;;;;;:::i;:::-;;:::i;7210:27::-;;;;;;;;;;-1:-1:-1;7210:27:11;;;;;;;;16361:165;;;;;;;;;;-1:-1:-1;16361:165:11;;;;;:::i;:::-;;:::i;25836:27::-;;;;;;;;;;;;;:::i;7407:49::-;;;;;;;;;;-1:-1:-1;7407:49:11;;;;;;;-1:-1:-1;;;;;7407:49:11;;;12244:170;;;;;;;;;;-1:-1:-1;12244:170:11;;;;;:::i;:::-;;:::i;2052:235:4:-;;;;;;;;;;-1:-1:-1;2052:235:4;;;;;:::i;:::-;;:::i;19759:209:11:-;;;;;;;;;;-1:-1:-1;19759:209:11;;;;;:::i;:::-;;:::i;26053:29::-;;;;;;;;;;-1:-1:-1;26053:29:11;;;;;;;;22073:222;;;;;;;;;;-1:-1:-1;22073:222:11;;;;;:::i;:::-;;:::i;1790:205:4:-;;;;;;;;;;-1:-1:-1;1790:205:4;;;;;:::i;:::-;;:::i;1598:92:14:-;;;;;;;;;;;;;:::i;4052:440:11:-;;;;;;;;;;-1:-1:-1;4052:440:11;;;;;:::i;:::-;;:::i;11635:185::-;;;;;;;;;;-1:-1:-1;11635:185:11;;;;;:::i;:::-;;:::i;9204:67::-;;;;;;;;;;-1:-1:-1;9204:67:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;9330:60;;;;;;;;;;-1:-1:-1;9330:60:11;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;9330:60:11;;;966:85:14;;;;;;;;;;-1:-1:-1;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;966:85;;9854:56:11;;;;;;;;;;-1:-1:-1;9854:56:11;;;;;:::i;:::-;;:::i;2511:102:4:-;;;;;;;;;;;;;:::i;36515:252:11:-;;;;;;;;;;-1:-1:-1;36515:252:11;;;;;:::i;:::-;;:::i;21498:263::-;;;;;;;;;;-1:-1:-1;21498:263:11;;;;;:::i;:::-;;:::i;20524:225::-;;;;;;;;;;-1:-1:-1;20524:225:11;;;;;:::i;:::-;;:::i;18718:291::-;;;;;;;;;;-1:-1:-1;18718:291:11;;;;;:::i;:::-;;:::i;17448:513::-;;;;;;;;;;-1:-1:-1;17448:513:11;;;;;:::i;:::-;;:::i;4144:290:4:-;;;;;;;;;;-1:-1:-1;4144:290:4;;;;;:::i;:::-;;:::i;9003:59:11:-;;;;;;;;;;-1:-1:-1;9003:59:11;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;9003:59:11;;;24408:169;;;;;;;;;;-1:-1:-1;24408:169:11;;;;;:::i;:::-;;:::i;22496:178::-;;;;;;;;;;-1:-1:-1;22496:178:11;;;;;:::i;:::-;;:::i;3460:::-;;;;;;;;;;-1:-1:-1;3460:178:11;;;;;:::i;:::-;;:::i;27812:56::-;;;;;;;;;;-1:-1:-1;27812:56:11;;;;;:::i;:::-;;:::i;25203:154::-;;;;;;;;;;-1:-1:-1;25203:154:11;;;;;:::i;:::-;;:::i;16796:315::-;;;;;;;;;;-1:-1:-1;16796:315:11;;;;;:::i;:::-;;:::i;5365:320:4:-;;;;;;;;;;-1:-1:-1;5365:320:4;;;;;:::i;:::-;;:::i;13229:125:11:-;;;;;;;;;;-1:-1:-1;13229:125:11;;;;;:::i;:::-;;:::i;34630:943::-;;;;;;;;;;-1:-1:-1;34630:943:11;;;;;:::i;:::-;;:::i;7094:32::-;;;;;;;;;;;;;;;;9693:57;;;;;;;;;;-1:-1:-1;9693:57:11;;;;;:::i;:::-;;:::i;20136:208::-;;;;;;;;;;-1:-1:-1;20136:208:11;;;;;:::i;:::-;;:::i;13989:1466::-;;;;;;:::i;:::-;;:::i;26714:141::-;;;;;;;;;;-1:-1:-1;26714:141:11;;;;;:::i;:::-;;:::i;6958:25::-;;;;;;;;;;;;;;;;9138:61;;;;;;;;;;-1:-1:-1;9138:61:11;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;9138:61:11;;;27752:53;;;;;;;;;;-1:-1:-1;27752:53:11;;;;;:::i;:::-;;;;;;;;;;;;;;4895:274;;;;;;;;;;-1:-1:-1;4895:274:11;;;;;:::i;:::-;;:::i;26404:142::-;;;;;;;;;;-1:-1:-1;26404:142:11;;;;;:::i;:::-;;:::i;10172:50::-;;;;;;;;;;-1:-1:-1;10172:50:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;25940:27;;;;;;;;;;;;;:::i;2378:22::-;;;;;;;;;;-1:-1:-1;2378:22:11;;;;-1:-1:-1;;;;;2378:22:11;;;4500:162:4;;;;;;;;;;-1:-1:-1;4500:162:4;;;;;:::i;:::-;-1:-1:-1;;;;;4620:25:4;;;4597:4;4620:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4500:162;9511:37:11;;;;;;;;;;-1:-1:-1;9511:37:11;;;;;;;;1839:189:14;;;;;;;;;;-1:-1:-1;1839:189:14;;;;;:::i;:::-;;:::i;7302:42:11:-;;;;;;;;;;-1:-1:-1;7302:42:11;;;;;;;;;;;23658:561;;;;;;;;;;-1:-1:-1;23658:561:11;;;;;:::i;:::-;;:::i;5970:800::-;;;;;;;;;;-1:-1:-1;5970:800:11;;;;;:::i;:::-;;:::i;26996:159::-;;;;;;;;;;-1:-1:-1;26996:159:11;;;;;:::i;:::-;;:::i;36949:1468::-;;;;;;:::i;:::-;;:::i;29613:161::-;;;;;;;;;;-1:-1:-1;29613:161:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;18219:224::-;;;;;;;;;;-1:-1:-1;18219:224:11;;;;;:::i;:::-;;:::i;31679:1007::-;31744:13;31768:20;:412;;;;;;;;;;;;;;;;;32230:38;32239:28;;;:18;:28;;;;;;;;;32230:38;;:8;:38;;;;;32291:28;;;;;;;;;;31768:412;;-1:-1:-1;31768:412:11;;32282:38;;:8;:38::i;:::-;32205:116;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;32189:133;;32364:6;32476:18;32485:8;32476;:18::i;:::-;32347:148;;;;;;;;;:::i;:::-;;;;;;;;;;;;;32331:165;;32538:6;32521:134;;;;;;;;:::i;:::-;;;;-1:-1:-1;;32521:134:11;;;;;;;;;;31679:1007;-1:-1:-1;;;31679:1007:11:o;1431:300:4:-;1533:4;-1:-1:-1;;;;;;1568:40:4;;-1:-1:-1;;;1568:40:4;;:104;;-1:-1:-1;;;;;;;1624:48:4;;-1:-1:-1;;;1624:48:4;1568:104;:156;;;-1:-1:-1;;;;;;;;;;871:40:3;;;1688:36:4;1549:175;1431:300;-1:-1:-1;;1431:300:4:o;2349:98::-;2403:13;2435:5;2428:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2349:98;:::o;3860:217::-;3936:7;7245:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7245:16:4;3955:73;;;;-1:-1:-1;;;3955:73:4;;19588:2:18;3955:73:4;;;19570:21:18;19627:2;19607:18;;;19600:30;19666:34;19646:18;;;19639:62;-1:-1:-1;;;19717:18:18;;;19710:42;19769:19;;3955:73:4;;;;;;;;;-1:-1:-1;4046:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;4046:24:4;;3860:217::o;3398:401::-;3478:13;3494:23;3509:7;3494:14;:23::i;:::-;3478:39;;3541:5;-1:-1:-1;;;;;3535:11:4;:2;-1:-1:-1;;;;;3535:11:4;;;3527:57;;;;-1:-1:-1;;;3527:57:4;;20001:2:18;3527:57:4;;;19983:21:18;20040:2;20020:18;;;20013:30;20079:34;20059:18;;;20052:62;-1:-1:-1;;;20130:18:18;;;20123:31;20171:19;;3527:57:4;19799:397:18;3527:57:4;666:10:2;-1:-1:-1;;;;;3616:21:4;;;;:62;;-1:-1:-1;3641:37:4;3658:5;666:10:2;4500:162:4;:::i;3641:37::-;3595:165;;;;-1:-1:-1;;;3595:165:4;;20403:2:18;3595:165:4;;;20385:21:18;20442:2;20422:18;;;20415:30;20481:34;20461:18;;;20454:62;20552:26;20532:18;;;20525:54;20596:19;;3595:165:4;20201:420:18;3595:165:4;3771:21;3780:2;3784:7;3771:8;:21::i;:::-;3468:331;3398:401;;:::o;8884:43:11:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;8884:43:11;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8884:43:11;;;;;-1:-1:-1;8884:43:11;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;8884:43:11;;;;;;;-1:-1:-1;;8884:43:11;;;;;;;;;;;;;;;;;:::o;12810:296::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;12917:4:11::1;12905:8;:16;;;;12897:35;;;::::0;-1:-1:-1;;;12897:35:11;;21189:2:18;12897:35:11::1;::::0;::::1;21171:21:18::0;21228:1;21208:18;;;21201:29;-1:-1:-1;;;21246:18:18;;;21239:36;21292:18;;12897:35:11::1;20987:329:18::0;12897:35:11::1;13007:5;12995:8;:17;;;;12987:37;;;::::0;-1:-1:-1;;;12987:37:11;;21523:2:18;12987:37:11::1;::::0;::::1;21505:21:18::0;21562:1;21542:18;;;21535:29;-1:-1:-1;;;21580:18:18;;;21573:37;21627:18;;12987:37:11::1;21321:330:18::0;12987:37:11::1;13076:13;:24:::0;;-1:-1:-1;;13076:24:11::1;;::::0;;;::::1;::::0;;;::::1;::::0;;12810:296::o;13476:149::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;13582:23:11::1;:37:::0;;-1:-1:-1;;13582:37:11::1;;::::0;;;::::1;::::0;;;::::1;::::0;;13476:149::o;24795:228::-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;24912:20:::1;::::0;;;:8:::1;:20;::::0;;;;:41:::1;::::0;:29:::1;;24944:9:::0;;24912:41:::1;:::i;:::-;;24995:10;24967:50;25007:9;;24967:50;;;;;;;:::i;:::-;;;;;;;;24795:228:::0;;;:::o;4724:330:4:-;4913:41;666:10:2;4946:7:4;4913:18;:41::i;:::-;4905:103;;;;-1:-1:-1;;;4905:103:4;;;;;;;:::i;:::-;5019:28;5029:4;5035:2;5039:7;5019:9;:28::i;11932:190:11:-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;-1:-1:-1;;;;;12021:28:11;::::1;12052:5;12021:28:::0;;;:18:::1;:28;::::0;;;;;;;:36;;-1:-1:-1;;12021:36:11::1;::::0;;12071:45;2033:41:18;;;12071:45:11::1;::::0;2006:18:18;12071:45:11::1;;;;;;;;11932:190:::0;:::o;35926:314::-;36017:16;36035:21;36087:14;;36075:8;:26;;36067:46;;;;-1:-1:-1;;;36067:46:11;;23003:2:18;36067:46:11;;;22985:21:18;23042:1;23022:18;;;23015:29;-1:-1:-1;;;23060:18:18;;;23053:37;23107:18;;36067:46:11;22801:330:18;36067:46:11;36130:55;36156:28;;;:18;:28;;;;;;;;;36130:55;;:25;:55;;;;;;36200:23;;-1:-1:-1;;;;;36130:55:11;;;;36226:5;;36187:36;;36200:23;;36187:10;:36;:::i;:::-;:44;;;;:::i;:::-;36122:110;;;;35926:314;;;;;;:::o;25490:133::-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;25595:22:::1;::::0;;-1:-1:-1;;25569:48:11;::::1;25595:22:::0;;;;::::1;;;25594:23;25569:48:::0;;::::1;;::::0;;25490:133::o;5294:551::-;1680:1:15;2259:7;;:19;;2251:63;;;;-1:-1:-1;;;2251:63:15;;23900:2:18;2251:63:15;;;23882:21:18;23939:2;23919:18;;;23912:30;23978:33;23958:18;;;23951:61;24029:18;;2251:63:15;23698:355:18;2251:63:15;1680:1;2389:7;:18;;;5472:14:11;5401:21:::1;::::0;5374:24:::1;::::0;5489:5:::1;::::0;5453:33:::1;::::0;-1:-1:-1;;;5472:14:11;::::1;;;5401:21:::0;5453:33:::1;:::i;:::-;:41;;;;:::i;:::-;5548:18;::::0;5429:65;;-1:-1:-1;5501:25:11::1;::::0;5569:5:::1;::::0;5529:37:::1;::::0;-1:-1:-1;;;5548:18:11;::::1;;;5529:16:::0;:37:::1;:::i;:::-;:45;;;;:::i;:::-;5501:73:::0;-1:-1:-1;5581:22:11::1;5501:73:::0;5606:32:::1;5625:13:::0;5606:16;:32:::1;:::i;:::-;:52;;;;:::i;:::-;5581:77;;5688:47;5720:14;5696:4;-1:-1:-1::0;;;;;5696:10:11::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5688:31:11::1;::::0;::::1;:47::i;:::-;5750:7;::::0;5742:41:::1;::::0;-1:-1:-1;;;;;5750:7:11::1;5769:13:::0;5742:26:::1;:41::i;:::-;5798:11;::::0;5790:49:::1;::::0;-1:-1:-1;;;;;5798:11:11::1;5821:17:::0;5790:30:::1;:49::i;:::-;-1:-1:-1::0;;1637:1:15;2562:22;;-1:-1:-1;;5294:551:11:o;5120:179:4:-;5253:39;5270:4;5276:2;5280:7;5253:39;;;;;;;;;;;;:16;:39::i;12550:124:11:-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;12641:10:11::1;:27:::0;12550:124::o;3163:173::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;-1:-1:-1;;;;;3247:22:11;::::1;;::::0;;;:12:::1;:22;::::0;;;;;;;;:29;;-1:-1:-1;;3247:29:11::1;3272:4;3247:29:::0;;::::1;::::0;;;3290:40;;2033:41:18;;;-1:-1:-1;;;;;;;;;;;3290:40:11;2006:18:18;3290:40:11::1;1893:187:18::0;19261:329:11;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;19404:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;19449:20:::2;::::0;;;:8:::2;:20;::::0;;;;:37:::2;;::::0;19433:53;::::2;;19425:62;;;::::0;::::2;;19520:7;19504:12;:23;;19496:32;;;::::0;::::2;;-1:-1:-1::0;;19537:20:11::2;::::0;;;:8:::2;:20;::::0;;;;;:32:::2;;:47:::0;19261:329::o;16361:165::-;16471:37;;;;:25;:37;;;;;;;16435:85;;-1:-1:-1;;;16435:85:11;;;;-1:-1:-1;;;;;16471:37:11;;;;16435:83;;:85;;;;;;;;;;;16471:37;;16435:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16361:165;:::o;25836:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;12244:170::-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;12354:16:::1;;12340:10;:30;;12332:39;;;::::0;::::1;;12378:17;:30:::0;12244:170::o;2052:235:4:-;2124:7;2159:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2159:16:4;2193:19;2185:73;;;;-1:-1:-1;;;2185:73:4;;25319:2:18;2185:73:4;;;25301:21:18;25358:2;25338:18;;;25331:30;25397:34;25377:18;;;25370:62;-1:-1:-1;;;25448:18:18;;;25441:39;25497:19;;2185:73:4;25117:405:18;19759:209:11;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;19901:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;19922:20:::2;::::0;;;:8:::2;:20;::::0;;;;;;;:40;;::::2;::::0;;::::2;::::0;::::2;:::i;22073:222::-:0;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;22220:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;22244:20:::2;::::0;;;:8:::2;:20;::::0;;;;;;;:45;;::::2;::::0;:31:::2;::::0;;::::2;::::0;:45;::::2;::::0;::::2;:::i;1790:205:4:-:0;1862:7;-1:-1:-1;;;;;1889:19:4;;1881:74;;;;-1:-1:-1;;;1881:74:4;;25729:2:18;1881:74:4;;;25711:21:18;25768:2;25748:18;;;25741:30;25807:34;25787:18;;;25780:62;-1:-1:-1;;;25858:18:18;;;25851:40;25908:19;;1881:74:4;25527:406:18;1881:74:4;-1:-1:-1;;;;;;1972:16:4;;;;;:9;:16;;;;;;;1790:205::o;1598:92:14:-;1012:7;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;1662:21:::1;1680:1;1662:9;:21::i;:::-;1598:92::o:0;4052:440:11:-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;4204:18:11::1;::::0;4198:24:::1;::::0;-1:-1:-1;;;4204:18:11;::::1;;;4198:5;:24;:::i;:::-;4182:41;;:11;:41;;;;4174:50;;;::::0;::::1;;4231:10;:8;:10::i;:::-;4261:7;::::0;;-1:-1:-1;;;;;4261:7:11;;::::1;4272:5;4248:21:::0;;;:12:::1;:21;::::0;;;;;;;:29;;-1:-1:-1;;4248:29:11::1;::::0;;4314:7;;4289:40;;2033:41:18;;;4314:7:11;;;::::1;::::0;-1:-1:-1;;;;;;;;;;;4289:40:11;2006:18:18;4289:40:11::1;;;;;;;-1:-1:-1::0;;;;;4336:25:11;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;;:32;;-1:-1:-1;;4336:32:11::1;4364:4;4336:32:::0;;::::1;::::0;;;4380:43;;2033:41:18;;;-1:-1:-1;;;;;;;;;;;4380:43:11;2006:18:18;4380:43:11::1;;;;;;;4430:7;:21:::0;;4458:28:::1;::::0;;::::1;-1:-1:-1::0;;;4458:28:11::1;-1:-1:-1::0;;;;;;4458:28:11;;;-1:-1:-1;;;;;4430:21:11;;::::1;4458:28:::0;;;;::::1;::::0;;4052:440::o;11635:185::-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;-1:-1:-1;;;;;11721:28:11;::::1;;::::0;;;:18:::1;:28;::::0;;;;;;;;:35;;-1:-1:-1;;11721:35:11::1;11752:4;11721:35:::0;;::::1;::::0;;;11770:44;;2033:41:18;;;11770:44:11::1;::::0;2006:18:18;11770:44:11::1;1893:187:18::0;9854:56:11;;;;;;;;;;;;;;;;:::i;2511:102:4:-;2567:13;2599:7;2592:14;;;;;:::i;36515:252:11:-;36636:8;28117:17;28125:8;28117:7;:17::i;:::-;-1:-1:-1;;;;;28103:31:11;:10;-1:-1:-1;;;;;28103:31:11;;:103;;;-1:-1:-1;28152:54:11;28177:28;;;:18;:28;;;;;;;;;28152:54;;:24;:54;;;;;;-1:-1:-1;;;;;28152:54:11;28138:10;:68;28103:103;28095:127;;;;-1:-1:-1;;;28095:127:11;;26362:2:18;28095:127:11;;;26344:21:18;26401:2;26381:18;;;26374:30;-1:-1:-1;;;26420:18:18;;;26413:41;26471:18;;28095:127:11;26160:335:18;28095:127:11;36663:26;36655:35:::1;;;::::0;::::1;;36740:8;36728:10;-1:-1:-1::0;;;;;36704:55:11::1;;36750:8;;36704:55;;;;;;;:::i;:::-;;;;;;;;36515:252:::0;;;;:::o;21498:263::-;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;21667:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;21688:20:::2;::::0;;;:8:::2;:20;::::0;;;;;;;:67;;::::2;::::0;:42:::2;::::0;;::::2;::::0;:67;::::2;::::0;::::2;:::i;20524:225::-:0;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;20675:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;20696:20:::2;::::0;;;:8:::2;:20;::::0;;;;:47:::2;::::0;:32:::2;;20731:12:::0;;20696:47:::2;:::i;:::-;;10360:1:::1;20524:225:::0;;;;:::o;18718:291::-;10591:10;10578:24;;;;:12;:24;;;;;;18844:10;;10578:24;;;:78;;-1:-1:-1;10620:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;10620:36:11;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1;;;10570:101:11;;;;;;;:::i;:::-;18893:1:::1;18873:17;:21;;;18865:30;;;::::0;::::1;;18933:3;18912:17;:24;;;;18904:33;;;::::0;::::1;;-1:-1:-1::0;18946:20:11::1;::::0;;;:8:::1;:20;::::0;;;;;:37:::1;;:57:::0;;-1:-1:-1;;18946:57:11::1;;::::0;;::::1;::::0;;;::::1;::::0;;18718:291::o;17448:513::-;10442:36;;;;:24;:36;;;;;;;;-1:-1:-1;;;;;10442:36:11;10428:10;:50;10420:69;;;;-1:-1:-1;;;10420:69:11;;26702:2:18;10420:69:11;;;26684:21:18;26741:1;26721:18;;;26714:29;-1:-1:-1;;;26759:18:18;;;26752:36;26805:18;;10420:69:11;26500:329:18;10420:69:11;17634:38:::1;::::0;;;:26:::1;:38;::::0;;;;;;;:57;;-1:-1:-1;;;;;;17634:57:11::1;-1:-1:-1::0;;;;;17634:57:11;;::::1;::::0;;::::1;::::0;;;17700:33:::1;:45:::0;;;;;:71;;-1:-1:-1;;17700:71:11::1;;::::0;::::1;::::0;;::::1;::::0;;;17841:25:::1;:37:::0;;;;;;;;17805:150;;-1:-1:-1;;;17805:150:11;;::::1;::::0;::::1;27006:51:18::0;;;;27073:18;;;27066:47;;;;17841:37:11::1;::::0;17805:107:::1;::::0;26979:18:18;;17805:150:11::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;17448:513:::0;;;;:::o;4144:290:4:-;-1:-1:-1;;;;;4246:24:4;;666:10:2;4246:24:4;;4238:62;;;;-1:-1:-1;;;4238:62:4;;27326:2:18;4238:62:4;;;27308:21:18;27365:2;27345:18;;;27338:30;27404:27;27384:18;;;27377:55;27449:18;;4238:62:4;27124:349:18;4238:62:4;666:10:2;4311:32:4;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;4311:42:4;;;;;;;;;;;;:53;;-1:-1:-1;;4311:53:4;;;;;;;;;;4379:48;;2033:41:18;;;4311:42:4;;666:10:2;4379:48:4;;2006:18:18;4379:48:4;;;;;;;4144:290;;:::o;24408:169:11:-;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;24516:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;-1:-1:-1::0;;24537:20:11::2;::::0;;;:8:::2;:20;::::0;;;;;;;:27:::2;:34:::0;;-1:-1:-1;;24537:34:11::2;::::0;::::2;::::0;;24408:169::o;22496:178::-;10591:10;10578:24;;;;:12;:24;;;;;;22589:10;;10578:24;;;:78;;-1:-1:-1;10620:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;10620:36:11;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1;;;10570:101:11;;;;;;;:::i;:::-;-1:-1:-1;22641:20:11::1;::::0;;;:8:::1;:20;::::0;;;;;;;:27:::1;::::0;;-1:-1:-1;;22610:58:11;::::1;22641:27;::::0;;;::::1;;;22640:28;22610:58:::0;;::::1;;::::0;;22496:178::o;3460:::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;-1:-1:-1;;;;;3547:22:11;::::1;3572:5;3547:22:::0;;;:12:::1;:22;::::0;;;;;;;:30;;-1:-1:-1;;3547:30:11::1;::::0;;3591:41;2033::18;;;-1:-1:-1;;;;;;;;;;;3591:41:11;2006:18:18;3591:41:11::1;1893:187:18::0;27812:56:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25203:154::-;2895:10;2882:24;;;;:12;:24;;;;;;;;2874:41;;;;-1:-1:-1;;;2874:41:11;;;;;;;:::i;:::-;25324:20:::1;::::0;;;:8:::1;:20;::::0;;;;;;;:27:::1;::::0;;-1:-1:-1;;25293:58:11;::::1;25324:27;::::0;;::::1;25323:28;25293:58;::::0;;25203:154::o;16796:315::-;10442:36;;;;:24;:36;;;;;;;;-1:-1:-1;;;;;10442:36:11;10428:10;:50;10420:69;;;;-1:-1:-1;;;10420:69:11;;26702:2:18;10420:69:11;;;26684:21:18;26741:1;26721:18;;;26714:29;-1:-1:-1;;;26759:18:18;;;26752:36;26805:18;;10420:69:11;26500:329:18;10420:69:11;16926:36:::1;::::0;;;:24:::1;:36;::::0;;;;;;;:56;;-1:-1:-1;;;;;;16926:56:11::1;-1:-1:-1::0;;;;;16926:56:11;;::::1;::::0;;::::1;::::0;;;17027:25:::1;:37:::0;;;;;;;;16991:114;;-1:-1:-1;;;16991:114:11;;::::1;::::0;::::1;2619:51:18::0;;;;17027:37:11;;::::1;::::0;16991:95:::1;::::0;2592:18:18;;16991:114:11::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;16796:315:::0;;;:::o;5365:320:4:-;5534:41;666:10:2;5567:7:4;5534:18;:41::i;:::-;5526:103;;;;-1:-1:-1;;;5526:103:4;;;;;;;:::i;:::-;5639:39;5653:4;5659:2;5663:7;5672:5;5639:13;:39::i;:::-;5365:320;;;;:::o;13229:125:11:-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;13343:5:11::1;13313:20:::0;;;:8:::1;:20;::::0;;;;;;;:27:::1;:35:::0;;-1:-1:-1;;13313:35:11::1;::::0;;13229:125::o;34630:943::-;7222:4:4;7245:16;;;:7;:16;;;;;;34696:13:11;;-1:-1:-1;;;;;7245:16:4;34720:77:11;;;;-1:-1:-1;;;34720:77:11;;27680:2:18;34720:77:11;;;27662:21:18;27719:2;27699:18;;;27692:30;27758:34;27738:18;;;27731:62;-1:-1:-1;;;27809:18:18;;;27802:45;27864:19;;34720:77:11;27478:411:18;34720:77:11;34809:17;;;;34806:760;;;34888:21;34912:10;:8;:10::i;:::-;34888:34;;34964:1;34946:7;34940:21;:25;:87;;;;;;;;;;;;;;;;;34992:7;35001:19;:8;:17;:19::i;:::-;34975:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;34940:87;34933:94;34630:943;-1:-1:-1;;;34630:943:11:o;34806:760::-;35132:18;35153:300;35257:37;35285:8;35257:27;:37::i;:::-;35346:28;35365:8;35346:18;:28::i;:::-;35222:192;;;;;;;;;:::i;:::-;;;;;;;;;;;;;35153:13;:300::i;:::-;35132:321;;35528:4;35478:55;;;;;;;;:::i;34806:760::-;34630:943;;;:::o;9693:57::-;;;;;;;;;;;;;;;;:::i;20136:208::-;10313:20;;;;:8;:20;;;;;;;;:27;;:20;;:27;;;;;10312:28;10304:47;;;;-1:-1:-1;;;10304:47:11;;;;;;;:::i;:::-;10591:10:::1;10578:24;::::0;;;:12:::1;:24;::::0;;;;;20276:10;;10578:24:::1;;::::0;:78:::1;;-1:-1:-1::0;10620:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;-1:-1:-1;;;;;10620:36:11::1;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1::0;;;10570:101:11::1;;;;;;;:::i;:::-;20297:20:::2;::::0;;;:8:::2;:20;::::0;;;;;;;:41;;::::2;::::0;:27:::2;::::0;;::::2;::::0;:41;::::2;::::0;::::2;:::i;13989:1466::-:0;10735:22;;;;;;;10732:91;;;10795:10;10776:30;;;;:18;:30;;;;;;;;10768:47;;;;-1:-1:-1;;;10768:47:11;;;;;;29844:2:18;29826:21;;;29883:1;29863:18;;;29856:29;-1:-1:-1;;;29916:2:18;29901:18;;29894:34;29960:2;29945:18;;29642:327;10768:47:11;14337:10:::1;;14324:9;:23;;14316:47;;;::::0;-1:-1:-1;;;14316:47:11;;30176:2:18;14316:47:11::1;::::0;::::1;30158:21:18::0;30215:2;30195:18;;;30188:30;-1:-1:-1;;;30234:18:18;;;30227:41;30285:18;;14316:47:11::1;29974:335:18::0;14316:47:11::1;14380:30:::0;14372:39:::1;;;::::0;::::1;;14428:29:::0;14420:38:::1;;;::::0;::::1;;14490:1;14475:12;:16;:43;;;;;14511:7;14495:12;:23;;14475:43;14467:52;;;::::0;::::1;;14530:16;:18:::0;;;:16:::1;:18;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;14578:16:11::1;::::0;14557:18:::1;14603:20:::0;;;:8:::1;:20;::::0;;;;:40:::1;::::0;14631:12;;14603:40:::1;:::i;:::-;-1:-1:-1::0;14652:20:11::1;::::0;;;:8:::1;:20;::::0;;;;:41:::1;::::0;:27:::1;;14682:11:::0;;14652:41:::1;:::i;:::-;-1:-1:-1::0;14702:20:11::1;::::0;;;:8:::1;:20;::::0;;;;:47:::1;::::0;:32:::1;;14737:12:::0;;14702:47:::1;:::i;:::-;-1:-1:-1::0;14760:36:11::1;::::0;;;:24:::1;:36;::::0;;;;;;;:49;;-1:-1:-1;;;;;;14760:49:11::1;14799:10;14760:49;::::0;;14818:31:::1;:43:::0;;;;;:65;;;14892:8:::1;:20:::0;;;;;:37:::1;::::0;::::1;:41:::0;;;;14942:32:::1;::::0;::::1;:47:::0;;;15000:37:::1;::::0;::::1;:42:::0;;-1:-1:-1;;15000:42:11::1;::::0;;::::1;::::0;;15053:67:::1;::::0;:42:::1;;15098:22:::0;;15053:67:::1;:::i;:::-;-1:-1:-1::0;15129:20:11::1;::::0;;;:8:::1;:20;::::0;;;;:45:::1;::::0;:31:::1;;15163:11:::0;;15129:45:::1;:::i;:::-;-1:-1:-1::0;15215:5:11::1;15185:20:::0;;;:8:::1;:20;::::0;;;;;;;:27:::1;:35:::0;;-1:-1:-1;;15272:35:11;15185::::1;15272::::0;;;15318:56:::1;15194:10:::0;15318:44:::1;:56::i;:::-;15424:10;15412;-1:-1:-1::0;;;;;15390:59:11::1;;15436:12;;15390:59;;;;;;;:::i;:::-;;;;;;;;14307:1148;13989:1466:::0;;;;;;;;;;;;:::o;26714:141::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;26814:33:11::1;:13;26830:17:::0;;26814:33:::1;:::i;4895:274::-:0;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;5055:14:11::1;::::0;5049:20:::1;::::0;-1:-1:-1;;;5055:14:11;::::1;;;5049:5;:20;:::i;:::-;5033:37;;:11;:37;;;;5025:46;;;::::0;::::1;;5078:10;:8;:10::i;:::-;5095:11;:29:::0;;5131:32:::1;::::0;;::::1;-1:-1:-1::0;;;5131:32:11::1;-1:-1:-1::0;;;;;;5131:32:11;;;-1:-1:-1;;;;;5095:29:11;;::::1;5131:32:::0;;;;::::1;::::0;;4895:274::o;26404:142::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;26505:33:11::1;:13;26521:17:::0;;26505:33:::1;:::i;25940:27::-:0;;;;;;;:::i;1839:189:14:-;1012:7;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;-1:-1:-1;;;;;1927:22:14;::::1;1919:73;;;::::0;-1:-1:-1;;;1919:73:14;;30656:2:18;1919:73:14::1;::::0;::::1;30638:21:18::0;30695:2;30675:18;;;30668:30;30734:34;30714:18;;;30707:62;-1:-1:-1;;;30785:18:18;;;30778:36;30831:19;;1919:73:14::1;30454:402:18::0;1919:73:14::1;2002:19;2012:8;2002:9;:19::i;:::-;1839:189:::0;:::o;23658:561:11:-;10591:10;10578:24;;;;:12;:24;;;;;;24007:10;;10578:24;;;:78;;-1:-1:-1;10620:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;10620:36:11;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1;;;10570:101:11;;;;;;;:::i;:::-;24026:35:::1;::::0;;;:23:::1;:35;::::0;;;;:54:::1;::::0;24064:16;;24026:54:::1;:::i;:::-;-1:-1:-1::0;24087:34:11::1;::::0;;;:22:::1;:34;::::0;;;;:52:::1;::::0;24124:15;;24087:52:::1;:::i;:::-;-1:-1:-1::0;;24146:42:11::1;::::0;;;:30:::1;:42;::::0;;;;;:67;;-1:-1:-1;;24146:67:11::1;::::0;::::1;;::::0;;;::::1;::::0;;;-1:-1:-1;;;;23658:561:11:o;5970:800::-;1680:1:15;2259:7;;:19;;2251:63;;;;-1:-1:-1;;;2251:63:15;;23900:2:18;2251:63:15;;;23882:21:18;23939:2;23919:18;;;23912:30;23978:33;23958:18;;;23951:61;24029:18;;2251:63:15;23698:355:18;2251:63:15;1680:1;2389:7;:18;6080:30:11::1;::::0;-1:-1:-1;;;6080:30:11;;6104:4:::1;6080:30;::::0;::::1;2619:51:18::0;6053:24:11::1;::::0;-1:-1:-1;;;;;6080:15:11;::::1;::::0;::::1;::::0;2592:18:18;;6080:30:11::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6053:57;;6144:1;6125:16;:20;6117:42;;;::::0;-1:-1:-1;;;6117:42:11;;31252:2:18;6117:42:11::1;::::0;::::1;31234:21:18::0;31291:1;31271:18;;;31264:29;-1:-1:-1;;;31309:18:18;;;31302:39;31358:18;;6117:42:11::1;31050:332:18::0;6117:42:11::1;6227:14;::::0;6184:21:::1;::::0;6244:5:::1;::::0;6208:33:::1;::::0;-1:-1:-1;;;6227:14:11;::::1;;;6208:16:::0;:33:::1;:::i;:::-;:41;;;;:::i;:::-;6303:18;::::0;6184:65;;-1:-1:-1;6256:25:11::1;::::0;6324:5:::1;::::0;6284:37:::1;::::0;-1:-1:-1;;;6303:18:11;::::1;;;6284:16:::0;:37:::1;:::i;:::-;:45;;;;:::i;:::-;6256:73:::0;-1:-1:-1;6336:22:11::1;6256:73:::0;6361:32:::1;6380:13:::0;6361:16;:32:::1;:::i;:::-;:52;;;;:::i;:::-;6336:77;;6443:59;6466:5;6473:4;-1:-1:-1::0;;;;;6473:10:11::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6487:14;6443:22;:59::i;:::-;6512:7;::::0;-1:-1:-1;;;;;6512:7:11::1;:21:::0;;::::1;::::0;:42:::1;;;6553:1;6537:13;:17;6512:42;6509:117;;;6595:7;::::0;6565:53:::1;::::0;6588:5;;-1:-1:-1;;;;;6595:7:11::1;6604:13:::0;6565:22:::1;:53::i;:::-;6635:11;::::0;-1:-1:-1;;;;;6635:11:11::1;:25:::0;;::::1;::::0;:50:::1;;;6684:1;6664:17;:21;6635:50;6632:133;;;6726:11;::::0;6696:61:::1;::::0;6719:5;;-1:-1:-1;;;;;6726:11:11::1;6739:17:::0;6696:22:::1;:61::i;:::-;-1:-1:-1::0;;1637:1:15;2562:22;;-1:-1:-1;;;5970:800:11:o;26996:159::-;1012:7:14;1038:6;-1:-1:-1;;;;;1038:6:14;666:10:2;1178:23:14;1170:68;;;;-1:-1:-1;;;1170:68:14;;;;;;;:::i;:::-;27103:17:11::1;:44:::0;;-1:-1:-1;;27103:44:11::1;::::0;::::1;;::::0;;;::::1;::::0;;26996:159::o;36949:1468::-;37067:43;;;;:31;:43;;;;;;37054:9;:56;;37046:77;;;;-1:-1:-1;;;37046:77:11;;31589:2:18;37046:77:11;;;31571:21:18;31628:1;31608:18;;;31601:29;-1:-1:-1;;;31646:18:18;;;31639:38;31694:18;;37046:77:11;31387:331:18;37046:77:11;37180:20;;;;:8;:20;;;;;:32;;;;37140:37;;;;;:72;37132:93;;;;-1:-1:-1;;;37132:93:11;;31925:2:18;37132:93:11;;;31907:21:18;31964:1;31944:18;;;31937:29;-1:-1:-1;;;31982:18:18;;;31975:38;32030:18;;37132:93:11;31723:331:18;37132:93:11;37330:20;;;;:8;:20;;;;;;;;:27;;;;;:81;;-1:-1:-1;37375:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;37375:36:11;37361:10;:50;37330:81;:109;;;-1:-1:-1;37428:10:11;37415:24;;;;:12;:24;;;;;;;;37330:109;37322:132;;;;-1:-1:-1;;;37322:132:11;;32261:2:18;37322:132:11;;;32243:21:18;32300:2;32280:18;;;32273:30;-1:-1:-1;;;32319:18:18;;;32312:40;32369:18;;37322:132:11;32059:334:18;37322:132:11;37562:20;;;;:8;:20;;;;;;;;:27;;;;;;;37561:28;;:82;;-1:-1:-1;37607:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;37607:36:11;37593:10;:50;37561:82;:110;;;-1:-1:-1;37660:10:11;37647:24;;;;:12;:24;;;;;;;;37561:110;37553:129;;;;-1:-1:-1;;;37553:129:11;;32600:2:18;37553:129:11;;;32582:21:18;32639:1;32619:18;;;32612:29;-1:-1:-1;;;32657:18:18;;;32650:36;32703:18;;37553:129:11;32398:329:18;37553:129:11;37711:19;37735:14;;37733:16;;;;;:::i;:::-;;;;;-1:-1:-1;37758:21:11;37784:20;;;:8;:20;;;;;:37;;37782:39;;37733:16;;-1:-1:-1;37758:21:11;;;;37782:39;;;:::i;:::-;;;;;-1:-1:-1;37832:31:11;;;;:18;:31;;;;;;;;:44;;;37885:31;;;;;;:47;;;37941:31;;;:19;:31;;;;:49;;;;;;;;;;;;;;;;37782:39;-1:-1:-1;38024:30:11;38030:10;37851:11;38024:5;:30::i;:::-;38248:37;;;;:25;:37;;;;;;38240:67;;-1:-1:-1;;;;;38248:37:11;38297:9;38240:56;:67::i;:::-;38397:11;38370:10;38358;-1:-1:-1;;;;;38323:86:11;;38382:13;38323:86;;;;1375:25:18;;1363:2;1348:18;;1229:177;38323:86:11;;;;;;;;37020:1397;;36949:1468;:::o;29613:161::-;29735:31;;;;:19;:31;;;;;;;;;29728:38;;;;;;;;;;;;;;;;;29689:26;;29728:38;;;29735:31;29728:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29613:161;;;:::o;18219:224::-;10591:10;10578:24;;;;:12;:24;;;;;;18351:10;;10578:24;;;:78;;-1:-1:-1;10620:36:11;;;;:24;:36;;;;;;-1:-1:-1;;;;;10620:36:11;10606:10;:50;10578:78;10570:101;;;;-1:-1:-1;;;10570:101:11;;;;;;;:::i;:::-;-1:-1:-1;18372:43:11::1;::::0;;;:31:::1;:43;::::0;;;;;:65;18219:224::o;30257:536::-;30313:13;30347:10;30343:53;;-1:-1:-1;;30374:10:11;;;;;;;;;;;;-1:-1:-1;;;30374:10:11;;;;;30257:536::o;30343:53::-;30421:5;30406:12;30462:78;30469:9;;30462:78;;30495:8;;;;:::i;:::-;;-1:-1:-1;30518:10:11;;-1:-1:-1;30526:2:11;30518:10;;:::i;:::-;;;30462:78;;;30550:19;30582:6;-1:-1:-1;;;;;30572:17:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30572:17:11;;30550:39;;30600:154;30607:10;;30600:154;;30634:11;30644:1;30634:11;;:::i;:::-;;-1:-1:-1;30703:10:11;30711:2;30703:5;:10;:::i;:::-;30690:24;;:2;:24;:::i;:::-;30677:39;;30660:6;30667;30660:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;30660:56:11;;;;;;;;-1:-1:-1;30731:11:11;30740:2;30731:11;;:::i;:::-;;;30600:154;;;30778:6;30257:536;-1:-1:-1;;;;30257:536:11:o;11008:171:4:-;11082:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;11082:29:4;-1:-1:-1;;;;;11082:29:4;;;;;;;;:24;;11135:23;11082:24;11135:14;:23::i;:::-;-1:-1:-1;;;;;11126:46:4;;;;;;;;;;;11008:171;;:::o;7440:344::-;7533:4;7245:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7245:16:4;7549:73;;;;-1:-1:-1;;;7549:73:4;;33316:2:18;7549:73:4;;;33298:21:18;33355:2;33335:18;;;33328:30;33394:34;33374:18;;;33367:62;-1:-1:-1;;;33445:18:18;;;33438:42;33497:19;;7549:73:4;33114:408:18;7549:73:4;7632:13;7648:23;7663:7;7648:14;:23::i;:::-;7632:39;;7700:5;-1:-1:-1;;;;;7689:16:4;:7;-1:-1:-1;;;;;7689:16:4;;:51;;;;7733:7;-1:-1:-1;;;;;7709:31:4;:20;7721:7;7709:11;:20::i;:::-;-1:-1:-1;;;;;7709:31:4;;7689:51;:87;;;-1:-1:-1;;;;;;4620:25:4;;;4597:4;4620:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7744:32;4500:162;10337:560;10491:4;-1:-1:-1;;;;;10464:31:4;:23;10479:7;10464:14;:23::i;:::-;-1:-1:-1;;;;;10464:31:4;;10456:85;;;;-1:-1:-1;;;10456:85:4;;33729:2:18;10456:85:4;;;33711:21:18;33768:2;33748:18;;;33741:30;33807:34;33787:18;;;33780:62;-1:-1:-1;;;33858:18:18;;;33851:39;33907:19;;10456:85:4;33527:405:18;10456:85:4;-1:-1:-1;;;;;10559:16:4;;10551:65;;;;-1:-1:-1;;;10551:65:4;;34139:2:18;10551:65:4;;;34121:21:18;34178:2;34158:18;;;34151:30;34217:34;34197:18;;;34190:62;-1:-1:-1;;;34268:18:18;;;34261:34;34312:19;;10551:65:4;33937:400:18;10551:65:4;10728:29;10745:1;10749:7;10728:8;:29::i;:::-;-1:-1:-1;;;;;10768:15:4;;;;;;:9;:15;;;;;:20;;10787:1;;10768:15;:20;;10787:1;;10768:20;:::i;:::-;;;;-1:-1:-1;;;;;;;10798:13:4;;;;;;:9;:13;;;;;:18;;10815:1;;10798:13;:18;;10815:1;;10798:18;:::i;:::-;;;;-1:-1:-1;;10826:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10826:21:4;-1:-1:-1;;;;;10826:21:4;;;;;;;;;10863:27;;10826:16;;10863:27;;;;;;;10337:560;;;:::o;2012:312:0:-;2126:6;2101:21;:31;;2093:73;;;;-1:-1:-1;;;2093:73:0;;34544:2:18;2093:73:0;;;34526:21:18;34583:2;34563:18;;;34556:30;34622:31;34602:18;;;34595:59;34671:18;;2093:73:0;34342:353:18;2093:73:0;2178:12;2196:9;-1:-1:-1;;;;;2196:14:0;2218:6;2196:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2177:52;;;2247:7;2239:78;;;;-1:-1:-1;;;2239:78:0;;35112:2:18;2239:78:0;;;35094:21:18;35151:2;35131:18;;;35124:30;35190:34;35170:18;;;35163:62;35261:28;35241:18;;;35234:56;35307:19;;2239:78:0;34910:422:18;2034:169:14;2089:16;2108:6;;-1:-1:-1;;;;;2124:17:14;;;-1:-1:-1;;;;;;2124:17:14;;;;;;2156:40;;2108:6;;;;;;;2156:40;;2089:16;2156:40;2079:124;2034:169;:::o;6547:307:4:-;6698:28;6708:4;6714:2;6718:7;6698:9;:28::i;:::-;6744:48;6767:4;6773:2;6777:7;6786:5;6744:22;:48::i;:::-;6736:111;;;;-1:-1:-1;;;6736:111:4;;;;;;;:::i;30005:104:11:-;30057:13;30088;30081:20;;;;;:::i;275:703:17:-;331:13;548:10;544:51;;-1:-1:-1;;574:10:17;;;;;;;;;;;;-1:-1:-1;;;574:10:17;;;;;275:703::o;544:51::-;619:5;604:12;658:75;665:9;;658:75;;690:8;;;;:::i;:::-;;-1:-1:-1;712:10:17;;-1:-1:-1;720:2:17;712:10;;:::i;:::-;;;658:75;;;742:19;774:6;-1:-1:-1;;;;;764:17:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;764:17:17;;742:39;;791:150;798:10;;791:150;;824:11;834:1;824:11;;:::i;:::-;;-1:-1:-1;892:10:17;900:2;892:5;:10;:::i;:::-;879:24;;:2;:24;:::i;:::-;866:39;;849:6;856;849:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;849:56:17;;;;;;;;-1:-1:-1;919:11:17;928:2;919:11;;:::i;:::-;;;791:150;;33602:804:11;33704:18;33725:28;;;:18;:28;;;;;;33680:13;;33807;33822:20;33725:28;33822:8;:20::i;:::-;33858:28;;;;:18;:28;;;;;;33849:38;;:8;:38::i;:::-;33790:98;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;33790:98:11;;;;;;;;;34025:20;34108;;;:8;33790:98;34108:20;;;;;;34151:28;;;;;;;;;;33790:98;;-1:-1:-1;34025:20:11;34142:38;;:8;:38::i;:::-;34216:20;;;;:8;:20;;;;;:32;;34285:4;34309:47;34347:8;34309:37;:47::i;:::-;34065:302;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;34065:302:11;;;;;;;;;;33602:804;-1:-1:-1;;;;;33602:804:11:o;30992:541::-;31085:19;31131:28;;;:18;:28;;;;;;;;;31107:53;;:23;:53;;;;;31085:75;;31061:13;;31085:19;31107:53;31085:75;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;31169:18:11;31213:28;;;:18;:28;;;;;;;;;31190:52;;:22;:52;;;;;31169:73;;31085:75;;-1:-1:-1;31169:18:11;;31190:52;;-1:-1:-1;31169:73:11;;-1:-1:-1;31169:73:11;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31276:1;31260:5;31254:19;:23;:49;;;;;31302:1;31287:4;31281:18;:22;31254:49;31251:275;;;31347:5;31353:18;31362:8;31353;:18::i;:::-;31372:4;31330:47;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;31316:62;;;;30992:541;;;:::o;31251:275::-;31466:48;31486:26;31503:8;31486:16;:26::i;:::-;31466:13;:48::i;:::-;31419:96;;;;;;;;:::i;38771:1607::-;38869:11;;38829:13;;38895:8;38891:23;;-1:-1:-1;;38905:9:11;;;;;;;;;-1:-1:-1;38905:9:11;;;38771:1607;-1:-1:-1;38771:1607:11:o;38891:23::-;38966:18;39004:1;38993:7;:3;38999:1;38993:7;:::i;:::-;38992:13;;;;:::i;:::-;38987:19;;:1;:19;:::i;:::-;38966:40;-1:-1:-1;39064:19:11;39096:15;38966:40;39109:2;39096:15;:::i;:::-;-1:-1:-1;;;;;39086:26:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39086:26:11;;39064:48;;39125:18;39146:5;;;;;;;;;;;;;;;;;39125:26;;39215:1;39208:5;39204:13;39260:2;39252:6;39248:15;39311:1;39279:777;39334:3;39331:1;39328:10;39279:777;;;39389:1;39432:12;;;;;39426:19;39527:4;39515:2;39511:14;;;;;39493:40;;39487:47;39636:2;39632:14;;;39628:25;;39614:40;;39608:47;39765:1;39761:13;;;39757:24;;39743:39;;39737:46;39885:16;;;;39871:31;;39865:38;39563:1;39559:11;;;39657:4;39604:58;;;39595:68;39688:11;;39733:57;;;39724:67;;;;39816:11;;39861:49;;39852:59;39940:3;39936:13;39969:22;;40039:1;40024:17;;;;39382:9;39279:777;;;39283:44;40088:1;40083:3;40079:11;40109:1;40104:84;;;;40207:1;40202:82;;;;40072:212;;40104:84;-1:-1:-1;;;;;40137:17:11;;40130:43;40104:84;;40202:82;-1:-1:-1;;;;;40235:17:11;;40228:41;40072:212;-1:-1:-1;;;40300:26:11;;;40307:6;38771:1607;-1:-1:-1;;;;38771:1607:11:o;15576:664::-;15742:1;15693:37;;;:25;:37;;;;;;-1:-1:-1;;;;;15693:37:11;:51;15685:109;;;;-1:-1:-1;;;15685:109:11;;39482:2:18;15685:109:11;;;39464:21:18;39521:2;39501:18;;;39494:30;39560:34;39540:18;;;39533:62;-1:-1:-1;;;39611:18:18;;;39604:43;39664:19;;15685:109:11;39280:409:18;15685:109:11;15866:14;;15823:19;;15845:37;;15866:14;;;-1:-1:-1;;;;;15866:14:11;15845:12;:37::i;:::-;15891;;;;:25;:37;;;;;;;;:60;;-1:-1:-1;;;;;;15891:60:11;-1:-1:-1;;;;;15891:60:11;;;;;;;;;16073:24;:36;;;;;;;16111:13;;15985:155;;-1:-1:-1;;;15985:155:11;;16054:4;15985:155;;;40024:34:18;40074:18;;;40067:34;;;16073:36:11;;40117:18:18;;;40110:43;16111:13:11;;;;40194:18:18;;;40187:43;40246:19;;;40239:44;;;40299:19;;;40292:44;;;;15891:60:11;;-1:-1:-1;15985:60:11;;39958:19:18;;15985:155:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16154:80:11;;16223:10;;-1:-1:-1;;;;;;16154:80:11;;;-1:-1:-1;16154:80:11;;;;;15659:581;15576:664;:::o;620:205:16:-;759:58;;;-1:-1:-1;;;;;206:32:18;;759:58:16;;;188:51:18;255:18;;;;248:34;;;759:58:16;;;;;;;;;;161:18:18;;;;759:58:16;;;;;;;;-1:-1:-1;;;;;759:58:16;-1:-1:-1;;;759:58:16;;;732:86;;752:5;;732:19;:86::i;9076:372:4:-;-1:-1:-1;;;;;9155:16:4;;9147:61;;;;-1:-1:-1;;;9147:61:4;;40549:2:18;9147:61:4;;;40531:21:18;;;40568:18;;;40561:30;40627:34;40607:18;;;40600:62;40679:18;;9147:61:4;40347:356:18;9147:61:4;7222:4;7245:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7245:16:4;:30;9218:58;;;;-1:-1:-1;;;9218:58:4;;40910:2:18;9218:58:4;;;40892:21:18;40949:2;40929:18;;;40922:30;40988;40968:18;;;40961:58;41036:18;;9218:58:4;40708:352:18;9218:58:4;-1:-1:-1;;;;;9343:13:4;;;;;;:9;:13;;;;;:18;;9360:1;;9343:13;:18;;9360:1;;9343:18;:::i;:::-;;;;-1:-1:-1;;9371:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9371:21:4;-1:-1:-1;;;;;9371:21:4;;;;;;;;9408:33;;9371:16;;;9408:33;;9371:16;;9408:33;9076:372;;:::o;11732:778::-;11882:4;-1:-1:-1;;;;;11902:13:4;;1034:20:0;1080:8;11898:606:4;;11937:72;;-1:-1:-1;;;11937:72:4;;-1:-1:-1;;;;;11937:36:4;;;;;:72;;666:10:2;;11988:4:4;;11994:7;;12003:5;;11937:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11937:72:4;;;;;;;;-1:-1:-1;;11937:72:4;;;;;;;;;;;;:::i;:::-;;;11933:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12176:13:4;;12172:266;;12218:60;;-1:-1:-1;;;12218:60:4;;;;;;;:::i;12172:266::-;12390:6;12384:13;12375:6;12371:2;12367:15;12360:38;11933:519;-1:-1:-1;;;;;;12059:51:4;-1:-1:-1;;;12059:51:4;;-1:-1:-1;12052:58:4;;11898:606;-1:-1:-1;12489:4:4;11732:778;;;;;;:::o;32857:596:11:-;32969:18;32990:28;;;:18;:28;;;;;;;;;33172:20;;;:8;:20;;;;;33067:347;;32945:13;;32990:28;;32969:18;;33067:347;;33172:20;;33261:27;;;;33353:29;;;;33067:347;;:::i;:::-;;;;-1:-1:-1;;33067:347:11;;;;;;;;;;32857:596;-1:-1:-1;;;;32857:596:11:o;906:515:1:-;963:16;1031:4;1025:11;-1:-1:-1;;;1056:3:1;1049:79;1174:14;1168:4;1164:25;1157:4;1152:3;1148:14;1141:49;-1:-1:-1;;;1219:4:1;1214:3;1210:14;1203:90;1333:4;1328:3;1325:1;1318:20;1306:32;-1:-1:-1;;;;;;;1365:22:1;;1357:57;;;;-1:-1:-1;;;1357:57:1;;43933:2:18;1357:57:1;;;43915:21:18;43972:2;43952:18;;;43945:30;-1:-1:-1;;;43991:18:18;;;43984:52;44053:18;;1357:57:1;43731:346:18;3126:706:16;3545:23;3571:69;3599:4;3571:69;;;;;;;;;;;;;;;;;3579:5;-1:-1:-1;;;;;3571:27:16;;;:69;;;;;:::i;:::-;3654:17;;3545:95;;-1:-1:-1;3654:21:16;3650:176;;3749:10;3738:30;;;;;;;;;;;;:::i;:::-;3730:85;;;;-1:-1:-1;;;3730:85:16;;44534:2:18;3730:85:16;;;44516:21:18;44573:2;44553:18;;;44546:30;44612:34;44592:18;;;44585:62;-1:-1:-1;;;44663:18:18;;;44656:40;44713:19;;3730:85:16;44332:406:18;3461:223:0;3594:12;3625:52;3647:6;3655:4;3661:1;3664:12;3594;1034:20;;4828:60;;;;-1:-1:-1;;;4828:60:0;;45352:2:18;4828:60:0;;;45334:21:18;45391:2;45371:18;;;45364:30;45430:31;45410:18;;;45403:59;45479:18;;4828:60:0;45150:353:18;4828:60:0;4900:12;4914:23;4941:6;-1:-1:-1;;;;;4941:11:0;4960:5;4967:4;4941:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4899:73;;;;4989:51;5006:7;5015:10;5027:12;4989:16;:51::i;:::-;4982:58;4548:499;-1:-1:-1;;;;;;;4548:499:0:o;7161:692::-;7307:12;7335:7;7331:516;;;-1:-1:-1;7365:10:0;7358:17;;7331:516;7476:17;;:21;7472:365;;7670:10;7664:17;7730:15;7717:10;7713:2;7709:19;7702:44;7472:365;7809:12;7802:20;;-1:-1:-1;;;7802:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;293:180:18;352:6;405:2;393:9;384:7;380:23;376:32;373:52;;;421:1;418;411:12;373:52;-1:-1:-1;444:23:18;;293:180;-1:-1:-1;293:180:18:o;478:258::-;550:1;560:113;574:6;571:1;568:13;560:113;;;650:11;;;644:18;631:11;;;624:39;596:2;589:10;560:113;;;691:6;688:1;685:13;682:48;;;-1:-1:-1;;726:1:18;708:16;;701:27;478:258::o;741:::-;783:3;821:5;815:12;848:6;843:3;836:19;864:63;920:6;913:4;908:3;904:14;897:4;890:5;886:16;864:63;:::i;:::-;981:2;960:15;-1:-1:-1;;956:29:18;947:39;;;;988:4;943:50;;741:258;-1:-1:-1;;741:258:18:o;1004:220::-;1153:2;1142:9;1135:21;1116:4;1173:45;1214:2;1203:9;1199:18;1191:6;1173:45;:::i;1411:131::-;-1:-1:-1;;;;;;1485:32:18;;1475:43;;1465:71;;1532:1;1529;1522:12;1547:245;1605:6;1658:2;1646:9;1637:7;1633:23;1629:32;1626:52;;;1674:1;1671;1664:12;1626:52;1713:9;1700:23;1732:30;1756:5;1732:30;:::i;2085:131::-;-1:-1:-1;;;;;2160:31:18;;2150:42;;2140:70;;2206:1;2203;2196:12;2221:247;2280:6;2333:2;2321:9;2312:7;2308:23;2304:32;2301:52;;;2349:1;2346;2339:12;2301:52;2388:9;2375:23;2407:31;2432:5;2407:31;:::i;2681:315::-;2749:6;2757;2810:2;2798:9;2789:7;2785:23;2781:32;2778:52;;;2826:1;2823;2816:12;2778:52;2865:9;2852:23;2884:31;2909:5;2884:31;:::i;:::-;2934:5;2986:2;2971:18;;;;2958:32;;-1:-1:-1;;;2681:315:18:o;3081:1490::-;3618:3;3607:9;3600:22;3581:4;3645:46;3686:3;3675:9;3671:19;3663:6;3645:46;:::i;:::-;3739:9;3731:6;3727:22;3722:2;3711:9;3707:18;3700:50;3773:33;3799:6;3791;3773:33;:::i;:::-;3759:47;;3854:9;3846:6;3842:22;3837:2;3826:9;3822:18;3815:50;3888:33;3914:6;3906;3888:33;:::i;:::-;3874:47;;3957:6;3952:2;3941:9;3937:18;3930:34;4001:6;3995:3;3984:9;3980:19;3973:35;4017:45;4057:3;4046:9;4042:19;4034:6;3068:4;3057:16;3045:29;;3001:75;4017:45;4111:9;4103:6;4099:22;4093:3;4082:9;4078:19;4071:51;4145:33;4171:6;4163;4145:33;:::i;:::-;4131:47;;4227:9;4219:6;4215:22;4209:3;4198:9;4194:19;4187:51;4261:33;4287:6;4279;4261:33;:::i;:::-;4247:47;;4343:9;4335:6;4331:22;4325:3;4314:9;4310:19;4303:51;4371:33;4397:6;4389;4371:33;:::i;:::-;4363:41;;;4413:44;4452:3;4441:9;4437:19;4429:6;1867:13;1860:21;1848:34;;1797:91;4413:44;1867:13;;1860:21;4506:3;4491:19;;1848:34;1867:13;;1860:21;4560:3;4545:19;;;1848:34;3081:1490;;-1:-1:-1;;;;;;;;;;3081:1490:18:o;4576:159::-;4643:20;;4703:6;4692:18;;4682:29;;4672:57;;4725:1;4722;4715:12;4740:184;4798:6;4851:2;4839:9;4830:7;4826:23;4822:32;4819:52;;;4867:1;4864;4857:12;4819:52;4890:28;4908:9;4890:28;:::i;5122:348::-;5174:8;5184:6;5238:3;5231:4;5223:6;5219:17;5215:27;5205:55;;5256:1;5253;5246:12;5205:55;-1:-1:-1;5279:20:18;;-1:-1:-1;;;;;5311:30:18;;5308:50;;;5354:1;5351;5344:12;5308:50;5391:4;5383:6;5379:17;5367:29;;5443:3;5436:4;5427:6;5419;5415:19;5411:30;5408:39;5405:59;;;5460:1;5457;5450:12;5475:479;5555:6;5563;5571;5624:2;5612:9;5603:7;5599:23;5595:32;5592:52;;;5640:1;5637;5630:12;5592:52;5676:9;5663:23;5653:33;;5737:2;5726:9;5722:18;5709:32;-1:-1:-1;;;;;5756:6:18;5753:30;5750:50;;;5796:1;5793;5786:12;5750:50;5835:59;5886:7;5877:6;5866:9;5862:22;5835:59;:::i;:::-;5475:479;;5913:8;;-1:-1:-1;5809:85:18;;-1:-1:-1;;;;5475:479:18:o;5959:456::-;6036:6;6044;6052;6105:2;6093:9;6084:7;6080:23;6076:32;6073:52;;;6121:1;6118;6111:12;6073:52;6160:9;6147:23;6179:31;6204:5;6179:31;:::i;:::-;6229:5;-1:-1:-1;6286:2:18;6271:18;;6258:32;6299:33;6258:32;6299:33;:::i;:::-;5959:456;;6351:7;;-1:-1:-1;;;6405:2:18;6390:18;;;;6377:32;;5959:456::o;6420:248::-;6488:6;6496;6549:2;6537:9;6528:7;6524:23;6520:32;6517:52;;;6565:1;6562;6555:12;6517:52;-1:-1:-1;;6588:23:18;;;6658:2;6643:18;;;6630:32;;-1:-1:-1;6420:248:18:o;6925:127::-;6986:10;6981:3;6977:20;6974:1;6967:31;7017:4;7014:1;7007:15;7041:4;7038:1;7031:15;7057:632;7122:5;-1:-1:-1;;;;;7193:2:18;7185:6;7182:14;7179:40;;;7199:18;;:::i;:::-;7274:2;7268:9;7242:2;7328:15;;-1:-1:-1;;7324:24:18;;;7350:2;7320:33;7316:42;7304:55;;;7374:18;;;7394:22;;;7371:46;7368:72;;;7420:18;;:::i;:::-;7460:10;7456:2;7449:22;7489:6;7480:15;;7519:6;7511;7504:22;7559:3;7550:6;7545:3;7541:16;7538:25;7535:45;;;7576:1;7573;7566:12;7535:45;7626:6;7621:3;7614:4;7606:6;7602:17;7589:44;7681:1;7674:4;7665:6;7657;7653:19;7649:30;7642:41;;;;7057:632;;;;;:::o;7694:519::-;7772:6;7780;7833:2;7821:9;7812:7;7808:23;7804:32;7801:52;;;7849:1;7846;7839:12;7801:52;7885:9;7872:23;7862:33;;7946:2;7935:9;7931:18;7918:32;-1:-1:-1;;;;;7965:6:18;7962:30;7959:50;;;8005:1;8002;7995:12;7959:50;8028:22;;8081:4;8073:13;;8069:27;-1:-1:-1;8059:55:18;;8110:1;8107;8100:12;8059:55;8133:74;8199:7;8194:2;8181:16;8176:2;8172;8168:11;8133:74;:::i;:::-;8123:84;;;7694:519;;;;;:::o;8218:319::-;8285:6;8293;8346:2;8334:9;8325:7;8321:23;8317:32;8314:52;;;8362:1;8359;8352:12;8314:52;8401:9;8388:23;8420:31;8445:5;8420:31;:::i;:::-;8470:5;-1:-1:-1;8494:37:18;8527:2;8512:18;;8494:37;:::i;:::-;8484:47;;8218:319;;;;;:::o;8542:337::-;8608:6;8616;8669:2;8657:9;8648:7;8644:23;8640:32;8637:52;;;8685:1;8682;8675:12;8637:52;8721:9;8708:23;8698:33;;8781:2;8770:9;8766:18;8753:32;8825:4;8818:5;8814:16;8807:5;8804:27;8794:55;;8845:1;8842;8835:12;8794:55;8868:5;8858:15;;;8542:337;;;;;:::o;8884:387::-;8960:6;8968;8976;9029:2;9017:9;9008:7;9004:23;9000:32;8997:52;;;9045:1;9042;9035:12;8997:52;9081:9;9068:23;9058:33;;9141:2;9130:9;9126:18;9113:32;9154:31;9179:5;9154:31;:::i;:::-;9204:5;-1:-1:-1;9228:37:18;9261:2;9246:18;;9228:37;:::i;:::-;9218:47;;8884:387;;;;;:::o;9276:118::-;9362:5;9355:13;9348:21;9341:5;9338:32;9328:60;;9384:1;9381;9374:12;9399:382;9464:6;9472;9525:2;9513:9;9504:7;9500:23;9496:32;9493:52;;;9541:1;9538;9531:12;9493:52;9580:9;9567:23;9599:31;9624:5;9599:31;:::i;:::-;9649:5;-1:-1:-1;9706:2:18;9691:18;;9678:32;9719:30;9678:32;9719:30;:::i;9786:315::-;9854:6;9862;9915:2;9903:9;9894:7;9890:23;9886:32;9883:52;;;9931:1;9928;9921:12;9883:52;9967:9;9954:23;9944:33;;10027:2;10016:9;10012:18;9999:32;10040:31;10065:5;10040:31;:::i;10106:795::-;10201:6;10209;10217;10225;10278:3;10266:9;10257:7;10253:23;10249:33;10246:53;;;10295:1;10292;10285:12;10246:53;10334:9;10321:23;10353:31;10378:5;10353:31;:::i;:::-;10403:5;-1:-1:-1;10460:2:18;10445:18;;10432:32;10473:33;10432:32;10473:33;:::i;:::-;10525:7;-1:-1:-1;10579:2:18;10564:18;;10551:32;;-1:-1:-1;10634:2:18;10619:18;;10606:32;-1:-1:-1;;;;;10650:30:18;;10647:50;;;10693:1;10690;10683:12;10647:50;10716:22;;10769:4;10761:13;;10757:27;-1:-1:-1;10747:55:18;;10798:1;10795;10788:12;10747:55;10821:74;10887:7;10882:2;10869:16;10864:2;10860;10856:11;10821:74;:::i;:::-;10811:84;;;10106:795;;;;;;;:::o;10906:1733::-;11079:6;11087;11095;11103;11111;11119;11127;11135;11143;11151;11159:7;11168;11222:3;11210:9;11201:7;11197:23;11193:33;11190:53;;;11239:1;11236;11229:12;11190:53;-1:-1:-1;;;;;11271:9:18;11258:23;11255:47;11252:67;;;11315:1;11312;11305:12;11252:67;11354:76;11422:7;11409:9;11396:23;11385:9;11381:39;11354:76;:::i;:::-;11449:8;;-1:-1:-1;11476:8:18;-1:-1:-1;;;;;;11527:2:18;11512:18;;11499:32;11496:56;11493:76;;;11565:1;11562;11555:12;11493:76;11604:85;11681:7;11674:2;11663:9;11659:18;11646:32;11635:9;11631:48;11604:85;:::i;:::-;11708:8;;-1:-1:-1;11735:8:18;-1:-1:-1;;;;;;11786:2:18;11771:18;;11758:32;11755:56;11752:76;;;11824:1;11821;11814:12;11752:76;11863:85;11940:7;11933:2;11922:9;11918:18;11905:32;11894:9;11890:48;11863:85;:::i;:::-;11967:8;;-1:-1:-1;11994:8:18;-1:-1:-1;12049:2:18;12034:18;;12021:32;;-1:-1:-1;12100:3:18;12085:19;;12072:33;;-1:-1:-1;;;;;;12148:3:18;12133:19;;12120:33;12117:57;12114:77;;;12187:1;12184;12177:12;12114:77;12226:86;12304:7;12296:3;12285:9;12281:19;12268:33;12257:9;12253:49;12226:86;:::i;:::-;12331:8;;-1:-1:-1;12358:8:18;-1:-1:-1;;;;;;12409:3:18;12394:19;;12381:33;12378:57;12375:77;;;12448:1;12445;12438:12;12375:77;12489:86;12567:7;12559:3;12548:9;12544:19;12531:33;12520:9;12516:49;12489:86;:::i;:::-;12595:9;12584:20;;12624:9;12613:20;;;;10906:1733;;;;;;;;;;;;;;:::o;12644:411::-;12715:6;12723;12776:2;12764:9;12755:7;12751:23;12747:32;12744:52;;;12792:1;12789;12782:12;12744:52;12832:9;12819:23;-1:-1:-1;;;;;12857:6:18;12854:30;12851:50;;;12897:1;12894;12887:12;12851:50;12936:59;12987:7;12978:6;12967:9;12963:22;12936:59;:::i;:::-;13014:8;;12910:85;;-1:-1:-1;12644:411:18;-1:-1:-1;;;;12644:411:18:o;13060:388::-;13128:6;13136;13189:2;13177:9;13168:7;13164:23;13160:32;13157:52;;;13205:1;13202;13195:12;13157:52;13244:9;13231:23;13263:31;13288:5;13263:31;:::i;:::-;13313:5;-1:-1:-1;13370:2:18;13355:18;;13342:32;13383:33;13342:32;13383:33;:::i;13453:919::-;13560:6;13568;13576;13584;13592;13600;13653:3;13641:9;13632:7;13628:23;13624:33;13621:53;;;13670:1;13667;13660:12;13621:53;13706:9;13693:23;13683:33;;13767:2;13756:9;13752:18;13739:32;-1:-1:-1;;;;;13831:2:18;13823:6;13820:14;13817:34;;;13847:1;13844;13837:12;13817:34;13886:59;13937:7;13928:6;13917:9;13913:22;13886:59;:::i;:::-;13964:8;;-1:-1:-1;13860:85:18;-1:-1:-1;14052:2:18;14037:18;;14024:32;;-1:-1:-1;14068:16:18;;;14065:36;;;14097:1;14094;14087:12;14065:36;;14136:61;14189:7;14178:8;14167:9;14163:24;14136:61;:::i;:::-;14216:8;;-1:-1:-1;14110:87:18;-1:-1:-1;;14301:2:18;14286:18;;14273:32;14314:28;14273:32;14314:28;:::i;:::-;14361:5;14351:15;;;13453:919;;;;;;;;:::o;14644:241::-;14700:6;14753:2;14741:9;14732:7;14728:23;14724:32;14721:52;;;14769:1;14766;14759:12;14721:52;14808:9;14795:23;14827:28;14849:5;14827:28;:::i;14890:632::-;15061:2;15113:21;;;15183:13;;15086:18;;;15205:22;;;15032:4;;15061:2;15284:15;;;;15258:2;15243:18;;;15032:4;15327:169;15341:6;15338:1;15335:13;15327:169;;;15402:13;;15390:26;;15471:15;;;;15436:12;;;;15363:1;15356:9;15327:169;;;-1:-1:-1;15513:3:18;;14890:632;-1:-1:-1;;;;;;14890:632:18:o;15527:380::-;15606:1;15602:12;;;;15649;;;15670:61;;15724:4;15716:6;15712:17;15702:27;;15670:61;15777:2;15769:6;15766:14;15746:18;15743:38;15740:161;;;15823:10;15818:3;15814:20;15811:1;15804:31;15858:4;15855:1;15848:15;15886:4;15883:1;15876:15;15740:161;;15527:380;;;:::o;16038:973::-;16123:12;;16088:3;;16178:1;16198:18;;;;16251;;;;16278:61;;16332:4;16324:6;16320:17;16310:27;;16278:61;16358:2;16406;16398:6;16395:14;16375:18;16372:38;16369:161;;;16452:10;16447:3;16443:20;16440:1;16433:31;16487:4;16484:1;16477:15;16515:4;16512:1;16505:15;16369:161;16546:18;16573:104;;;;16691:1;16686:319;;;;16539:466;;16573:104;-1:-1:-1;;16606:24:18;;16594:37;;16651:16;;;;-1:-1:-1;16573:104:18;;16686:319;15985:1;15978:14;;;16022:4;16009:18;;16780:1;16794:165;16808:6;16805:1;16802:13;16794:165;;;16886:14;;16873:11;;;16866:35;16929:16;;;;16823:10;;16794:165;;;16798:3;;16988:6;16983:3;16979:16;16972:23;;16539:466;;;;;;;16038:973;;;;:::o;17016:684::-;17341:3;17379:6;17373:13;17395:53;17441:6;17436:3;17429:4;17421:6;17417:17;17395:53;:::i;:::-;17467:51;17510:6;17505:3;17501:16;17493:6;17467:51;:::i;:::-;17457:61;;-1:-1:-1;;;17534:2:18;17527:17;17575:6;17569:13;17591:62;17644:8;17640:1;17636:2;17632:10;17625:4;17617:6;17613:17;17591:62;:::i;:::-;17673:17;17692:1;17669:25;;17016:684;-1:-1:-1;;;;;17016:684:18:o;17705:921::-;17985:3;18023:6;18017:13;18039:53;18085:6;18080:3;18073:4;18065:6;18061:17;18039:53;:::i;:::-;18123:6;18118:3;18114:16;18101:29;;18153:66;18146:5;18139:81;18254:66;18247:4;18240:5;18236:16;18229:92;18353:66;18348:2;18341:5;18337:14;18330:90;-1:-1:-1;;;18447:2:18;18440:5;18436:14;18429:31;18491:6;18485:13;18507:67;18565:8;18559:3;18552:5;18548:15;18541:4;18533:6;18529:17;18507:67;:::i;:::-;18594:20;18616:3;18590:30;;17705:921;-1:-1:-1;;;;17705:921:18:o;18631:750::-;18863:3;18901:6;18895:13;18917:53;18963:6;18958:3;18951:4;18943:6;18939:17;18917:53;:::i;:::-;19031:66;18992:16;;19017:81;;;-1:-1:-1;19132:66:18;19125:4;19114:16;;19107:92;19231:66;19226:2;19215:14;;19208:90;-1:-1:-1;;;19325:2:18;19314:14;;19307:37;19371:3;19360:15;;18631:750;-1:-1:-1;18631:750:18:o;20626:356::-;20828:2;20810:21;;;20847:18;;;20840:30;20906:34;20901:2;20886:18;;20879:62;20973:2;20958:18;;20626:356::o;21656:327::-;21858:2;21840:21;;;21897:1;21877:18;;;21870:29;-1:-1:-1;;;21930:2:18;21915:18;;21908:34;21974:2;21959:18;;21656:327::o;21988:390::-;22147:2;22136:9;22129:21;22186:6;22181:2;22170:9;22166:18;22159:34;22243:6;22235;22230:2;22219:9;22215:18;22202:48;22299:1;22270:22;;;22294:2;22266:31;;;22259:42;;;;22362:2;22341:15;;;-1:-1:-1;;22337:29:18;22322:45;22318:54;;21988:390;-1:-1:-1;21988:390:18:o;22383:413::-;22585:2;22567:21;;;22624:2;22604:18;;;22597:30;22663:34;22658:2;22643:18;;22636:62;-1:-1:-1;;;22729:2:18;22714:18;;22707:47;22786:3;22771:19;;22383:413::o;23136:127::-;23197:10;23192:3;23188:20;23185:1;23178:31;23228:4;23225:1;23218:15;23252:4;23249:1;23242:15;23268:168;23308:7;23374:1;23370;23366:6;23362:14;23359:1;23356:21;23351:1;23344:9;23337:17;23333:45;23330:71;;;23381:18;;:::i;:::-;-1:-1:-1;23421:9:18;;23268:168::o;23441:127::-;23502:10;23497:3;23493:20;23490:1;23483:31;23533:4;23530:1;23523:15;23557:4;23554:1;23547:15;23573:120;23613:1;23639;23629:35;;23644:18;;:::i;:::-;-1:-1:-1;23678:9:18;;23573:120::o;24058:125::-;24098:4;24126:1;24123;24120:8;24117:34;;;24131:18;;:::i;:::-;-1:-1:-1;24168:9:18;;24058:125::o;24188:251::-;24258:6;24311:2;24299:9;24290:7;24286:23;24282:32;24279:52;;;24327:1;24324;24317:12;24279:52;24359:9;24353:16;24378:31;24403:5;24378:31;:::i;24444:329::-;24646:2;24628:21;;;24685:1;24665:18;;;24658:29;-1:-1:-1;;;24718:2:18;24703:18;;24696:36;24764:2;24749:18;;24444:329::o;24778:334::-;24980:2;24962:21;;;25019:2;24999:18;;;24992:30;-1:-1:-1;;;25053:2:18;25038:18;;25031:40;25103:2;25088:18;;24778:334::o;25938:217::-;25977:4;26006:6;26062:10;;;;26032;;26084:12;;;26081:38;;;26099:18;;:::i;:::-;26136:13;;25938:217;-1:-1:-1;;;25938:217:18:o;27894:470::-;28073:3;28111:6;28105:13;28127:53;28173:6;28168:3;28161:4;28153:6;28149:17;28127:53;:::i;:::-;28243:13;;28202:16;;;;28265:57;28243:13;28202:16;28299:4;28287:17;;28265:57;:::i;:::-;28338:20;;27894:470;-1:-1:-1;;;;27894:470:18:o;28369:815::-;28750:3;28788:6;28782:13;28804:53;28850:6;28845:3;28838:4;28830:6;28826:17;28804:53;:::i;:::-;-1:-1:-1;;;28879:16:18;;;28904:51;;;28980:13;;29002:66;28980:13;29054:2;29043:14;;29036:4;29024:17;;29002:66;:::i;:::-;-1:-1:-1;;;29131:2:18;29087:20;;;;29123:11;;;29116:35;29175:2;29167:11;;28369:815;-1:-1:-1;;;;28369:815:18:o;29189:448::-;29451:31;29446:3;29439:44;29421:3;29512:6;29506:13;29528:62;29583:6;29578:2;29573:3;29569:12;29562:4;29554:6;29550:17;29528:62;:::i;:::-;29610:16;;;;29628:2;29606:25;;29189:448;-1:-1:-1;;29189:448:18:o;30314:135::-;30353:3;-1:-1:-1;;30374:17:18;;30371:43;;;30394:18;;:::i;:::-;-1:-1:-1;30441:1:18;30430:13;;30314:135::o;30861:184::-;30931:6;30984:2;30972:9;30963:7;30959:23;30955:32;30952:52;;;31000:1;30997;30990:12;30952:52;-1:-1:-1;31023:16:18;;30861:184;-1:-1:-1;30861:184:18:o;32732:112::-;32764:1;32790;32780:35;;32795:18;;:::i;:::-;-1:-1:-1;32829:9:18;;32732:112::o;32849:128::-;32889:3;32920:1;32916:6;32913:1;32910:13;32907:39;;;32926:18;;:::i;:::-;-1:-1:-1;32962:9:18;;32849:128::o;32982:127::-;33043:10;33038:3;33034:20;33031:1;33024:31;33074:4;33071:1;33064:15;33098:4;33095:1;33088:15;35337:414;35539:2;35521:21;;;35578:2;35558:18;;;35551:30;35617:34;35612:2;35597:18;;35590:62;-1:-1:-1;;;35683:2:18;35668:18;;35661:48;35741:3;35726:19;;35337:414::o;35756:714::-;36081:3;36109:38;36143:3;36135:6;36109:38;:::i;:::-;36176:6;36170:13;36192:52;36237:6;36233:2;36226:4;36218:6;36214:17;36192:52;:::i;:::-;-1:-1:-1;;;36266:15:18;;36290:18;;;36333:13;;36355:65;36333:13;36407:1;36396:13;;36389:4;36377:17;;36355:65;:::i;:::-;36440:20;36462:1;36436:28;;35756:714;-1:-1:-1;;;;;35756:714:18:o;36475:1681::-;-1:-1:-1;;;37315:45:18;;37297:3;37379:47;37422:2;37413:12;;37405:6;37379:47;:::i;:::-;-1:-1:-1;;;37442:2:18;37435:17;37481:6;37475:13;37497:60;37550:6;37546:1;37542:2;37538:10;37531:4;37523:6;37519:17;37497:60;:::i;:::-;-1:-1:-1;;;37615:1:18;37576:15;;;;37607:10;;;37600:70;37689:46;37731:2;37723:11;;37715:6;37689:46;:::i;:::-;-1:-1:-1;;;37744:63:18;;37832:13;;37679:56;;-1:-1:-1;37854:63:18;37832:13;37903:2;37895:11;;37888:4;37876:17;;37854:63;:::i;:::-;-1:-1:-1;;;37977:2:18;37936:17;;;;37969:11;;;37962:36;38023:13;;38045:63;38023:13;38094:2;38086:11;;38079:4;38067:17;;38045:63;:::i;:::-;38128:17;38147:2;38124:26;;36475:1681;-1:-1:-1;;;;;;;36475:1681:18:o;38161:664::-;38388:3;38426:6;38420:13;38442:53;38488:6;38483:3;38476:4;38468:6;38464:17;38442:53;:::i;:::-;38558:13;;38517:16;;;;38580:57;38558:13;38517:16;38614:4;38602:17;;38580:57;:::i;:::-;38704:13;;38659:20;;;38726:57;38704:13;38659:20;38760:4;38748:17;;38726:57;:::i;:::-;38799:20;;38161:664;-1:-1:-1;;;;;38161:664:18:o;38830:445::-;39092:28;39087:3;39080:41;39062:3;39150:6;39144:13;39166:62;39221:6;39216:2;39211:3;39207:12;39200:4;39192:6;39188:17;39166:62;:::i;:::-;39248:16;;;;39266:2;39244:25;;38830:445;-1:-1:-1;;38830:445:18:o;41065:489::-;-1:-1:-1;;;;;41334:15:18;;;41316:34;;41386:15;;41381:2;41366:18;;41359:43;41433:2;41418:18;;41411:34;;;41481:3;41476:2;41461:18;;41454:31;;;41259:4;;41502:46;;41528:19;;41520:6;41502:46;:::i;:::-;41494:54;41065:489;-1:-1:-1;;;;;;41065:489:18:o;41559:249::-;41628:6;41681:2;41669:9;41660:7;41656:23;41652:32;41649:52;;;41697:1;41694;41687:12;41649:52;41729:9;41723:16;41748:30;41772:5;41748:30;:::i;41813:1913::-;-1:-1:-1;;;42857:55:18;;42942:66;42937:2;42928:12;;42921:88;-1:-1:-1;;;43073:2:18;43064:12;;43057:24;;;-1:-1:-1;;43100:47:18;43143:2;43134:12;;43126:6;43100:47;:::i;:::-;-1:-1:-1;;;43191:14:18;;;43233:66;43229:1;43221:10;;43214:86;-1:-1:-1;;;43324:2:18;43316:11;;43309:38;43366:46;43408:2;43400:11;;43392:6;43366:46;:::i;:::-;43356:56;;43432:2;43428;43421:14;;43463:66;43459:1;43455:2;43451:10;43444:86;43559:2;43554;43550;43546:11;43539:23;43581:46;43623:2;43619;43615:11;43607:6;43581:46;:::i;:::-;-1:-1:-1;;;43636:26:18;;-1:-1:-1;;;43686:1:18;43678:10;;43671:23;43718:1;43710:10;;41813:1913;-1:-1:-1;;;;;;;41813:1913:18:o;44082:245::-;44149:6;44202:2;44190:9;44181:7;44177:23;44173:32;44170:52;;;44218:1;44215;44208:12;44170:52;44250:9;44244:16;44269:28;44291:5;44269:28;:::i;45508:274::-;45637:3;45675:6;45669:13;45691:53;45737:6;45732:3;45725:4;45717:6;45713:17;45691:53;:::i;:::-;45760:16;;;;;45508:274;-1:-1:-1;;45508:274:18:o

Swarm Source

ipfs://96772b62db352165086235cb24be2231481653d0ff6e366d1f6ad784e0c34119
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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