ETH Price: $1,474.32 (-5.97%)

Contract

0x37c9553A3d8Bd4b9bC1BE4D6B4722B2AA490781E
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer From219306442025-02-26 12:55:5941 days ago1740574559IN
0x37c9553A...AA490781E
0 ETH0.000334673.78121533
Set Approval For...162806342022-12-28 3:42:23832 days ago1672198943IN
0x37c9553A...AA490781E
0 ETH0.0007079615.30694382
Set Approval For...158898662022-11-03 13:42:59887 days ago1667482979IN
0x37c9553A...AA490781E
0 ETH0.0007029315.22204969
Set Approval For...151620162022-07-17 19:32:56996 days ago1658086376IN
0x37c9553A...AA490781E
0 ETH0.0008856936.37219845
Transfer From148654742022-05-29 8:32:351045 days ago1653813155IN
0x37c9553A...AA490781E
0 ETH0.0007284311.02462881
Set Approval For...146363012022-04-22 18:35:121082 days ago1650652512IN
0x37c9553A...AA490781E
0 ETH0.0032448670.13958395
Set Approval For...145630102022-04-11 7:13:571093 days ago1649661237IN
0x37c9553A...AA490781E
0 ETH0.0009655720.8714647
Set Approval For...145516202022-04-09 12:57:011095 days ago1649509021IN
0x37c9553A...AA490781E
0 ETH0.001569833.93214829
Set Approval For...144947912022-03-31 15:33:411104 days ago1648740821IN
0x37c9553A...AA490781E
0 ETH0.0056237121.5593496
Transfer From143049522022-03-02 2:39:291133 days ago1646188769IN
0x37c9553A...AA490781E
0 ETH0.0042942148.51068123
Transfer From143046192022-03-02 1:17:231133 days ago1646183843IN
0x37c9553A...AA490781E
0 ETH0.0043921149.61668206
Set Approval For...142554752022-02-22 11:02:591141 days ago1645527779IN
0x37c9553A...AA490781E
0 ETH0.0020213843.69344258
Set Approval For...142299452022-02-18 11:53:071145 days ago1645185187IN
0x37c9553A...AA490781E
0 ETH0.0030534766.00263335
Set Approval For...142293002022-02-18 9:35:591145 days ago1645176959IN
0x37c9553A...AA490781E
0 ETH0.00254515104.51960272
Set Approval For...142140002022-02-16 0:34:581147 days ago1644971698IN
0x37c9553A...AA490781E
0 ETH0.00682083147.43601784
Set Approval For...142139222022-02-16 0:17:291147 days ago1644970649IN
0x37c9553A...AA490781E
0 ETH0.01172886253.525714
Destroy Random W...142068132022-02-14 21:59:431148 days ago1644875983IN
0x37c9553A...AA490781E
0.08 ETH0.0041032656.52428458
Destroy Random W...142068082022-02-14 21:58:371148 days ago1644875917IN
0x37c9553A...AA490781E
0.04 ETH0.0044130860.79214903
Destroy Random W...142067992022-02-14 21:56:461148 days ago1644875806IN
0x37c9553A...AA490781E
0.02 ETH0.0046705964.33946048
Destroy Random W...142066342022-02-14 21:24:591149 days ago1644873899IN
0x37c9553A...AA490781E
0.01 ETH0.0047714565.72884519
Destroy Random W...142065362022-02-14 21:01:341149 days ago1644872494IN
0x37c9553A...AA490781E
0.005 ETH0.00952068131.15161282
Transfer From141697562022-02-09 4:39:291154 days ago1644381569IN
0x37c9553A...AA490781E
0 ETH0.0076171186.06032861
Destroy Random W...140929972022-01-28 8:06:591166 days ago1643357219IN
0x37c9553A...AA490781E
0 ETH0.0065054100.01385026
Destroy Random W...140929932022-01-28 8:05:441166 days ago1643357144IN
0x37c9553A...AA490781E
0 ETH0.0064652199.39606431
Destroy Random W...140929872022-01-28 8:04:001166 days ago1643357040IN
0x37c9553A...AA490781E
0 ETH0.0061421194.42866884
View all transactions

Latest 11 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
-142068132022-02-14 21:59:431148 days ago1644875983
0x37c9553A...AA490781E
0.08 ETH
-142068082022-02-14 21:58:371148 days ago1644875917
0x37c9553A...AA490781E
0.04 ETH
-142067992022-02-14 21:56:461148 days ago1644875806
0x37c9553A...AA490781E
0.02 ETH
-142066342022-02-14 21:24:591149 days ago1644873899
0x37c9553A...AA490781E
0.01 ETH
-142065362022-02-14 21:01:341149 days ago1644872494
0x37c9553A...AA490781E
0.005 ETH
-139987572022-01-13 18:23:291181 days ago1642098209
0x37c9553A...AA490781E
0.06875 ETH
-139987572022-01-13 18:23:291181 days ago1642098209
0x37c9553A...AA490781E
0.1375 ETH
-139987572022-01-13 18:23:291181 days ago1642098209
0x37c9553A...AA490781E
0.06875 ETH
-139243112022-01-02 6:04:081192 days ago1641103448
0x37c9553A...AA490781E
0.75 ETH
-139243112022-01-02 6:04:081192 days ago1641103448
0x37c9553A...AA490781E
1.5 ETH
-139243112022-01-02 6:04:081192 days ago1641103448
0x37c9553A...AA490781E
0.75 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Combine

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-31
*/

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



pragma solidity ^0.8.6;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "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);
    }

}
// File: Roots.sol



pragma solidity ^0.8.6;

library Roots {

// calculates a^(1/n) to dp decimal places
    // maxIts bounds the number of iterations performed
    function nthRoot(uint _a, uint _n, uint _dp, uint _maxIts) pure internal returns(uint) {
        assert (_n > 1);

        // The scale factor is a crude way to turn everything into integer calcs.
        // Actually do (a * (10 ^ ((dp + 1) * n))) ^ (1/n)
        // We calculate to one extra dp and round at the end
        uint one = 10 ** (1 + _dp);
        uint a0 = one ** _n * _a;

        // Initial guess: 1.0
        uint xNew = one;

        uint iter = 0;
        while (iter < _maxIts) {
            uint x = xNew;
            uint t0 = x ** (_n - 1);
            if (x * t0 > a0) {
                xNew = x - (x - a0 / t0) / _n;
            } else {
                xNew = x + (a0 / t0 - x) / _n;
            }
            ++iter;
            if(xNew == x) {
                break;
            }
        }

        // Round to nearest in the last dp.
        return (xNew + 5) / 10;
    }
}
// File: Base64.sol



pragma solidity >=0.6.0;

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

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

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}
// File: ABDKMath64x64.sol


/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity ^0.8.6;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
  /*
   * Minimum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

  /*
   * Maximum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

  /**
   * Convert signed 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromInt (int256 x) internal pure returns (int128) {
    unchecked {
      require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (x << 64);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 64-bit integer number
   * rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64-bit integer number
   */
  function toInt (int128 x) internal pure returns (int64) {
    unchecked {
      return int64 (x >> 64);
    }
  }

  /**
   * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromUInt (uint256 x) internal pure returns (int128) {
    unchecked {
      require (x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (int256 (x << 64));
    }
  }

  /**
   * Convert signed 64.64 fixed point number into unsigned 64-bit integer
   * number rounding down.  Revert on underflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return unsigned 64-bit integer number
   */
  function toUInt (int128 x) internal pure returns (uint64) {
    unchecked {
      require (x >= 0);
      return uint64 (uint128 (x >> 64));
    }
  }

  /**
   * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
   * number rounding down.  Revert on overflow.
   *
   * @param x signed 128.128-bin fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function from128x128 (int256 x) internal pure returns (int128) {
    unchecked {
      int256 result = x >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 128.128 fixed point
   * number.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 128.128 fixed point number
   */
  function to128x128 (int128 x) internal pure returns (int256) {
    unchecked {
      return int256 (x) << 64;
    }
  }

  /**
   * Calculate x + y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function add (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) + y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x - y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sub (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) - y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding down.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function mul (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) * y >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
   * number and y is signed 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y signed 256-bit integer number
   * @return signed 256-bit integer number
   */
  function muli (int128 x, int256 y) internal pure returns (int256) {
    unchecked {
      if (x == MIN_64x64) {
        require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
          y <= 0x1000000000000000000000000000000000000000000000000);
        return -y << 63;
      } else {
        bool negativeResult = false;
        if (x < 0) {
          x = -x;
          negativeResult = true;
        }
        if (y < 0) {
          y = -y; // We rely on overflow behavior here
          negativeResult = !negativeResult;
        }
        uint256 absoluteResult = mulu (x, uint256 (y));
        if (negativeResult) {
          require (absoluteResult <=
            0x8000000000000000000000000000000000000000000000000000000000000000);
          return -int256 (absoluteResult); // We rely on overflow behavior here
        } else {
          require (absoluteResult <=
            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
          return int256 (absoluteResult);
        }
      }
    }
  }

  /**
   * Calculate x * y rounding down, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y unsigned 256-bit integer number
   * @return unsigned 256-bit integer number
   */
  function mulu (int128 x, uint256 y) internal pure returns (uint256) {
    unchecked {
      if (y == 0) return 0;

      require (x >= 0);

      uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
      uint256 hi = uint256 (int256 (x)) * (y >> 128);

      require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      hi <<= 64;

      require (hi <=
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
      return hi + lo;
    }
  }

  /**
   * Calculate x / y rounding towards zero.  Revert on overflow or when y is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function div (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      int256 result = (int256 (x) << 64) / y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are signed 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x signed 256-bit integer number
   * @param y signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divi (int256 x, int256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);

      bool negativeResult = false;
      if (x < 0) {
        x = -x; // We rely on overflow behavior here
        negativeResult = true;
      }
      if (y < 0) {
        y = -y; // We rely on overflow behavior here
        negativeResult = !negativeResult;
      }
      uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
      if (negativeResult) {
        require (absoluteResult <= 0x80000000000000000000000000000000);
        return -int128 (absoluteResult); // We rely on overflow behavior here
      } else {
        require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int128 (absoluteResult); // We rely on overflow behavior here
      }
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divu (uint256 x, uint256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      uint128 result = divuu (x, y);
      require (result <= uint128 (MAX_64x64));
      return int128 (result);
    }
  }

  /**
   * Calculate -x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function neg (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return -x;
    }
  }

  /**
   * Calculate |x|.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function abs (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return x < 0 ? -x : x;
    }
  }

  /**
   * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function inv (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != 0);
      int256 result = int256 (0x100000000000000000000000000000000) / x;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function avg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      return int128 ((int256 (x) + int256 (y)) >> 1);
    }
  }

  /**
   * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
   * Revert on overflow or in case x * y is negative.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function gavg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 m = int256 (x) * int256 (y);
      require (m >= 0);
      require (m <
          0x4000000000000000000000000000000000000000000000000000000000000000);
      return int128 (sqrtu (uint256 (m)));
    }
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y uint256 value
   * @return signed 64.64-bit fixed point number
   */
  function pow (int128 x, uint256 y) internal pure returns (int128) {
    unchecked {
      bool negative = x < 0 && y & 1 == 1;

      uint256 absX = uint128 (x < 0 ? -x : x);
      uint256 absResult;
      absResult = 0x100000000000000000000000000000000;

      if (absX <= 0x10000000000000000) {
        absX <<= 63;
        while (y != 0) {
          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x2 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x4 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x8 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          y >>= 4;
        }

        absResult >>= 64;
      } else {
        uint256 absXShift = 63;
        if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
        if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
        if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
        if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
        if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
        if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }

        uint256 resultShift = 0;
        while (y != 0) {
          require (absXShift < 64);

          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
            resultShift += absXShift;
            if (absResult > 0x100000000000000000000000000000000) {
              absResult >>= 1;
              resultShift += 1;
            }
          }
          absX = absX * absX >> 127;
          absXShift <<= 1;
          if (absX >= 0x100000000000000000000000000000000) {
              absX >>= 1;
              absXShift += 1;
          }

          y >>= 1;
        }

        require (resultShift < 64);
        absResult >>= 64 - resultShift;
      }
      int256 result = negative ? -int256 (absResult) : int256 (absResult);
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down.  Revert if x < 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sqrt (int128 x) internal pure returns (int128) {
    unchecked {
      require (x >= 0);
      return int128 (sqrtu (uint256 (int256 (x)) << 64));
    }
  }

  /**
   * Calculate binary logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function log_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      int256 msb = 0;
      int256 xc = x;
      if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      int256 result = msb - 64 << 64;
      uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
      for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
        ux *= ux;
        uint256 b = ux >> 255;
        ux >>= 127 + b;
        result += bit * int256 (b);
      }

      return int128 (result);
    }
  }

  /**
   * Calculate natural logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function ln (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      return int128 (int256 (
          uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
    }
  }

  /**
   * Calculate binary exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      uint256 result = 0x80000000000000000000000000000000;

      if (x & 0x8000000000000000 > 0)
        result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
      if (x & 0x4000000000000000 > 0)
        result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
      if (x & 0x2000000000000000 > 0)
        result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
      if (x & 0x1000000000000000 > 0)
        result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
      if (x & 0x800000000000000 > 0)
        result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
      if (x & 0x400000000000000 > 0)
        result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
      if (x & 0x200000000000000 > 0)
        result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
      if (x & 0x100000000000000 > 0)
        result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
      if (x & 0x80000000000000 > 0)
        result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
      if (x & 0x40000000000000 > 0)
        result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
      if (x & 0x20000000000000 > 0)
        result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
      if (x & 0x10000000000000 > 0)
        result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
      if (x & 0x8000000000000 > 0)
        result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
      if (x & 0x4000000000000 > 0)
        result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
      if (x & 0x2000000000000 > 0)
        result = result * 0x1000162E525EE054754457D5995292026 >> 128;
      if (x & 0x1000000000000 > 0)
        result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
      if (x & 0x800000000000 > 0)
        result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
      if (x & 0x400000000000 > 0)
        result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
      if (x & 0x200000000000 > 0)
        result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
      if (x & 0x100000000000 > 0)
        result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
      if (x & 0x80000000000 > 0)
        result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
      if (x & 0x40000000000 > 0)
        result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
      if (x & 0x20000000000 > 0)
        result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
      if (x & 0x10000000000 > 0)
        result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
      if (x & 0x8000000000 > 0)
        result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
      if (x & 0x4000000000 > 0)
        result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
      if (x & 0x2000000000 > 0)
        result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
      if (x & 0x1000000000 > 0)
        result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
      if (x & 0x800000000 > 0)
        result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
      if (x & 0x400000000 > 0)
        result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
      if (x & 0x200000000 > 0)
        result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
      if (x & 0x100000000 > 0)
        result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
      if (x & 0x80000000 > 0)
        result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
      if (x & 0x40000000 > 0)
        result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
      if (x & 0x20000000 > 0)
        result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
      if (x & 0x10000000 > 0)
        result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
      if (x & 0x8000000 > 0)
        result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
      if (x & 0x4000000 > 0)
        result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
      if (x & 0x2000000 > 0)
        result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
      if (x & 0x1000000 > 0)
        result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
      if (x & 0x800000 > 0)
        result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
      if (x & 0x400000 > 0)
        result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
      if (x & 0x200000 > 0)
        result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
      if (x & 0x100000 > 0)
        result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
      if (x & 0x80000 > 0)
        result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
      if (x & 0x40000 > 0)
        result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
      if (x & 0x20000 > 0)
        result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
      if (x & 0x10000 > 0)
        result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
      if (x & 0x8000 > 0)
        result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
      if (x & 0x4000 > 0)
        result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
      if (x & 0x2000 > 0)
        result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
      if (x & 0x1000 > 0)
        result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
      if (x & 0x800 > 0)
        result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
      if (x & 0x400 > 0)
        result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
      if (x & 0x200 > 0)
        result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
      if (x & 0x100 > 0)
        result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
      if (x & 0x80 > 0)
        result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
      if (x & 0x40 > 0)
        result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
      if (x & 0x20 > 0)
        result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
      if (x & 0x10 > 0)
        result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
      if (x & 0x8 > 0)
        result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
      if (x & 0x4 > 0)
        result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
      if (x & 0x2 > 0)
        result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
      if (x & 0x1 > 0)
        result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;

      result >>= uint256 (int256 (63 - (x >> 64)));
      require (result <= uint256 (int256 (MAX_64x64)));

      return int128 (int256 (result));
    }
  }

  /**
   * Calculate natural exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      return exp_2 (
          int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return unsigned 64.64-bit fixed point number
   */
  function divuu (uint256 x, uint256 y) private pure returns (uint128) {
    unchecked {
      require (y != 0);

      uint256 result;

      if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
        result = (x << 64) / y;
      else {
        uint256 msb = 192;
        uint256 xc = x >> 192;
        if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
        if (xc >= 0x10000) { xc >>= 16; msb += 16; }
        if (xc >= 0x100) { xc >>= 8; msb += 8; }
        if (xc >= 0x10) { xc >>= 4; msb += 4; }
        if (xc >= 0x4) { xc >>= 2; msb += 2; }
        if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

        result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
        require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 hi = result * (y >> 128);
        uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 xh = x >> 192;
        uint256 xl = x << 64;

        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here
        lo = hi << 128;
        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here

        assert (xh == hi >> 128);

        result += xl / y;
      }

      require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return uint128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
   * number.
   *
   * @param x unsigned 256-bit integer number
   * @return unsigned 128-bit integer number
   */
  function sqrtu (uint256 x) private pure returns (uint128) {
    unchecked {
      if (x == 0) return 0;
      else {
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
        if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
        if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
        if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
        if (xx >= 0x100) { xx >>= 8; r <<= 4; }
        if (xx >= 0x10) { xx >>= 4; r <<= 2; }
        if (xx >= 0x8) { r <<= 1; }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return uint128 (r < r1 ? r : r1);
      }
    }
  }
}
// File: CombineMetadata.sol


pragma solidity ^0.8.6;





interface ICombineMetadata {    
    function tokenMetadata(
        uint256 tokenId, 
        uint256 rarity, 
        uint256 tokenDensity, 
        uint256 alphaDensity, 
        bool isAlpha, 
        uint256 mergeCount) external view returns (string memory);
}

contract CombineMetadata is ICombineMetadata {
    
    struct ERC721MetadataStructure {
        bool isImageLinked;
        string name;
        string description;
        string createdBy;
        string image;
        ERC721MetadataAttribute[] attributes;
    }

    struct ERC721MetadataAttribute {
        bool includeDisplayType;
        bool includeTraitType;
        bool isValueAString;
        string displayType;
        string traitType;
        string value;
    }
    
    using ABDKMath64x64 for int128;    
    using Base64 for string;
    using Roots for uint;    
    using Strings for uint256;    
    
    address public owner;  

    string private _name;
    string private _imageBaseURI;
    string private _imageExtension;
    uint256 private _maxRadius;
    string[] private _imageParts;
    mapping (string => string) private _classStyles;
  
    string constant private _OFFSET_TAG = '<OFFSET>';
    string constant private _RADIUS_TAG = '<RADIUS>';
    string constant private _CLASS_TAG = '<CLASS>';  
    string constant private _CLASS_STYLE_TAG = '<CLASS_STYLE>';

    function getRadius() public view returns (uint256) { 
        return _maxRadius;
    }
  
    constructor() {
        owner = msg.sender;
        _name = "c";
        _imageBaseURI = ""; // Set to empty string - results in on-chain SVG generation by default unless this is set later
        _imageExtension = ""; // Set to empty string - can be changed later to remain empty, .png, .mp4, etc
        _maxRadius = 2000;

        // Deploy with default SVG image parts - can be completely replaced later
        _imageParts.push("<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='2000' height='2000'>");
            _imageParts.push("<style>");
                _imageParts.push(".m1 #c{fill: #fff;}");
                _imageParts.push(".m1 #r{fill: #000;}");
                _imageParts.push(".m2 #c{fill: #fff;}");
                _imageParts.push(".m2 #r{fill: #10a;}"); // b
                _imageParts.push(".m3 #c{fill: #df0;}"); // y
                _imageParts.push(".m3 #r{fill: #000;}");
                _imageParts.push(".m4 #c{fill: #f00;}"); // r
                _imageParts.push(".m4 #r{fill: #000;}");
                _imageParts.push(".a #c{fill: #000 !important;}"); // b
                _imageParts.push(".a #r{fill: #000 !important;}");
                _imageParts.push(_CLASS_STYLE_TAG);
            _imageParts.push("</style>");
            _imageParts.push("<g class='");
                _imageParts.push(_CLASS_TAG);
                _imageParts.push("'>");
                    _imageParts.push("<rect id='r' width='2000' height='2000'/>");
                    _imageParts.push("<rect id='c' x='");
                        _imageParts.push(_OFFSET_TAG);
                    _imageParts.push("' y='");
                        _imageParts.push(_OFFSET_TAG);
                    _imageParts.push("' width='");
                        _imageParts.push(_RADIUS_TAG);
                    _imageParts.push("' height='");
                        _imageParts.push(_RADIUS_TAG);
                    _imageParts.push("'/>");

            _imageParts.push("</g>");                
        _imageParts.push("</svg>");
    }        
    
    function setName(string calldata name_) external { 
        _requireOnlyOwner();       
        _name = name_;
    }

    function setImageBaseURI(string calldata imageBaseURI_, string calldata imageExtension_) external {        
        _requireOnlyOwner();
        _imageBaseURI = imageBaseURI_;
        _imageExtension = imageExtension_;
    }

    function setMaxRadius(uint256 maxRadius_) external {
        _requireOnlyOwner();
        _maxRadius = maxRadius_;
    }    

    function tokenMetadata(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha, uint256 mergeCount) external view override returns (string memory) {        
        string memory base64Json = Base64.encode(bytes(string(abi.encodePacked(_getJson(tokenId, rarity, tokenDensity, alphaDensity, isAlpha, mergeCount)))));
        return string(abi.encodePacked('data:application/json;base64,', base64Json));
    }

    function updateImageParts(string[] memory imageParts_) public {
        _requireOnlyOwner();
        _imageParts = imageParts_;
    }

    function updateClassStyle(string calldata cssClass, string calldata cssStyle) external {
        _requireOnlyOwner();
        _classStyles[cssClass] = cssStyle;
    }

    function getClassStyle(string memory cssClass) public view returns (string memory) {
        return _classStyles[cssClass];
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function imageBaseURI() public view returns (string memory) {
        return _imageBaseURI;
    }

    function imageExtension() public view returns (string memory) {
        return _imageExtension;
    }

    function maxRadius() public view returns (uint256) {
        return _maxRadius;
    }            

    function getClassString(uint256 tokenId, uint256 rarity, bool isAlpha, bool offchainImage) public pure returns (string memory) {
        return _getClassString(tokenId, rarity, isAlpha, offchainImage);
    }

    function _getJson(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha, uint256 mergeCount) private view returns (string memory) {        
        string memory imageData = 
            bytes(_imageBaseURI).length == 0 ? 
                _getSvg(tokenId, rarity, tokenDensity, alphaDensity, isAlpha) :
                string(abi.encodePacked(imageBaseURI(), _getClassString(tokenId, rarity, isAlpha, true), "_", uint256(int256(_getScaledRadius(tokenDensity, alphaDensity, _maxRadius).toInt())).toString(), imageExtension()));

        ERC721MetadataStructure memory metadata = ERC721MetadataStructure({
            isImageLinked: bytes(_imageBaseURI).length > 0, 
            name: string(abi.encodePacked(name(), "(", tokenDensity.toString(), ") #", tokenId.toString())),
            description: tokenDensity.toString(),
            createdBy: "Hak",
            image: imageData,
            attributes: _getJsonAttributes(tokenId, rarity, tokenDensity, mergeCount, isAlpha)
        });

        return _generateERC721Metadata(metadata);
    }        

    function _getJsonAttributes(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 mergeCount, bool isAlpha) private pure returns (ERC721MetadataAttribute[] memory) {
        uint256 tensDigit = tokenId % 100 / 10;
        uint256 onesDigit = tokenId % 10;
        uint256 class = tensDigit * 10 + onesDigit;

        ERC721MetadataAttribute[] memory metadataAttributes = new ERC721MetadataAttribute[](5);
        metadataAttributes[0] = _getERC721MetadataAttribute(false, true, false, "", "Density", tokenDensity.toString());
        metadataAttributes[1] = _getERC721MetadataAttribute(false, true, false, "", "Alpha", isAlpha ? "1" : "0");
        metadataAttributes[2] = _getERC721MetadataAttribute(false, true, false, "", "Tier", rarity.toString());
        metadataAttributes[3] = _getERC721MetadataAttribute(false, true, false, "", "Class", class.toString());
        metadataAttributes[4] = _getERC721MetadataAttribute(false, true, false, "", "Combines", mergeCount.toString());
        return metadataAttributes;
    }    

    function _getERC721MetadataAttribute(bool includeDisplayType, bool includeTraitType, bool isValueAString, string memory displayType, string memory traitType, string memory value) private pure returns (ERC721MetadataAttribute memory) {
        ERC721MetadataAttribute memory attribute = ERC721MetadataAttribute({
            includeDisplayType: includeDisplayType,
            includeTraitType: includeTraitType,
            isValueAString: isValueAString,
            displayType: displayType,
            traitType: traitType,
            value: value
        });

        return attribute;
    }    

    function _getSvg(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha) private view returns (string memory) {
        bytes memory byteString;
        int128 radius = _getScaledRadius(tokenDensity, alphaDensity, _maxRadius);
        int128 offset = _getOffset(radius, _maxRadius);
        //return _floatToString(offset);
        for (uint i = 0; i < _imageParts.length; i++) {
          if (_checkTag(_imageParts[i], _RADIUS_TAG)) {
            byteString = abi.encodePacked(byteString, _floatToString(radius));
          } else if (_checkTag(_imageParts[i], _OFFSET_TAG)) {
            byteString = abi.encodePacked(byteString, _floatToString(offset));
          } else if (_checkTag(_imageParts[i], _CLASS_TAG)) {
            byteString = abi.encodePacked(byteString, _getClassString(tokenId, rarity, isAlpha, false));
          } else if (_checkTag(_imageParts[i], _CLASS_STYLE_TAG)) {
              uint256 tensDigit = tokenId % 100 / 10;
              uint256 onesDigit = tokenId % 10;
              uint256 class = tensDigit * 10 + onesDigit;
              string memory classCss = getClassStyle(_getTokenIdClass(class));
              if(bytes(classCss).length > 0) {
                  byteString = abi.encodePacked(byteString, classCss);
              }            
          } else {
            byteString = abi.encodePacked(byteString, _imageParts[i]);
          }
        }
        return string(byteString); 
    }

    function _getScaledRadius(uint256 tokenDensity, uint256 alphaDensity, uint256 maximumRadius) private pure returns (int128) {
        int128 radiusDensity = _getRadius64x64(tokenDensity);
        int128 radiusAlphaDensity = _getRadius64x64(alphaDensity);
        int128 scalePercentage = ABDKMath64x64.div(radiusDensity, radiusAlphaDensity);                
        int128 scaledRadius = ABDKMath64x64.mul(ABDKMath64x64.fromUInt(maximumRadius), scalePercentage);
        if(uint256(int256(scaledRadius.toInt())) == 0) {
            scaledRadius = ABDKMath64x64.fromUInt(1);
        }
        return scaledRadius;
    }

    function _getOffset(int128 radius, uint256 maximumRadius) private pure returns (int128) {
        
        int128 remainLength = ABDKMath64x64.sub(ABDKMath64x64.fromUInt(maximumRadius), radius);                
        int128 offset = ABDKMath64x64.div(remainLength, ABDKMath64x64.fromUInt(2));
        if(uint256(int256(offset.toInt())) == 0) {
            offset = ABDKMath64x64.fromUInt(0);
        }
        return offset;
    }

    // Radius = Cube Root(Density) * Cube Root (0.23873241463)
    // Radius = Cube Root(Density) * 0.62035049089
    function _getRadius64x64(uint256 density) private pure returns (int128) {        
        int128 cubeRootScalar = ABDKMath64x64.divu(62035049089, 100000000000);
        int128 cubeRootDensity = ABDKMath64x64.divu(density.nthRoot(3, 6, 32), 1000000);
        int128 radius = ABDKMath64x64.mul(cubeRootDensity, cubeRootScalar);        
        return radius;
    }            

    function _generateERC721Metadata(ERC721MetadataStructure memory metadata) private pure returns (string memory) {
      bytes memory byteString;    
    
        byteString = abi.encodePacked(
          byteString,
          _openJsonObject());
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("name", metadata.name, true));
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("description", metadata.description, true));
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("created_by", metadata.createdBy, true));
    
        if(metadata.isImageLinked) {
            byteString = abi.encodePacked(
                byteString,
                _pushJsonPrimitiveStringAttribute("image", metadata.image, true));
        } else {
            byteString = abi.encodePacked(
                byteString,
                _pushJsonPrimitiveStringAttribute("image_data", metadata.image, true));
        }

        byteString = abi.encodePacked(
          byteString,
          _pushJsonComplexAttribute("attributes", _getAttributes(metadata.attributes), false));
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonObject());
    
        return string(byteString);
    }

    function _getAttributes(ERC721MetadataAttribute[] memory attributes) private pure returns (string memory) {
        bytes memory byteString;
    
        byteString = abi.encodePacked(
          byteString,
          _openJsonArray());
    
        for (uint i = 0; i < attributes.length; i++) {
          ERC721MetadataAttribute memory attribute = attributes[i];

          byteString = abi.encodePacked(
            byteString,
            _pushJsonArrayElement(_getAttribute(attribute), i < (attributes.length - 1)));
        }
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonArray());
    
        return string(byteString);
    }

    function _getAttribute(ERC721MetadataAttribute memory attribute) private pure returns (string memory) {
        bytes memory byteString;
        
        byteString = abi.encodePacked(
          byteString,
          _openJsonObject());
    
        if(attribute.includeDisplayType) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("display_type", attribute.displayType, true));
        }
    
        if(attribute.includeTraitType) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("trait_type", attribute.traitType, true));
        }
    
        if(attribute.isValueAString) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("value", attribute.value, false));
        } else {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveNonStringAttribute("value", attribute.value, false));
        }
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonObject());
    
        return string(byteString);
    }

    function _getClassString(uint256 tokenId, uint256 rarity, bool isAlpha, bool offchainImage) private pure returns (string memory) {
        bytes memory byteString;    
    
        byteString = abi.encodePacked(byteString, _getRarityClass(rarity));
        
        if(isAlpha) {
            byteString = abi.encodePacked(
              byteString,
              string(abi.encodePacked(offchainImage ? "_" : " ", "a")));
        }

        uint256 tensDigit = tokenId % 100 / 10;
        uint256 onesDigit = tokenId % 10;
        uint256 class = tensDigit * 10 + onesDigit;

        byteString = abi.encodePacked(
          byteString,
          string(abi.encodePacked(offchainImage ? "_" : " ", _getTokenIdClass(class))));

        return string(byteString);    
    }

    function _getRarityClass(uint256 rarity) private pure returns (string memory) {
        return string(abi.encodePacked("m", rarity.toString()));
    }

    function _getTokenIdClass(uint256 class) private pure returns (string memory) {
        return string(abi.encodePacked("c", class.toString()));
    }

    function _checkTag(string storage a, string memory b) private pure returns (bool) {
        return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
    }

    function _floatToString(int128 value) private pure returns (string memory) {
        uint256 decimal4 = (value & 0xFFFFFFFFFFFFFFFF).mulu(10000);
        return string(abi.encodePacked(uint256(int256(value.toInt())).toString(), '.', _decimal4ToString(decimal4)));
    }
  
    function _decimal4ToString(uint256 decimal4) private pure returns (string memory) {
        bytes memory decimal4Characters = new bytes(4);
        for (uint i = 0; i < 4; i++) {
          decimal4Characters[3 - i] = bytes1(uint8(0x30 + decimal4 % 10));
          decimal4 /= 10;
        }
        return string(abi.encodePacked(decimal4Characters));
    }

    function _requireOnlyOwner() private view {
        require(msg.sender == owner, "You are not the owner");
    }

    function _openJsonObject() private pure returns (string memory) {        
        return string(abi.encodePacked("{"));
    }

    function _closeJsonObject() private pure returns (string memory) {
        return string(abi.encodePacked("}"));
    }

    function _openJsonArray() private pure returns (string memory) {        
        return string(abi.encodePacked("["));
    }

    function _closeJsonArray() private pure returns (string memory) {        
        return string(abi.encodePacked("]"));
    }

    function _pushJsonPrimitiveStringAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": "', value, '"', insertComma ? ',' : ''));
    }

    function _pushJsonPrimitiveNonStringAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": ', value, insertComma ? ',' : ''));
    }

    function _pushJsonComplexAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": ', value, insertComma ? ',' : ''));
    }

    function _pushJsonArrayElement(string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked(value, insertComma ? ',' : ''));
    }
}
// File: Combine.sol


pragma solidity ^0.8.6;


interface IERC721Receiver {
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

interface ERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;

    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function setApprovalForAll(address operator, bool _approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

interface ERC721Metadata {
    function name() external view returns (string memory _name);
    function symbol() external view returns (string memory _symbol);
    function tokenURI(uint256 _tokenId) external view returns (string memory);
}

contract Combine is ERC721, ERC721Metadata {
 
    ICombineMetadata public _metadataGenerator;

    bool public frozen;

    string private _name;
    string private _symbol;

    uint256 constant private CLASS_MULTIPLIER = 100000; // 100k

    // valid classes are in the range [1, 4]
    uint256 constant private MIN_CLASS_INCL = 1; 
    uint256 constant private MAX_CLASS_INCL = 4;

    // valid densities are in the range [1, 100k - 1]
    uint256 constant private MIN_DENSITY_INCL = 1; 
    uint256 constant private MAX_DENSITY_EXCL = CLASS_MULTIPLIER - 1;

    uint256 public _saleStartTime = 1640969999;
    uint256 public _saleEndTime = 1699999999;

    uint256 public _maxSupply = 5000;
    uint256 public _maxDensity = 25000;

    uint256 public _unitPrice = 25e15;

    uint256 public _freeIndex = 101;
 
    uint256 public _nextMintId;
 
    uint256 public _countToken;

    uint256 immutable public _percentageTotal;
    uint256 public _percentageRoyalty;

    uint256 public _alphaDensity;

    uint256 public _alphaId;

    uint256 public _densityTotal;

    address public _hak;
    address public _collab;
    address public _fund;
    address public _receiver;
    address constant public _dead = 0x000000000000000000000000000000000000dEaD;

    event AlphaDensityUpdate(uint256 indexed tokenId, uint256 alphaDensity);

    event DensityUpdate(uint256 indexed tokenIdBurned, uint256 indexed tokenIdPersist, uint256 density);

    uint256[5001] private _tokenIdArray;

    mapping (uint256 => uint256) private _tokenIdToIndex;

    // Mapping of addresses disbarred from holding any token.
    mapping (address => bool) private _blacklistAddress;

    // Mapping of address allowed to hold multiple tokens.
    mapping (address => bool) private _whitelistAddress;

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

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

    // Mapping token ID to density value.
    mapping (uint256 => uint256) private _values;

    // Mapping token ID to all quantity combined into it.
    mapping (uint256 => uint256) private _combineCount;

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

    // 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;


    function getCombineCount(uint256 tokenId) public view returns (uint256 combineCount) {
        require(_exists(tokenId), "nonexistent token");
        return _combineCount[tokenId];
    }

    function getTokenIdFromArray(uint256 index) public view returns (uint256 tokenId) {
        return _tokenIdArray[index];
    }

    function getIndexFromTokenId(uint256 tokenId) public view returns (uint256 index) {
        return _tokenIdToIndex[tokenId];
    }

    modifier onlyHak() {
        require(_msgSender() == _hak, "msg.sender is not hak");
        _;
    }

    modifier onlyValidWhitelist() {
        require(_whitelistAddress[_msgSender()], "invalid msg.sender");
        _;
    }

    modifier notFrozen() {
        require(!frozen, "transfer frozen");
        _;
    }

    function ensureValidClass(uint256 class) private pure {
        require(MIN_CLASS_INCL <= class && class <= MAX_CLASS_INCL, "class must be [1,4].");
    }

    function ensureValidDensity(uint256 density) private pure {
        require(MIN_DENSITY_INCL <= density && density < MAX_DENSITY_EXCL, "density must be [1,100k-1).");
    }
   
    constructor(address metadataGenerator_, address collab_, address fund_) {

        _metadataGenerator = ICombineMetadata(metadataGenerator_);
        _name = "combine.";
        _symbol = "c";

        _hak = msg.sender;
        _collab = collab_;
        _fund = fund_;
        _receiver = _hak;

        _percentageTotal = 10000;
        _percentageRoyalty = 1000;

        _blacklistAddress[address(this)] = true;            

        // mint one with density 10 to act as placeholder alpha
        _values[1] = encodeClassAndDensity(1, 10);         
        _owners[1] = msg.sender;
        _tokens[msg.sender] = 1;
        emit Transfer(address(0), msg.sender, 1);
        _countToken++;
        _balances[msg.sender]++;
        _densityTotal = 10;
        _alphaDensity = 10;
        _alphaId = 1;
        emit AlphaDensityUpdate(1, 10);

        _tokenIdToIndex[1] = 1;
        _tokenIdArray[_countToken] = 1;
        _nextMintId = 2;
    }
        
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    } 

    function totalSupply() public view returns (uint256) {
        return _countToken;
    }
 
    function combine(uint256 tokenIdRcvr, uint256 tokenIdSndr) external onlyValidWhitelist notFrozen returns (uint256 tokenIdDead) {        
        address owner = ownerOf(tokenIdRcvr);
        require(owner == ownerOf(tokenIdSndr), "disparate owner");
        require(_msgSender() == owner, "not token owner.");

        // owners are same, so decrement their balance as we are merging
        _balances[owner] -= 1;

        tokenIdDead = _combine(tokenIdRcvr, tokenIdSndr);

        // clear ownership of dead token
        delete _owners[tokenIdDead];

        // owners are the same; burn dead token from common owner
        emit Transfer(owner, address(0), tokenIdDead);
    }

    function _transfer(address owner, address from, address to, uint256 tokenId) internal notFrozen {
        require(owner == from, "token not own");
        require(to != address(0), "cannot transfer to zero addr");
        require(!_blacklistAddress[to], "cannot transfer to blacklist");

        // if transferring to `_dead_` then `_transfer` is interpreted as a burn
        if (to == _dead) {
            _burnNoEmitTransfer(owner, tokenId);

            emit Transfer(from, _dead, tokenId);
            emit Transfer(_dead, address(0), tokenId);
        } else {
            // Clear any prior approvals
            // includes an emit of Approval to zero
            _approve(owner, address(0), tokenId);

            // in all cases we first wish to log the transfer
            // no merging later can deny the fact that `from` transferred to `to`
            emit Transfer(from, to, tokenId);

            if (from == to) {
                // !non-local control flow!
                // we make an exception here, as it’s easy to follow that a self transfer
                // can skip _all_ following state changes
                return;
            }

            // if all addresses were whitelisted, then transfer would be like any other ERC-721
            // _balances[from] -= 1;
            // _balances[to] += 1;
            // _owners[tokenId] = to;

            // _balances (1) and _owners (2) are the main mappings to update
            // for non-whitelisted addresses there is also the _tokens (3) mapping
            //
            // Our updates will be
            //   - 1a: decrement balance of `from`
            //   - 1b: update balance of `to` (not guaranteed to increase)
            //   - 2: assign ownership of `tokenId`
            //   - 3a: assign unique token of `to`
            //   - 3b: unassign unique token of `from`

            bool fromIsWhitelisted = isWhitelisted(from);
            bool toIsWhitelisted = isWhitelisted(to);

            // BEGIN PART 1: update _balances
            //
            // PART 1a: decrease balance of `from`
            //   the classic implementation would be
            //   _balances[from] -= 1;
            if (fromIsWhitelisted) {
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _balances[from] -= 1;
            } else {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // we known that `from` was the owner so the only possible state is
                //   _balances[from] == 1
                // to save an SLOAD, we can assign a balance of 0 (or delete)
                delete _balances[from];
            }
            // PART 1b: increase balance of `to`
            //   the classic implementation would be
            //   _balances[to] += 1;
            if (toIsWhitelisted) {
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _balances[to] += 1;
            } else if (_tokens[to] == 0) {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // if _tokens[to] == 0 then _balances[to] == 0
                // to save an SLOAD, we can assign a balance of 1
                _balances[to] = 1;
            } else {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // if _tokens[to] != 0 then _balance[to] == 1
                // to preserve the invariant, we have nothing to do (the balance is already 1)
            }
            // END PART 1

            if (toIsWhitelisted) {
                // PART 2: update _owners
                // assign ownership of token
                //   the classic implementation would be
                //   _owners[tokenId] = to;
                //
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _owners[tokenId] = to;
            } else {
                // label current and sent token with respect to address `to`
                uint256 currentTokenId = _tokens[to];

                if (currentTokenId == 0) {
                    // PART 2: update _owners
                    // assign ownership of token
                    _owners[tokenId] = to;

                    // PART 3a
                    // assign unique token of `to`
                    _tokens[to] = tokenId;
                } else {
                    uint256 sentTokenId = tokenId;

                    // compute token combine, returning the dead token
                    uint256 deadTokenId = _combine(currentTokenId, sentTokenId);

                    // logically, the token has already been transferred to `to`
                    // so log the burning of the dead token id as originating ‘from’ `to`
                    emit Transfer(to, address(0), deadTokenId);

                    // thus inferring the alive token
                    uint256 aliveTokenId = currentTokenId;
                    if (currentTokenId == deadTokenId) {
                        aliveTokenId = sentTokenId;
                    }

                    // PART 2 continued:
                    // and ownership of dead token is deleted
                    delete _owners[deadTokenId];

                    // if received token surplanted the current token
                    if (currentTokenId != aliveTokenId) {
                        // PART 2 continued:
                        // to takes ownership of alive token
                        _owners[aliveTokenId] = to;

                        // PART 3a
                        // assign unique token of `to`
                        _tokens[to] = aliveTokenId;
                    }
                }
            }

            // PART 3b:
            // unassign unique token of `from`
            //
            // _tokens is only defined for non-whitelisted addresses
            if (!fromIsWhitelisted) {
                delete _tokens[from];
            }
        }
    }

    function _increaseDensity(uint256 tokenId, uint256 density_) private {
        uint256 currentDensity = decodeDensity(_values[tokenId]);
        _values[tokenId] += density_;

        uint256 newDensity = currentDensity + density_;

        if(newDensity > _alphaDensity) {
            _alphaId = tokenId;
            _alphaDensity = newDensity;
            emit AlphaDensityUpdate(_alphaId, newDensity);
        }

        emit DensityUpdate(0, tokenId, newDensity);
    }

    function _combine(uint256 tokenIdRcvr, uint256 tokenIdSndr) internal returns (uint256 tokenIdDead) {
        require(tokenIdRcvr != tokenIdSndr, "identical tokenId");

        uint256 densityRcvr = decodeDensity(_values[tokenIdRcvr]);
        uint256 densitySndr = decodeDensity(_values[tokenIdSndr]);
        
        uint256 densitySmall = densityRcvr;
        uint256 densityLarge = densitySndr;

        uint256 tokenIdSmall = tokenIdRcvr;
        uint256 tokenIdLarge = tokenIdSndr;

        if (densityRcvr >= densitySndr) {

            densitySmall = densitySndr;
            densityLarge = densityRcvr;

            tokenIdSmall = tokenIdSndr;
            tokenIdLarge = tokenIdRcvr;
        }

        _values[tokenIdLarge] += densitySmall;

        uint256 combinedDensity = densityLarge + densitySmall;

        if(combinedDensity > _alphaDensity) {
            _alphaId = tokenIdLarge;
            _alphaDensity = combinedDensity;
            emit AlphaDensityUpdate(_alphaId, combinedDensity);
        }
        
        _combineCount[tokenIdLarge]++;

        delete _values[tokenIdSmall];

        uint256 indexToReplace = _tokenIdToIndex[tokenIdSmall];
        uint256 lastTokenId = _tokenIdArray[_countToken];
        _tokenIdArray[indexToReplace] = lastTokenId;
        _tokenIdToIndex[lastTokenId] = indexToReplace;
        _countToken--;

        emit DensityUpdate(tokenIdSmall, tokenIdLarge, combinedDensity);

        return tokenIdSmall;
    }

    function setRoyaltyBips(uint256 percentageRoyalty_) external onlyHak {
        require(percentageRoyalty_ <= _percentageTotal, "more than 100%");
        _percentageRoyalty = percentageRoyalty_;
    }

    function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) {
        uint256 royaltyAmount = (salePrice * _percentageRoyalty) / _percentageTotal;
        return (_receiver, royaltyAmount);
    }

    function setBlacklistAddress(address address_, bool status) external onlyHak {
        _blacklistAddress[address_] = status;
    }

    function setCollab(address collab_) external onlyHak {  
        _collab = collab_;
    }

    function setFund(address fund_) external onlyHak {  
        _fund = fund_;
    }

    function setHak(address hak_) external onlyHak {
        require(address(this).balance < 1e16, "be careful");
        _hak = hak_;
    }

    function setUnitPrice(uint256 unitPrice_) external onlyHak {
        _unitPrice = unitPrice_;
    }

    function setSaleStartTime(uint256 startTime_) external onlyHak {
        require(
            startTime_ < _saleEndTime,
            "invalid time"
        );
        _saleStartTime = startTime_;
    }

    function setSaleEndTime(uint256 endTime_) external onlyHak {
        require(
            _saleStartTime < endTime_,
            "invalid time"
        );
        _saleEndTime = endTime_;
    }

    function setMaxSupply(uint256 count_) external onlyHak {
        require(_nextMintId <= count_, "invalid supply count");
        _maxSupply = count_;
    }

    function setFreeIndex(uint256 index_) external onlyHak {
        require(_nextMintId <= index_ && index_ <= _maxSupply, "invalid index");
        _freeIndex = index_;
    }
    
    function setMaxDensity(uint256 density_) external onlyHak {
        require(_densityTotal <= density_ && density_ <= MAX_DENSITY_EXCL, "invalid density");
        _maxDensity = density_;
    }

    function setRoyaltyReceiver(address receiver_) external onlyHak {  
        _receiver = receiver_;
    }
    
    function setMetadataGenerator(address metadataGenerator_) external onlyHak {  
        _metadataGenerator = ICombineMetadata(metadataGenerator_);
    }
   
    function whitelistUpdate(address address_, bool status) external onlyHak {

        if(status == false) {
            require(balanceOf(address_) <= 1, "addr cannot be removed");
        }

        _whitelistAddress[address_] = status;
    }

    function isWhitelisted(address address_) public view returns (bool) {
        return _whitelistAddress[address_];
    }

    function isBlacklisted(address address_) public view returns (bool) {
        return _blacklistAddress[address_];
    }

    function ownerOf(uint256 tokenId) public view override returns (address owner) {
        owner = _owners[tokenId]; 
        require(owner != address(0), "nonexistent token");
    }

    /**
     *
     *
     * _densityToMint - density of the cube you want to mint
     *
     * Emits a series of {Transfer} events.
     */
    function mint(uint256 _densityToMint) external payable {
        require(
            block.timestamp >= _saleStartTime && block.timestamp < _saleEndTime,
            "sale not open"
        );
        require(_nextMintId < _maxSupply, "max supply reached");
        // require(
        //     _balances[msg.sender] == 0,
        //     "cannot mint while holding cube"
        // );
        require(
            tx.origin == msg.sender,
            "cannot use custom contract"
        );

        bool ownACube = _balances[msg.sender] != 0;
        
        // for efficiency reasons copy from storage into local variables
        uint256 index = _nextMintId;
        uint256 alphaId = _alphaId;
        uint256 alphaDensity = _alphaDensity;

        uint256 paidCount = _densityToMint;

        if (msg.sender == _hak){
            paidCount = 0;
        
        } // first few are free for density 1 (nonholder only)
        else if (index <= _freeIndex && !ownACube){
            paidCount--;
        }

        require(
            msg.value >= paidCount * _unitPrice,
            "insufficient ETH"
        );

        // update total density in system (must be bounded by MAX_DENSITY_EXCL)
        uint256 prevDensityTotal = _densityTotal;
        uint256 newDensityTotal = prevDensityTotal + _densityToMint;
        require(
            newDensityTotal <= _maxDensity,
            "total max density reached"
        );
        _densityTotal = newDensityTotal;

        // IF owner already has a cube, simply update the density of that cube
        if (ownACube){
            require(!isWhitelisted(msg.sender), "cannot update wl density");
            _increaseDensity(tokenOf(msg.sender), _densityToMint);
            return;
        }

        // 5% of having a special background
        uint256 class = (random() % 100) < 5 ? 2 : 1;

        _values[index] = encodeClassAndDensity(class, _densityToMint);         
        _owners[index] = msg.sender;


        // update token supply
        _countToken++;

        if (alphaDensity < _densityToMint){
            alphaDensity = _densityToMint;
            alphaId = index;
        }

        _tokenIdArray[index] = index;
        _tokenIdToIndex[index] = index;

        _transfer(address(0), address(0), msg.sender, index);
        //emit Transfer(address(0), msg.sender, index);

        index++;
        // return new token id index to storage
        _nextMintId = index; 


        // if the alpha was supplanted, return that new state to storage
        if(_alphaId != alphaId) {
            _alphaId = alphaId;
            _alphaDensity = alphaDensity;
            emit AlphaDensityUpdate(alphaId, alphaDensity);
        }        
    }

    function random() private view returns (uint256) {
        // pseudorandom
        bytes32 randomHash = keccak256(
            abi.encode(
                block.timestamp,
                block.difficulty,
                block.coinbase,
                msg.sender
            )
        );
        return uint256(randomHash);
    }
   

    function freeze(bool state_) external onlyHak {
        frozen = state_;
    }

    function _destroy(uint256 tokenId) private {
        address owner = _owners[tokenId];
        require(owner != address(0), "nonexistent token");
        _burnNoEmitTransfer(owner, tokenId);
        if (msg.value > 0){
            (bool success,) = owner.call{value: msg.value}("");
            require(success, "transfer failed");
        }
        emit Transfer(owner, address(0), tokenId);
    }

    function destroyWithMercy(uint256 tokenId) external payable onlyHak {
        _destroy(tokenId);
    }

    function destroyRandomWithMercy() external payable onlyHak {
        uint256 tokenId = _tokenIdArray[(random() % (_countToken)) + 1];
        uint256 newTokenId;
        while ((random() % _alphaDensity) > densityOf(tokenId)){
            newTokenId = _tokenIdArray[(random() % (_countToken)) + 1];
            if (tokenId == newTokenId){
                break;
            } else {
                tokenId = newTokenId;
            }
        }
        _destroy(tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "non ERC721Receiver implementer");
    }

    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        (address owner, bool isApprovedOrOwner) = _isApprovedOrOwner(_msgSender(), tokenId);
        require(isApprovedOrOwner, "not owner nor approved");
        _transfer(owner, from, to, tokenId);
    }

    function balanceOf(address owner) public view override returns (uint256) {
        return _balances[owner];        
    }

    function densityOf(uint256 tokenId) public view virtual returns (uint256) {
        uint256 value = getValueOf(tokenId);
        return decodeDensity(value);
    }

    function getValueOf(uint256 tokenId) public view virtual returns (uint256 value) {
        value = _values[tokenId];
        require(value != 0, "nonexistent token");
    }

    function tokenOf(address owner) public view virtual returns (uint256) {
        require(!isWhitelisted(owner), "tokenOf undefined");
        uint256 token = _tokens[owner];
        return token;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ownerOf(tokenId);
        require(to != owner, "approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "not owner nor approved for all"
        );
        _approve(owner, to, tokenId);
    }

    function _approve(address owner, address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "nonexistent token");       
        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "approve to caller");
        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function _exists(uint256 tokenId) internal view returns (bool) {
        return _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (address owner, bool isApprovedOrOwner) {
        owner = _owners[tokenId];

        require(owner != address(0), "nonexistent token");

        isApprovedOrOwner = (spender == owner || _tokenApprovals[tokenId] == spender || isApprovedForAll(owner, spender));
    }   

    function tokenURI(uint256 tokenId) public virtual view override returns (string memory) {
        require(_exists(tokenId), "nonexistent token");
        
        return _metadataGenerator.tokenMetadata(
            tokenId, 
            decodeClass(_values[tokenId]), 
            decodeDensity(_values[tokenId]), 
            decodeDensity(_values[_alphaId]), 
            tokenId == _alphaId,
            getCombineCount(tokenId));
    }

    function updateTokenClass(uint tokenId, uint256 class) external onlyHak {
        require(_exists(tokenId), "nonexistent token");
        _values[tokenId] = encodeClassAndDensity(class, densityOf(tokenId));
    }

    function encodeClassAndDensity(uint256 class, uint256 density) public pure returns (uint256) {
        ensureValidClass(class);
        ensureValidDensity(density);
        return ((class * CLASS_MULTIPLIER) + density);
    }

    function decodeClassAndDensity(uint256 value) public pure returns (uint256, uint256) {
        uint256 class = decodeClass(value);
        uint256 density = decodeDensity(value);
        return (class, density);
    }

    function decodeClass(uint256 value) public pure returns (uint256 class) {
        class = value / CLASS_MULTIPLIER; // integer division is ‘checked’ in Solidity 0.8.x
        ensureValidClass(class);
    }    

    function decodeDensity(uint256 value) public pure returns (uint256 density) {
        density = value % CLASS_MULTIPLIER; // integer modulo is ‘checked’ in Solidity 0.8.x
        ensureValidDensity(density);
    }

    function _msgSender() internal view returns (address) {
        return msg.sender;
    }

    function withdrawAll() public onlyHak {
        uint256 currentBal = address(this).balance;
        require(currentBal > 0);
        if (_collab == _hak){
            _withdraw(_hak, address(this).balance);
        } else {
            _withdraw(_collab, currentBal / 4); // 25%
            _withdraw(_fund, currentBal / 2); // 50%
            //remainder to prevent ether dust
            _withdraw(_hak, address(this).balance); // 25%
        }
    }

    function _withdraw(address _addr, uint256 _amt) private {
        (bool success,) = _addr.call{value: _amt}("");
        require(success, "transfer failed");
    }
     
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) {
        if (isContract(to)) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("non ERC721Receiver implementer");
                }
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
        return true;
    }    

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        bytes4 _ERC165_ = 0x01ffc9a7;
        bytes4 _ERC721_ = 0x80ac58cd;
        bytes4 _ERC2981_ = 0x2a55205a;
        bytes4 _ERC721Metadata_ = 0x5b5e139f;
        return interfaceId == _ERC165_ 
            || interfaceId == _ERC721_
            || interfaceId == _ERC2981_
            || interfaceId == _ERC721Metadata_;
    }


    function burn(uint256 tokenId) public notFrozen {
        (address owner, bool isApprovedOrOwner) = _isApprovedOrOwner(_msgSender(), tokenId);
        require(isApprovedOrOwner, "not owner nor approved");

        _burnNoEmitTransfer(owner, tokenId);

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

    function _burnNoEmitTransfer(address owner, uint256 tokenId) internal {
        _approve(owner, address(0), tokenId);

        _densityTotal -= decodeDensity(_values[tokenId]);

        delete _tokens[owner];
        delete _owners[tokenId];
        delete _values[tokenId];

        uint256 indexToReplace = _tokenIdToIndex[tokenId];
        uint256 lastTokenId = _tokenIdArray[_countToken];
        _tokenIdArray[indexToReplace] = lastTokenId;
        _tokenIdToIndex[lastTokenId] = indexToReplace;
        _countToken--;



        _balances[owner] -= 1;        

        emit DensityUpdate(tokenId, 0, 0);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"metadataGenerator_","type":"address"},{"internalType":"address","name":"collab_","type":"address"},{"internalType":"address","name":"fund_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"alphaDensity","type":"uint256"}],"name":"AlphaDensityUpdate","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenIdBurned","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenIdPersist","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"density","type":"uint256"}],"name":"DensityUpdate","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":[],"name":"_alphaDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_alphaId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_collab","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_countToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_dead","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_densityTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_freeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_fund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_hak","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_metadataGenerator","outputs":[{"internalType":"contract ICombineMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_percentageRoyalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_percentageTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_receiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_saleEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_saleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_unitPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIdRcvr","type":"uint256"},{"internalType":"uint256","name":"tokenIdSndr","type":"uint256"}],"name":"combine","outputs":[{"internalType":"uint256","name":"tokenIdDead","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeClass","outputs":[{"internalType":"uint256","name":"class","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeClassAndDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeDensity","outputs":[{"internalType":"uint256","name":"density","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"densityOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"destroyRandomWithMercy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"destroyWithMercy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"class","type":"uint256"},{"internalType":"uint256","name":"density","type":"uint256"}],"name":"encodeClassAndDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"state_","type":"bool"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"frozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"getCombineCount","outputs":[{"internalType":"uint256","name":"combineCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getIndexFromTokenId","outputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getTokenIdFromArray","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getValueOf","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_densityToMint","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setBlacklistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collab_","type":"address"}],"name":"setCollab","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"setFreeIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fund_","type":"address"}],"name":"setFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hak_","type":"address"}],"name":"setHak","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"density_","type":"uint256"}],"name":"setMaxDensity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count_","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"metadataGenerator_","type":"address"}],"name":"setMetadataGenerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentageRoyalty_","type":"uint256"}],"name":"setRoyaltyBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"}],"name":"setRoyaltyReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"endTime_","type":"uint256"}],"name":"setSaleEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime_","type":"uint256"}],"name":"setSaleStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"unitPrice_","type":"uint256"}],"name":"setUnitPrice","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":"owner","type":"address"}],"name":"tokenOf","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":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","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":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"class","type":"uint256"}],"name":"updateTokenClass","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"whitelistUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040526361cf370f600355636553f0ff6004556113886005556161a86006556658d15e1762800060075560656008553480156200003d57600080fd5b50604051620043183803806200431883398101604081905262000060916200049f565b600080546001600160a01b0319166001600160a01b0385161790556040805180820190915260088082526731b7b6b134b7329760c11b6020909201918252620000ac91600191620003dc565b50604080518082019091526001808252606360f81b6020909201918252620000d791600291620003dc565b50600f8054336001600160a01b031991821681179092556010805482166001600160a01b03868116919091179091556011805483169185169190911790556012805490911690911790556127106080526103e8600b5530600090815261139d60205260409020805460ff191660019081179091556200015890600a620002cb565b7f52720b109a02538e76b28c1d71d4649ce6f5aaeee2824746084acf71af20c71a557f4b7b132a0111b8646ad8b973d4f43f9f1d49318338b2f5ae83f3ef157877766a80546001600160a01b03191633908117909155600081815261139f60205260408082206001908190559051909291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4600a80549060006200020183620004ff565b90915550503360009081526113a0602052604081208054916200022483620004ff565b9091555050600a600e819055600c8190556001600d819055604051918252907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a26001600081905261139c6020527ff8d445471faa4e45902923d2d366e37efb6bb1f72ccdac568a5c46e4df804876819055600a546013906113898110620002bb57620002bb6200051d565b01555050600260095550620005c7565b6000620002d88362000306565b620002e3826200036e565b81620002f3620186a08562000533565b620002ff919062000555565b9392505050565b8060011115801562000319575060048111155b6200036b5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e00000000000000000000000060448201526064015b60405180910390fd5b50565b806001111580156200038e57506200038b6001620186a062000570565b81105b6200036b5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e0000000000604482015260640162000362565b828054620003ea906200058a565b90600052602060002090601f0160209004810192826200040e576000855562000459565b82601f106200042957805160ff191683800117855562000459565b8280016001018555821562000459579182015b82811115620004595782518255916020019190600101906200043c565b50620004679291506200046b565b5090565b5b808211156200046757600081556001016200046c565b80516001600160a01b03811681146200049a57600080fd5b919050565b600080600060608486031215620004b557600080fd5b620004c08462000482565b9250620004d06020850162000482565b9150620004e06040850162000482565b90509250925092565b634e487b7160e01b600052601160045260246000fd5b6000600019821415620005165762000516620004e9565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615620005505762000550620004e9565b500290565b600082198211156200056b576200056b620004e9565b500190565b600082821015620005855762000585620004e9565b500390565b600181811c908216806200059f57607f821691505b60208210811415620005c157634e487b7160e01b600052602260045260246000fd5b50919050565b608051613d27620005f160003960008181610a6c0152818161139501526119a50152613d276000f3fe6080604052600436106104655760003560e01c8063525f8a5c11610243578063a755516011610143578063dbf65de0116100bb578063e985e9c51161008a578063ec259d171161006f578063ec259d1714610cf0578063fb1fac1814610d10578063fe575a8714610d2657600080fd5b8063e985e9c514610c86578063eafe706e14610cd057600080fd5b8063dbf65de014610c1a578063dc1b732814610c3a578063dcfb383314610c5a578063dde502d114610c7057600080fd5b8063b88d4fde11610112578063c87b56dd116100f7578063c87b56dd14610bba578063cbd14a7d14610bda578063d132391a14610bfa57600080fd5b8063b88d4fde14610b7a578063b8d4a4aa14610b9a57600080fd5b8063a755516014610af6578063a819e4e414610b16578063a8a07b3614610b2c578063b5bf15e514610b5a57600080fd5b8063853828b6116101d65780639121ac0d116101a557806395d89b411161018a57806395d89b4114610aae578063a0712d6814610ac3578063a22cb46514610ad657600080fd5b80639121ac0d14610a5a5780639377736914610a8e57600080fd5b8063853828b6146109f25780638a50fecb14610a075780638dc251e314610a2757806390b5098814610a4757600080fd5b80636f8b44b0116102125780636f8b44b01461096557806370a082311461098557806375a99b9f146109bc57806378907bf7146109d257600080fd5b8063525f8a5c146108e557806355d5f96314610905578063629a5334146109255780636352211e1461094557600080fd5b8063258ef43911610369578063423abb61116102e157806343f51ebb116102b05780634885382a116102955780634885382a1461088f5780634f558e79146108a5578063504ce0e2146108c557600080fd5b806343f51ebb1461085957806343fa2c9c1461087957600080fd5b8063423abb61146107d957806342842e0e146107f957806342966c681461081957806342ec38e21461083957600080fd5b80632b447ff511610338578063341815f61161031d578063341815f614610769578063369b012d1461077f5780633af32abf1461079f57600080fd5b80632b447ff5146107335780632bddccdc1461075357600080fd5b8063258ef4391461069757806327686691146106b75780632a347f61146106ec5780632a55205a146106f457600080fd5b80630ab2b6b9116103fc5780631ef467e1116103cb57806323b872dd116103b057806323b872dd1461064157806324032e9814610661578063254709d31461068157600080fd5b80631ef467e11461060b57806322f4596f1461062b57600080fd5b80630ab2b6b9146105a05780630e21750f146105c057806314066c7c146105e057806318160ddd146105f657600080fd5b806306fdde031161043857806306fdde031461051c5780630764789a1461053e578063081812fc1461055e578063095ea7b31461057e57600080fd5b806301ffc9a71461046a578063029108911461049f57806302964ff1146104c3578063054f7d9c146104fb575b600080fd5b34801561047657600080fd5b5061048a6104853660046137f2565b610d60565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b5600d5481565b604051908152602001610496565b3480156104cf57600080fd5b506012546104e3906001600160a01b031681565b6040516001600160a01b039091168152602001610496565b34801561050757600080fd5b5060005461048a90600160a01b900460ff1681565b34801561052857600080fd5b50610531610e42565b6040516104969190613867565b34801561054a57600080fd5b50600f546104e3906001600160a01b031681565b34801561056a57600080fd5b506104e361057936600461387a565b610ed4565b34801561058a57600080fd5b5061059e6105993660046138aa565b610f4f565b005b3480156105ac57600080fd5b506104b56105bb36600461387a565b611036565b3480156105cc57600080fd5b5061059e6105db3660046138d4565b61108c565b3480156105ec57600080fd5b506104b560045481565b34801561060257600080fd5b50600a546104b5565b34801561061757600080fd5b506104b56106263660046138ef565b6110ff565b34801561063757600080fd5b506104b560055481565b34801561064d57600080fd5b5061059e61065c366004613911565b611132565b34801561066d57600080fd5b506011546104e3906001600160a01b031681565b34801561068d57600080fd5b506104b5600c5481565b3480156106a357600080fd5b506104b56106b236600461387a565b6111a4565b3480156106c357600080fd5b506106d76106d236600461387a565b6111bb565b60408051928352602083019190915201610496565b61059e6111e2565b34801561070057600080fd5b5061071461070f3660046138ef565b61138e565b604080516001600160a01b039093168352602083019190915201610496565b34801561073f57600080fd5b5061059e61074e36600461387a565b6113e3565b34801561075f57600080fd5b506104b560095481565b34801561077557600080fd5b506104b5600e5481565b34801561078b57600080fd5b5061059e61079a3660046138d4565b611499565b3480156107ab57600080fd5b5061048a6107ba3660046138d4565b6001600160a01b0316600090815261139e602052604090205460ff1690565b3480156107e557600080fd5b506104b56107f436600461387a565b61150c565b34801561080557600080fd5b5061059e610814366004613911565b611579565b34801561082557600080fd5b5061059e61083436600461387a565b611594565b34801561084557600080fd5b506104b56108543660046138d4565b611684565b34801561086557600080fd5b5061059e6108743660046138ef565b61170b565b34801561088557600080fd5b506104b5600b5481565b34801561089b57600080fd5b506104b560085481565b3480156108b157600080fd5b5061048a6108c036600461387a565b6117d9565b3480156108d157600080fd5b5061059e6108e036600461387a565b6117fb565b3480156108f157600080fd5b5061059e61090036600461387a565b6118bc565b34801561091157600080fd5b506000546104e3906001600160a01b031681565b34801561093157600080fd5b5061059e61094036600461387a565b611952565b34801561095157600080fd5b506104e361096036600461387a565b611a18565b34801561097157600080fd5b5061059e61098036600461387a565b611a72565b34801561099157600080fd5b506104b56109a03660046138d4565b6001600160a01b031660009081526113a0602052604090205490565b3480156109c857600080fd5b506104b560035481565b3480156109de57600080fd5b506104b56109ed36600461387a565b611b1a565b3480156109fe57600080fd5b5061059e611b34565b348015610a1357600080fd5b506104b5610a223660046138ef565b611c13565b348015610a3357600080fd5b5061059e610a423660046138d4565b611e22565b61059e610a5536600461387a565b611e95565b348015610a6657600080fd5b506104b57f000000000000000000000000000000000000000000000000000000000000000081565b348015610a9a57600080fd5b5061059e610aa93660046138d4565b611eef565b348015610aba57600080fd5b50610531611f62565b61059e610ad136600461387a565b611f71565b348015610ae257600080fd5b5061059e610af136600461395d565b612379565b348015610b0257600080fd5b5061059e610b1136600461395d565b61243f565b348015610b2257600080fd5b506104b560065481565b348015610b3857600080fd5b506104b5610b4736600461387a565b600090815261139c602052604090205490565b348015610b6657600080fd5b5061059e610b75366004613987565b6124bc565b348015610b8657600080fd5b5061059e610b95366004613a11565b612546565b348015610ba657600080fd5b5061059e610bb53660046138d4565b6125af565b348015610bc657600080fd5b50610531610bd536600461387a565b612678565b348015610be657600080fd5b506104b5610bf536600461387a565b6127cc565b348015610c0657600080fd5b5061059e610c1536600461387a565b6127ea565b348015610c2657600080fd5b5061059e610c3536600461395d565b612880565b348015610c4657600080fd5b5061059e610c5536600461387a565b612972565b348015610c6657600080fd5b506104e361dead81565b348015610c7c57600080fd5b506104b560075481565b348015610c9257600080fd5b5061048a610ca1366004613abc565b6001600160a01b0391821660009081526113a56020908152604080832093909416825291909152205460ff1690565b348015610cdc57600080fd5b506104b5610ceb36600461387a565b6129c8565b348015610cfc57600080fd5b506010546104e3906001600160a01b031681565b348015610d1c57600080fd5b506104b5600a5481565b348015610d3257600080fd5b5061048a610d413660046138d4565b6001600160a01b0316600090815261139d602052604090205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f80ac58cd000000000000000000000000000000000000000000000000000000007f2a55205a000000000000000000000000000000000000000000000000000000007f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03198616841480610e0a57506001600160e01b0319868116908416145b80610e2157506001600160e01b0319868116908316145b80610e3857506001600160e01b0319868116908216145b9695505050505050565b606060018054610e5190613ae6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7d90613ae6565b8015610eca5780601f10610e9f57610100808354040283529160200191610eca565b820191906000526020600020905b815481529060010190602001808311610ead57829003601f168201915b5050505050905090565b60008181526113a360205260408120546001600160a01b0316610f325760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b60448201526064015b60405180910390fd5b5060009081526113a460205260409020546001600160a01b031690565b6000610f5a82611a18565b9050806001600160a01b0316836001600160a01b03161415610fbe5760405162461bcd60e51b815260206004820152601960248201527f617070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610f29565b336001600160a01b0382161480610fda5750610fda8133610ca1565b6110265760405162461bcd60e51b815260206004820152601e60248201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610f29565b6110318184846129e2565b505050565b60008181526113a16020526040902054806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b919050565b600f546001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110a83612a3f565b61111382612a9d565b81611121620186a085613b37565b61112b9190613b56565b9392505050565b600080611140335b84612b06565b91509150806111915760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61119d82868686612bd5565b5050505050565b6000806111b083611036565b905061112b81611b1a565b60008060006111c9846129c8565b905060006111d685611b1a565b91959194509092505050565b600f546001600160a01b0316336001600160a01b0316146112335760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60006013600a5461127a60408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b6112849190613b84565b61128f906001613b56565b61138981106112a0576112a0613b98565b0154905060005b6112b0826111a4565b600c5460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a090920190925280519101206112f79190613b84565b1115611381576013600a5461134260408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61134c9190613b84565b611357906001613b56565b611389811061136857611368613b98565b015490508082141561137957611381565b8091506112a7565b61138a826130a7565b5050565b60008060007f0000000000000000000000000000000000000000000000000000000000000000600b54856113c29190613b37565b6113cc9190613bae565b6012546001600160a01b0316969095509350505050565b600f546001600160a01b0316336001600160a01b0316146114345760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115801561144857506005548111155b6114945760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420696e646578000000000000000000000000000000000000006044820152606401610f29565b600855565b600f546001600160a01b0316336001600160a01b0316146114ea5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260408120546001600160a01b03166115655760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b5060009081526113a2602052604090205490565b61103183838360405180602001604052806000815250612546565b600054600160a01b900460ff16156115e05760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000806115ec3361113a565b915091508061163d5760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61164782846131f2565b60405183906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6001600160a01b038116600090815261139e602052604081205460ff16156116ee5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e4f6620756e646566696e65640000000000000000000000000000006044820152606401610f29565b506001600160a01b0316600090815261139f602052604090205490565b600f546001600160a01b0316336001600160a01b03161461175c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008281526113a360205260409020546001600160a01b03166117b55760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b6117c281610626846111a4565b60009283526113a160205260409092209190915550565b60008181526113a360205260408120546001600160a01b031615155b92915050565b600f546001600160a01b0316336001600160a01b03161461184c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b80600e541115801561186b57506118676001620186a0613bc2565b8111155b6118b75760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642064656e7369747900000000000000000000000000000000006044820152606401610f29565b600655565b600f546001600160a01b0316336001600160a01b03161461190d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600454811061194d5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600355565b600f546001600160a01b0316336001600160a01b0316146119a35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b7f0000000000000000000000000000000000000000000000000000000000000000811115611a135760405162461bcd60e51b815260206004820152600e60248201527f6d6f7265207468616e20313030250000000000000000000000000000000000006044820152606401610f29565b600b55565b60008181526113a360205260409020546001600160a01b0316806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600f546001600160a01b0316336001600160a01b031614611ac35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115611b155760405162461bcd60e51b815260206004820152601460248201527f696e76616c696420737570706c7920636f756e740000000000000000000000006044820152606401610f29565b600555565b6000611b29620186a083613b84565b905061108781612a9d565b600f546001600160a01b0316336001600160a01b031614611b855760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b4780611b9057600080fd5b600f546010546001600160a01b0390811691161415611bc257600f54611bbf906001600160a01b031647613341565b50565b601054611be2906001600160a01b0316611bdd600484613bae565b613341565b601154611bfd906001600160a01b0316611bdd600284613bae565b600f54611bbf906001600160a01b031647613341565b33600090815261139e602052604081205460ff16611c735760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206d73672e73656e64657200000000000000000000000000006044820152606401610f29565b600054600160a01b900460ff1615611cbf5760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000611cca84611a18565b9050611cd583611a18565b6001600160a01b0316816001600160a01b031614611d355760405162461bcd60e51b815260206004820152600f60248201527f646973706172617465206f776e657200000000000000000000000000000000006044820152606401610f29565b336001600160a01b03821614611d8d5760405162461bcd60e51b815260206004820152601060248201527f6e6f7420746f6b656e206f776e65722e000000000000000000000000000000006044820152606401610f29565b6001600160a01b03811660009081526113a060205260408120805460019290611db7908490613bc2565b90915550611dc7905084846133e4565b60008181526113a3602052604080822080546001600160a01b03191690555191935083916001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45092915050565b600f546001600160a01b0316336001600160a01b031614611e735760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b0316336001600160a01b031614611ee65760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b611bbf816130a7565b600f546001600160a01b0316336001600160a01b031614611f405760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b606060028054610e5190613ae6565b6003544210158015611f84575060045442105b611fd05760405162461bcd60e51b815260206004820152600d60248201527f73616c65206e6f74206f70656e000000000000000000000000000000000000006044820152606401610f29565b600554600954106120235760405162461bcd60e51b815260206004820152601260248201527f6d617820737570706c79207265616368656400000000000000000000000000006044820152606401610f29565b3233146120725760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f742075736520637573746f6d20636f6e74726163740000000000006044820152606401610f29565b3360008181526113a06020526040902054600954600d54600c54600f549315159492939192909186916001600160a01b0390911614156120b4575060006120d7565b60085484111580156120c4575084155b156120d757806120d381613bd9565b9150505b6007546120e49082613b37565b3410156121335760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420455448000000000000000000000000000000006044820152606401610f29565b600e5460006121428883613b56565b90506006548111156121965760405162461bcd60e51b815260206004820152601960248201527f746f74616c206d61782064656e736974792072656163686564000000000000006044820152606401610f29565b600e819055861561221e5733600090815261139e602052604090205460ff16156122025760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742075706461746520776c2064656e7369747900000000000000006044820152606401610f29565b61221461220e33611684565b896135e5565b5050505050505050565b60006005606461226460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61226e9190613b84565b1061227a57600161227d565b60025b60ff16905061228c818a6110ff565b60008881526113a160209081526040808320939093556113a3905290812080546001600160a01b03191633179055600a8054916122c883613bf0565b9190505550888510156122dc578894508695505b8660138861138981106122f1576122f1613b98565b0155600087815261139c602052604081208890556123119080338a612bd5565b8661231b81613bf0565b9750508660098190555085600d541461236e57600d869055600c85905560405185815286907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b505050505050505050565b6001600160a01b0382163314156123d25760405162461bcd60e51b815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610f29565b3360008181526113a5602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600f546001600160a01b0316336001600160a01b0316146124905760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b6001600160a01b0391909116600090815261139d60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b03161461250d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612551848484611132565b61255d848484846136b6565b6125a95760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b50505050565b600f546001600160a01b0316336001600160a01b0316146126005760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b662386f26fc1000047106126565760405162461bcd60e51b815260206004820152600a60248201527f6265206361726566756c000000000000000000000000000000000000000000006044820152606401610f29565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260409020546060906001600160a01b03166126d45760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600080548382526113a16020526040909120546001600160a01b039091169063592fa5cc908490612704906129c8565b60008681526113a1602052604090205461271d90611b1a565b600d5460009081526113a1602052604090205461273990611b1a565b600d5488146127478961150c565b6040516001600160e01b031960e089901b16815260048101969096526024860194909452604485019290925260648401521515608483015260a482015260c401600060405180830381865afa1580156127a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117f59190810190613c0b565b600060138261138981106127e2576127e2613b98565b015492915050565b600f546001600160a01b0316336001600160a01b03161461283b5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806003541061287b5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600455565b600f546001600160a01b0316336001600160a01b0316146128d15760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806129465760016128f8836001600160a01b031660009081526113a0602052604090205490565b11156129465760405162461bcd60e51b815260206004820152601660248201527f616464722063616e6e6f742062652072656d6f766564000000000000000000006044820152606401610f29565b6001600160a01b0391909116600090815261139e60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b0316146129c35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600755565b60006129d7620186a083613bae565b905061108781612a3f565b60008181526113a4602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b80600111158015612a51575060048111155b611bbf5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e0000000000000000000000006044820152606401610f29565b80600111158015612aba5750612ab76001620186a0613bc2565b81105b611bbf5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e00000000006044820152606401610f29565b60008181526113a360205260408120546001600160a01b03169081612b615760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b816001600160a01b0316846001600160a01b03161480612b9b575060008381526113a460205260409020546001600160a01b038581169116145b80612bcc57506001600160a01b0380831660009081526113a5602090815260408083209388168352929052205460ff165b90509250929050565b600054600160a01b900460ff1615612c215760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b826001600160a01b0316846001600160a01b031614612c825760405162461bcd60e51b815260206004820152600d60248201527f746f6b656e206e6f74206f776e000000000000000000000000000000000000006044820152606401610f29565b6001600160a01b038216612cd85760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f207a65726f2061646472000000006044820152606401610f29565b6001600160a01b038216600090815261139d602052604090205460ff1615612d425760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f20626c61636b6c697374000000006044820152606401610f29565b6001600160a01b03821661dead1415612dcf57612d5f84826131f2565b604051819061dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4604051819060009061dead907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a46125a9565b612ddb846000836129e2565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4816001600160a01b0316836001600160a01b03161415612e3b576125a9565b6001600160a01b03838116600090815261139e602052604080822054928516825290205460ff91821691168115612ea1576001600160a01b03851660009081526113a060205260408120805460019290612e96908490613bc2565b90915550612ebc9050565b6001600160a01b03851660009081526113a060205260408120555b8015612ef7576001600160a01b03841660009081526113a060205260408120805460019290612eec908490613b56565b90915550612f339050565b6001600160a01b038416600090815261139f6020526040902054612f33576001600160a01b03841660009081526113a060205260409020600190555b8015612f665760008381526113a36020526040902080546001600160a01b0319166001600160a01b03861617905561307f565b6001600160a01b038416600090815261139f602052604090205480612fc55760008481526113a36020908152604080832080546001600160a01b0319166001600160a01b038a16908117909155835261139f909152902084905561307d565b836000612fd283836133e4565b60405190915081906000906001600160a01b038a16907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a482818114156130195750815b60008281526113a36020526040902080546001600160a01b03191690558381146130795760008181526113a36020908152604080832080546001600160a01b0319166001600160a01b038d16908117909155835261139f90915290208190555b5050505b505b8161309f576001600160a01b038516600090815261139f60205260408120555b505050505050565b60008181526113a360205260409020546001600160a01b0316806131015760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b61310b81836131f2565b34156131b6576000816001600160a01b03163460405160006040518083038185875af1925050503d806000811461315e576040519150601f19603f3d011682016040523d82523d6000602084013e613163565b606091505b50509050806131b45760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b505b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6131fe826000836129e2565b60008181526113a1602052604090205461321790611b1a565b600e60008282546132289190613bc2565b90915550506001600160a01b038216600090815261139f602090815260408083208390558383526113a3825280832080546001600160a01b03191690556113a1825280832083905561139c909152812054600a54909190601390611389811061329357613293613b98565b015490508060138361138981106132ac576132ac613b98565b0155600081815261139c60205260408120839055600a8054916132ce83613bd9565b90915550506001600160a01b03841660009081526113a0602052604081208054600192906132fd908490613bc2565b909155505060405160008082529084907f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef906020015b60405180910390a350505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461338e576040519150601f19603f3d011682016040523d82523d6000602084013e613393565b606091505b50509050806110315760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b6000818314156134365760405162461bcd60e51b815260206004820152601160248201527f6964656e746963616c20746f6b656e49640000000000000000000000000000006044820152606401610f29565b60008381526113a1602052604081205461344f90611b1a565b60008481526113a160205260408120549192509061346c90611b1a565b9050818186868284106134855750839250849150869050875b60008181526113a16020526040812080548692906134a4908490613b56565b90915550600090506134b68585613b56565b9050600c5481111561350257600d829055600c81905560405181815282907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b60008281526113a26020526040812080549161351d83613bf0565b909155505060008381526113a16020908152604080832083905561139c909152812054600a54909190601390611389811061355a5761355a613b98565b0154905080601383611389811061357357613573613b98565b0155600081815261139c60205260408120839055600a80549161359583613bd9565b919050555083857f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef856040516135cd91815260200190565b60405180910390a350929a9950505050505050505050565b60008281526113a160205260408120546135fe90611b1a565b9050816113a1600085815260200190815260200160002060008282546136249190613b56565b90915550600090506136368383613b56565b9050600c5481111561368257600d849055600c81905560405181815284907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b8360007f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef8360405161333391815260200190565b6000833b156137d057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136f1903390899088908890600401613c82565b6020604051808303816000875af192505050801561372c575060408051601f3d908101601f1916820190925261372991810190613cb4565b60015b6137b6573d80801561375a576040519150601f19603f3d011682016040523d82523d6000602084013e61375f565b606091505b5080516137ae5760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506137d4565b5060015b949350505050565b6001600160e01b031981168114611bbf57600080fd5b60006020828403121561380457600080fd5b813561112b816137dc565b60005b8381101561382a578181015183820152602001613812565b838111156125a95750506000910152565b6000815180845261385381602086016020860161380f565b601f01601f19169290920160200192915050565b60208152600061112b602083018461383b565b60006020828403121561388c57600080fd5b5035919050565b80356001600160a01b038116811461108757600080fd5b600080604083850312156138bd57600080fd5b6138c683613893565b946020939093013593505050565b6000602082840312156138e657600080fd5b61112b82613893565b6000806040838503121561390257600080fd5b50508035926020909101359150565b60008060006060848603121561392657600080fd5b61392f84613893565b925061393d60208501613893565b9150604084013590509250925092565b8035801515811461108757600080fd5b6000806040838503121561397057600080fd5b61397983613893565b9150612bcc6020840161394d565b60006020828403121561399957600080fd5b61112b8261394d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139e1576139e16139a2565b604052919050565b600067ffffffffffffffff821115613a0357613a036139a2565b50601f01601f191660200190565b60008060008060808587031215613a2757600080fd5b613a3085613893565b9350613a3e60208601613893565b925060408501359150606085013567ffffffffffffffff811115613a6157600080fd5b8501601f81018713613a7257600080fd5b8035613a85613a80826139e9565b6139b8565b818152886020838501011115613a9a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060408385031215613acf57600080fd5b613ad883613893565b9150612bcc60208401613893565b600181811c90821680613afa57607f821691505b60208210811415613b1b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613b5157613b51613b21565b500290565b60008219821115613b6957613b69613b21565b500190565b634e487b7160e01b600052601260045260246000fd5b600082613b9357613b93613b6e565b500690565b634e487b7160e01b600052603260045260246000fd5b600082613bbd57613bbd613b6e565b500490565b600082821015613bd457613bd4613b21565b500390565b600081613be857613be8613b21565b506000190190565b6000600019821415613c0457613c04613b21565b5060010190565b600060208284031215613c1d57600080fd5b815167ffffffffffffffff811115613c3457600080fd5b8201601f81018413613c4557600080fd5b8051613c53613a80826139e9565b818152856020838501011115613c6857600080fd5b613c7982602083016020860161380f565b95945050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152610e38608083018461383b565b600060208284031215613cc657600080fd5b815161112b816137dc56fe6d73672e73656e646572206973206e6f742068616b0000000000000000000000a26469706673582212201e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f62864736f6c634300080a00330000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8

Deployed Bytecode

0x6080604052600436106104655760003560e01c8063525f8a5c11610243578063a755516011610143578063dbf65de0116100bb578063e985e9c51161008a578063ec259d171161006f578063ec259d1714610cf0578063fb1fac1814610d10578063fe575a8714610d2657600080fd5b8063e985e9c514610c86578063eafe706e14610cd057600080fd5b8063dbf65de014610c1a578063dc1b732814610c3a578063dcfb383314610c5a578063dde502d114610c7057600080fd5b8063b88d4fde11610112578063c87b56dd116100f7578063c87b56dd14610bba578063cbd14a7d14610bda578063d132391a14610bfa57600080fd5b8063b88d4fde14610b7a578063b8d4a4aa14610b9a57600080fd5b8063a755516014610af6578063a819e4e414610b16578063a8a07b3614610b2c578063b5bf15e514610b5a57600080fd5b8063853828b6116101d65780639121ac0d116101a557806395d89b411161018a57806395d89b4114610aae578063a0712d6814610ac3578063a22cb46514610ad657600080fd5b80639121ac0d14610a5a5780639377736914610a8e57600080fd5b8063853828b6146109f25780638a50fecb14610a075780638dc251e314610a2757806390b5098814610a4757600080fd5b80636f8b44b0116102125780636f8b44b01461096557806370a082311461098557806375a99b9f146109bc57806378907bf7146109d257600080fd5b8063525f8a5c146108e557806355d5f96314610905578063629a5334146109255780636352211e1461094557600080fd5b8063258ef43911610369578063423abb61116102e157806343f51ebb116102b05780634885382a116102955780634885382a1461088f5780634f558e79146108a5578063504ce0e2146108c557600080fd5b806343f51ebb1461085957806343fa2c9c1461087957600080fd5b8063423abb61146107d957806342842e0e146107f957806342966c681461081957806342ec38e21461083957600080fd5b80632b447ff511610338578063341815f61161031d578063341815f614610769578063369b012d1461077f5780633af32abf1461079f57600080fd5b80632b447ff5146107335780632bddccdc1461075357600080fd5b8063258ef4391461069757806327686691146106b75780632a347f61146106ec5780632a55205a146106f457600080fd5b80630ab2b6b9116103fc5780631ef467e1116103cb57806323b872dd116103b057806323b872dd1461064157806324032e9814610661578063254709d31461068157600080fd5b80631ef467e11461060b57806322f4596f1461062b57600080fd5b80630ab2b6b9146105a05780630e21750f146105c057806314066c7c146105e057806318160ddd146105f657600080fd5b806306fdde031161043857806306fdde031461051c5780630764789a1461053e578063081812fc1461055e578063095ea7b31461057e57600080fd5b806301ffc9a71461046a578063029108911461049f57806302964ff1146104c3578063054f7d9c146104fb575b600080fd5b34801561047657600080fd5b5061048a6104853660046137f2565b610d60565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b5600d5481565b604051908152602001610496565b3480156104cf57600080fd5b506012546104e3906001600160a01b031681565b6040516001600160a01b039091168152602001610496565b34801561050757600080fd5b5060005461048a90600160a01b900460ff1681565b34801561052857600080fd5b50610531610e42565b6040516104969190613867565b34801561054a57600080fd5b50600f546104e3906001600160a01b031681565b34801561056a57600080fd5b506104e361057936600461387a565b610ed4565b34801561058a57600080fd5b5061059e6105993660046138aa565b610f4f565b005b3480156105ac57600080fd5b506104b56105bb36600461387a565b611036565b3480156105cc57600080fd5b5061059e6105db3660046138d4565b61108c565b3480156105ec57600080fd5b506104b560045481565b34801561060257600080fd5b50600a546104b5565b34801561061757600080fd5b506104b56106263660046138ef565b6110ff565b34801561063757600080fd5b506104b560055481565b34801561064d57600080fd5b5061059e61065c366004613911565b611132565b34801561066d57600080fd5b506011546104e3906001600160a01b031681565b34801561068d57600080fd5b506104b5600c5481565b3480156106a357600080fd5b506104b56106b236600461387a565b6111a4565b3480156106c357600080fd5b506106d76106d236600461387a565b6111bb565b60408051928352602083019190915201610496565b61059e6111e2565b34801561070057600080fd5b5061071461070f3660046138ef565b61138e565b604080516001600160a01b039093168352602083019190915201610496565b34801561073f57600080fd5b5061059e61074e36600461387a565b6113e3565b34801561075f57600080fd5b506104b560095481565b34801561077557600080fd5b506104b5600e5481565b34801561078b57600080fd5b5061059e61079a3660046138d4565b611499565b3480156107ab57600080fd5b5061048a6107ba3660046138d4565b6001600160a01b0316600090815261139e602052604090205460ff1690565b3480156107e557600080fd5b506104b56107f436600461387a565b61150c565b34801561080557600080fd5b5061059e610814366004613911565b611579565b34801561082557600080fd5b5061059e61083436600461387a565b611594565b34801561084557600080fd5b506104b56108543660046138d4565b611684565b34801561086557600080fd5b5061059e6108743660046138ef565b61170b565b34801561088557600080fd5b506104b5600b5481565b34801561089b57600080fd5b506104b560085481565b3480156108b157600080fd5b5061048a6108c036600461387a565b6117d9565b3480156108d157600080fd5b5061059e6108e036600461387a565b6117fb565b3480156108f157600080fd5b5061059e61090036600461387a565b6118bc565b34801561091157600080fd5b506000546104e3906001600160a01b031681565b34801561093157600080fd5b5061059e61094036600461387a565b611952565b34801561095157600080fd5b506104e361096036600461387a565b611a18565b34801561097157600080fd5b5061059e61098036600461387a565b611a72565b34801561099157600080fd5b506104b56109a03660046138d4565b6001600160a01b031660009081526113a0602052604090205490565b3480156109c857600080fd5b506104b560035481565b3480156109de57600080fd5b506104b56109ed36600461387a565b611b1a565b3480156109fe57600080fd5b5061059e611b34565b348015610a1357600080fd5b506104b5610a223660046138ef565b611c13565b348015610a3357600080fd5b5061059e610a423660046138d4565b611e22565b61059e610a5536600461387a565b611e95565b348015610a6657600080fd5b506104b57f000000000000000000000000000000000000000000000000000000000000271081565b348015610a9a57600080fd5b5061059e610aa93660046138d4565b611eef565b348015610aba57600080fd5b50610531611f62565b61059e610ad136600461387a565b611f71565b348015610ae257600080fd5b5061059e610af136600461395d565b612379565b348015610b0257600080fd5b5061059e610b1136600461395d565b61243f565b348015610b2257600080fd5b506104b560065481565b348015610b3857600080fd5b506104b5610b4736600461387a565b600090815261139c602052604090205490565b348015610b6657600080fd5b5061059e610b75366004613987565b6124bc565b348015610b8657600080fd5b5061059e610b95366004613a11565b612546565b348015610ba657600080fd5b5061059e610bb53660046138d4565b6125af565b348015610bc657600080fd5b50610531610bd536600461387a565b612678565b348015610be657600080fd5b506104b5610bf536600461387a565b6127cc565b348015610c0657600080fd5b5061059e610c1536600461387a565b6127ea565b348015610c2657600080fd5b5061059e610c3536600461395d565b612880565b348015610c4657600080fd5b5061059e610c5536600461387a565b612972565b348015610c6657600080fd5b506104e361dead81565b348015610c7c57600080fd5b506104b560075481565b348015610c9257600080fd5b5061048a610ca1366004613abc565b6001600160a01b0391821660009081526113a56020908152604080832093909416825291909152205460ff1690565b348015610cdc57600080fd5b506104b5610ceb36600461387a565b6129c8565b348015610cfc57600080fd5b506010546104e3906001600160a01b031681565b348015610d1c57600080fd5b506104b5600a5481565b348015610d3257600080fd5b5061048a610d413660046138d4565b6001600160a01b0316600090815261139d602052604090205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f80ac58cd000000000000000000000000000000000000000000000000000000007f2a55205a000000000000000000000000000000000000000000000000000000007f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03198616841480610e0a57506001600160e01b0319868116908416145b80610e2157506001600160e01b0319868116908316145b80610e3857506001600160e01b0319868116908216145b9695505050505050565b606060018054610e5190613ae6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7d90613ae6565b8015610eca5780601f10610e9f57610100808354040283529160200191610eca565b820191906000526020600020905b815481529060010190602001808311610ead57829003601f168201915b5050505050905090565b60008181526113a360205260408120546001600160a01b0316610f325760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b60448201526064015b60405180910390fd5b5060009081526113a460205260409020546001600160a01b031690565b6000610f5a82611a18565b9050806001600160a01b0316836001600160a01b03161415610fbe5760405162461bcd60e51b815260206004820152601960248201527f617070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610f29565b336001600160a01b0382161480610fda5750610fda8133610ca1565b6110265760405162461bcd60e51b815260206004820152601e60248201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610f29565b6110318184846129e2565b505050565b60008181526113a16020526040902054806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b919050565b600f546001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110a83612a3f565b61111382612a9d565b81611121620186a085613b37565b61112b9190613b56565b9392505050565b600080611140335b84612b06565b91509150806111915760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61119d82868686612bd5565b5050505050565b6000806111b083611036565b905061112b81611b1a565b60008060006111c9846129c8565b905060006111d685611b1a565b91959194509092505050565b600f546001600160a01b0316336001600160a01b0316146112335760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60006013600a5461127a60408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b6112849190613b84565b61128f906001613b56565b61138981106112a0576112a0613b98565b0154905060005b6112b0826111a4565b600c5460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a090920190925280519101206112f79190613b84565b1115611381576013600a5461134260408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61134c9190613b84565b611357906001613b56565b611389811061136857611368613b98565b015490508082141561137957611381565b8091506112a7565b61138a826130a7565b5050565b60008060007f0000000000000000000000000000000000000000000000000000000000002710600b54856113c29190613b37565b6113cc9190613bae565b6012546001600160a01b0316969095509350505050565b600f546001600160a01b0316336001600160a01b0316146114345760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115801561144857506005548111155b6114945760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420696e646578000000000000000000000000000000000000006044820152606401610f29565b600855565b600f546001600160a01b0316336001600160a01b0316146114ea5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260408120546001600160a01b03166115655760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b5060009081526113a2602052604090205490565b61103183838360405180602001604052806000815250612546565b600054600160a01b900460ff16156115e05760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000806115ec3361113a565b915091508061163d5760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61164782846131f2565b60405183906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6001600160a01b038116600090815261139e602052604081205460ff16156116ee5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e4f6620756e646566696e65640000000000000000000000000000006044820152606401610f29565b506001600160a01b0316600090815261139f602052604090205490565b600f546001600160a01b0316336001600160a01b03161461175c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008281526113a360205260409020546001600160a01b03166117b55760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b6117c281610626846111a4565b60009283526113a160205260409092209190915550565b60008181526113a360205260408120546001600160a01b031615155b92915050565b600f546001600160a01b0316336001600160a01b03161461184c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b80600e541115801561186b57506118676001620186a0613bc2565b8111155b6118b75760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642064656e7369747900000000000000000000000000000000006044820152606401610f29565b600655565b600f546001600160a01b0316336001600160a01b03161461190d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600454811061194d5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600355565b600f546001600160a01b0316336001600160a01b0316146119a35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b7f0000000000000000000000000000000000000000000000000000000000002710811115611a135760405162461bcd60e51b815260206004820152600e60248201527f6d6f7265207468616e20313030250000000000000000000000000000000000006044820152606401610f29565b600b55565b60008181526113a360205260409020546001600160a01b0316806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600f546001600160a01b0316336001600160a01b031614611ac35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115611b155760405162461bcd60e51b815260206004820152601460248201527f696e76616c696420737570706c7920636f756e740000000000000000000000006044820152606401610f29565b600555565b6000611b29620186a083613b84565b905061108781612a9d565b600f546001600160a01b0316336001600160a01b031614611b855760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b4780611b9057600080fd5b600f546010546001600160a01b0390811691161415611bc257600f54611bbf906001600160a01b031647613341565b50565b601054611be2906001600160a01b0316611bdd600484613bae565b613341565b601154611bfd906001600160a01b0316611bdd600284613bae565b600f54611bbf906001600160a01b031647613341565b33600090815261139e602052604081205460ff16611c735760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206d73672e73656e64657200000000000000000000000000006044820152606401610f29565b600054600160a01b900460ff1615611cbf5760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000611cca84611a18565b9050611cd583611a18565b6001600160a01b0316816001600160a01b031614611d355760405162461bcd60e51b815260206004820152600f60248201527f646973706172617465206f776e657200000000000000000000000000000000006044820152606401610f29565b336001600160a01b03821614611d8d5760405162461bcd60e51b815260206004820152601060248201527f6e6f7420746f6b656e206f776e65722e000000000000000000000000000000006044820152606401610f29565b6001600160a01b03811660009081526113a060205260408120805460019290611db7908490613bc2565b90915550611dc7905084846133e4565b60008181526113a3602052604080822080546001600160a01b03191690555191935083916001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45092915050565b600f546001600160a01b0316336001600160a01b031614611e735760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b0316336001600160a01b031614611ee65760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b611bbf816130a7565b600f546001600160a01b0316336001600160a01b031614611f405760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b606060028054610e5190613ae6565b6003544210158015611f84575060045442105b611fd05760405162461bcd60e51b815260206004820152600d60248201527f73616c65206e6f74206f70656e000000000000000000000000000000000000006044820152606401610f29565b600554600954106120235760405162461bcd60e51b815260206004820152601260248201527f6d617820737570706c79207265616368656400000000000000000000000000006044820152606401610f29565b3233146120725760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f742075736520637573746f6d20636f6e74726163740000000000006044820152606401610f29565b3360008181526113a06020526040902054600954600d54600c54600f549315159492939192909186916001600160a01b0390911614156120b4575060006120d7565b60085484111580156120c4575084155b156120d757806120d381613bd9565b9150505b6007546120e49082613b37565b3410156121335760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420455448000000000000000000000000000000006044820152606401610f29565b600e5460006121428883613b56565b90506006548111156121965760405162461bcd60e51b815260206004820152601960248201527f746f74616c206d61782064656e736974792072656163686564000000000000006044820152606401610f29565b600e819055861561221e5733600090815261139e602052604090205460ff16156122025760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742075706461746520776c2064656e7369747900000000000000006044820152606401610f29565b61221461220e33611684565b896135e5565b5050505050505050565b60006005606461226460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61226e9190613b84565b1061227a57600161227d565b60025b60ff16905061228c818a6110ff565b60008881526113a160209081526040808320939093556113a3905290812080546001600160a01b03191633179055600a8054916122c883613bf0565b9190505550888510156122dc578894508695505b8660138861138981106122f1576122f1613b98565b0155600087815261139c602052604081208890556123119080338a612bd5565b8661231b81613bf0565b9750508660098190555085600d541461236e57600d869055600c85905560405185815286907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b505050505050505050565b6001600160a01b0382163314156123d25760405162461bcd60e51b815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610f29565b3360008181526113a5602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600f546001600160a01b0316336001600160a01b0316146124905760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b6001600160a01b0391909116600090815261139d60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b03161461250d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612551848484611132565b61255d848484846136b6565b6125a95760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b50505050565b600f546001600160a01b0316336001600160a01b0316146126005760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b662386f26fc1000047106126565760405162461bcd60e51b815260206004820152600a60248201527f6265206361726566756c000000000000000000000000000000000000000000006044820152606401610f29565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260409020546060906001600160a01b03166126d45760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600080548382526113a16020526040909120546001600160a01b039091169063592fa5cc908490612704906129c8565b60008681526113a1602052604090205461271d90611b1a565b600d5460009081526113a1602052604090205461273990611b1a565b600d5488146127478961150c565b6040516001600160e01b031960e089901b16815260048101969096526024860194909452604485019290925260648401521515608483015260a482015260c401600060405180830381865afa1580156127a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117f59190810190613c0b565b600060138261138981106127e2576127e2613b98565b015492915050565b600f546001600160a01b0316336001600160a01b03161461283b5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806003541061287b5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600455565b600f546001600160a01b0316336001600160a01b0316146128d15760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806129465760016128f8836001600160a01b031660009081526113a0602052604090205490565b11156129465760405162461bcd60e51b815260206004820152601660248201527f616464722063616e6e6f742062652072656d6f766564000000000000000000006044820152606401610f29565b6001600160a01b0391909116600090815261139e60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b0316146129c35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600755565b60006129d7620186a083613bae565b905061108781612a3f565b60008181526113a4602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b80600111158015612a51575060048111155b611bbf5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e0000000000000000000000006044820152606401610f29565b80600111158015612aba5750612ab76001620186a0613bc2565b81105b611bbf5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e00000000006044820152606401610f29565b60008181526113a360205260408120546001600160a01b03169081612b615760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b816001600160a01b0316846001600160a01b03161480612b9b575060008381526113a460205260409020546001600160a01b038581169116145b80612bcc57506001600160a01b0380831660009081526113a5602090815260408083209388168352929052205460ff165b90509250929050565b600054600160a01b900460ff1615612c215760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b826001600160a01b0316846001600160a01b031614612c825760405162461bcd60e51b815260206004820152600d60248201527f746f6b656e206e6f74206f776e000000000000000000000000000000000000006044820152606401610f29565b6001600160a01b038216612cd85760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f207a65726f2061646472000000006044820152606401610f29565b6001600160a01b038216600090815261139d602052604090205460ff1615612d425760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f20626c61636b6c697374000000006044820152606401610f29565b6001600160a01b03821661dead1415612dcf57612d5f84826131f2565b604051819061dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4604051819060009061dead907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a46125a9565b612ddb846000836129e2565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4816001600160a01b0316836001600160a01b03161415612e3b576125a9565b6001600160a01b03838116600090815261139e602052604080822054928516825290205460ff91821691168115612ea1576001600160a01b03851660009081526113a060205260408120805460019290612e96908490613bc2565b90915550612ebc9050565b6001600160a01b03851660009081526113a060205260408120555b8015612ef7576001600160a01b03841660009081526113a060205260408120805460019290612eec908490613b56565b90915550612f339050565b6001600160a01b038416600090815261139f6020526040902054612f33576001600160a01b03841660009081526113a060205260409020600190555b8015612f665760008381526113a36020526040902080546001600160a01b0319166001600160a01b03861617905561307f565b6001600160a01b038416600090815261139f602052604090205480612fc55760008481526113a36020908152604080832080546001600160a01b0319166001600160a01b038a16908117909155835261139f909152902084905561307d565b836000612fd283836133e4565b60405190915081906000906001600160a01b038a16907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a482818114156130195750815b60008281526113a36020526040902080546001600160a01b03191690558381146130795760008181526113a36020908152604080832080546001600160a01b0319166001600160a01b038d16908117909155835261139f90915290208190555b5050505b505b8161309f576001600160a01b038516600090815261139f60205260408120555b505050505050565b60008181526113a360205260409020546001600160a01b0316806131015760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b61310b81836131f2565b34156131b6576000816001600160a01b03163460405160006040518083038185875af1925050503d806000811461315e576040519150601f19603f3d011682016040523d82523d6000602084013e613163565b606091505b50509050806131b45760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b505b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6131fe826000836129e2565b60008181526113a1602052604090205461321790611b1a565b600e60008282546132289190613bc2565b90915550506001600160a01b038216600090815261139f602090815260408083208390558383526113a3825280832080546001600160a01b03191690556113a1825280832083905561139c909152812054600a54909190601390611389811061329357613293613b98565b015490508060138361138981106132ac576132ac613b98565b0155600081815261139c60205260408120839055600a8054916132ce83613bd9565b90915550506001600160a01b03841660009081526113a0602052604081208054600192906132fd908490613bc2565b909155505060405160008082529084907f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef906020015b60405180910390a350505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461338e576040519150601f19603f3d011682016040523d82523d6000602084013e613393565b606091505b50509050806110315760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b6000818314156134365760405162461bcd60e51b815260206004820152601160248201527f6964656e746963616c20746f6b656e49640000000000000000000000000000006044820152606401610f29565b60008381526113a1602052604081205461344f90611b1a565b60008481526113a160205260408120549192509061346c90611b1a565b9050818186868284106134855750839250849150869050875b60008181526113a16020526040812080548692906134a4908490613b56565b90915550600090506134b68585613b56565b9050600c5481111561350257600d829055600c81905560405181815282907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b60008281526113a26020526040812080549161351d83613bf0565b909155505060008381526113a16020908152604080832083905561139c909152812054600a54909190601390611389811061355a5761355a613b98565b0154905080601383611389811061357357613573613b98565b0155600081815261139c60205260408120839055600a80549161359583613bd9565b919050555083857f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef856040516135cd91815260200190565b60405180910390a350929a9950505050505050505050565b60008281526113a160205260408120546135fe90611b1a565b9050816113a1600085815260200190815260200160002060008282546136249190613b56565b90915550600090506136368383613b56565b9050600c5481111561368257600d849055600c81905560405181815284907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b8360007f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef8360405161333391815260200190565b6000833b156137d057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136f1903390899088908890600401613c82565b6020604051808303816000875af192505050801561372c575060408051601f3d908101601f1916820190925261372991810190613cb4565b60015b6137b6573d80801561375a576040519150601f19603f3d011682016040523d82523d6000602084013e61375f565b606091505b5080516137ae5760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506137d4565b5060015b949350505050565b6001600160e01b031981168114611bbf57600080fd5b60006020828403121561380457600080fd5b813561112b816137dc565b60005b8381101561382a578181015183820152602001613812565b838111156125a95750506000910152565b6000815180845261385381602086016020860161380f565b601f01601f19169290920160200192915050565b60208152600061112b602083018461383b565b60006020828403121561388c57600080fd5b5035919050565b80356001600160a01b038116811461108757600080fd5b600080604083850312156138bd57600080fd5b6138c683613893565b946020939093013593505050565b6000602082840312156138e657600080fd5b61112b82613893565b6000806040838503121561390257600080fd5b50508035926020909101359150565b60008060006060848603121561392657600080fd5b61392f84613893565b925061393d60208501613893565b9150604084013590509250925092565b8035801515811461108757600080fd5b6000806040838503121561397057600080fd5b61397983613893565b9150612bcc6020840161394d565b60006020828403121561399957600080fd5b61112b8261394d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139e1576139e16139a2565b604052919050565b600067ffffffffffffffff821115613a0357613a036139a2565b50601f01601f191660200190565b60008060008060808587031215613a2757600080fd5b613a3085613893565b9350613a3e60208601613893565b925060408501359150606085013567ffffffffffffffff811115613a6157600080fd5b8501601f81018713613a7257600080fd5b8035613a85613a80826139e9565b6139b8565b818152886020838501011115613a9a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060408385031215613acf57600080fd5b613ad883613893565b9150612bcc60208401613893565b600181811c90821680613afa57607f821691505b60208210811415613b1b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613b5157613b51613b21565b500290565b60008219821115613b6957613b69613b21565b500190565b634e487b7160e01b600052601260045260246000fd5b600082613b9357613b93613b6e565b500690565b634e487b7160e01b600052603260045260246000fd5b600082613bbd57613bbd613b6e565b500490565b600082821015613bd457613bd4613b21565b500390565b600081613be857613be8613b21565b506000190190565b6000600019821415613c0457613c04613b21565b5060010190565b600060208284031215613c1d57600080fd5b815167ffffffffffffffff811115613c3457600080fd5b8201601f81018413613c4557600080fd5b8051613c53613a80826139e9565b818152856020838501011115613c6857600080fd5b613c7982602083016020860161380f565b95945050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152610e38608083018461383b565b600060208284031215613cc657600080fd5b815161112b816137dc56fe6d73672e73656e646572206973206e6f742068616b0000000000000000000000a26469706673582212201e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f62864736f6c634300080a0033

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

0000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8

-----Decoded View---------------
Arg [0] : metadataGenerator_ (address): 0x3569FBC5B9cB5E21a18B632c97C32F7a296734F5
Arg [1] : collab_ (address): 0x405937f8AD695b20bB2eB4630c7bC9BaE23326d8
Arg [2] : fund_ (address): 0xf80A1479f144e3a2F74A77ca9C07964B7349c4f8

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5
Arg [1] : 000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8
Arg [2] : 000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8


Deployed Bytecode Sourcemap

53636:29697:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81927:435;;;;;;;;;;-1:-1:-1;81927:435:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;81927:435:0;;;;;;;;54683:23;;;;;;;;;;;;;;;;;;;784:25:1;;;772:2;757:18;54683:23:0;638:177:1;54834:24:0;;;;;;;;;;-1:-1:-1;54834:24:0;;;;-1:-1:-1;;;;;54834:24:0;;;;;;-1:-1:-1;;;;;984:55:1;;;966:74;;954:2;939:18;54834:24:0;820:226:1;53740:18:0;;;;;;;;;;-1:-1:-1;53740:18:0;;;;-1:-1:-1;;;53740:18:0;;;;;;58402:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54752:19::-;;;;;;;;;;-1:-1:-1;54752:19:0;;;;-1:-1:-1;;;;;54752:19:0;;;77302:199;;;;;;;;;;-1:-1:-1;77302:199:0;;;;;:::i;:::-;;:::i;76754:361::-;;;;;;;;;;-1:-1:-1;76754:361:0;;;;;:::i;:::-;;:::i;:::-;;76359:175;;;;;;;;;;-1:-1:-1;76359:175:0;;;;;:::i;:::-;;:::i;68584:83::-;;;;;;;;;;-1:-1:-1;68584:83:0;;;;;:::i;:::-;;:::i;54271:40::-;;;;;;;;;;;;;;;;58623:90;;;;;;;;;;-1:-1:-1;58694:11:0;;58623:90;;79266:229;;;;;;;;;;-1:-1:-1;79266:229:0;;;;;:::i;:::-;;:::i;54320:32::-;;;;;;;;;;;;;;;;75746:300;;;;;;;;;;-1:-1:-1;75746:300:0;;;;;:::i;:::-;;:::i;54807:20::-;;;;;;;;;;-1:-1:-1;54807:20:0;;;;-1:-1:-1;;;;;54807:20:0;;;54646:28;;;;;;;;;;;;;;;;76185:166;;;;;;;;;;-1:-1:-1;76185:166:0;;;;;:::i;:::-;;:::i;79503:221::-;;;;;;;;;;-1:-1:-1;79503:221:0;;;;;:::i;:::-;;:::i;:::-;;;;3398:25:1;;;3454:2;3439:18;;3432:34;;;;3371:18;79503:221:0;3224:248:1;74817:489:0;;;:::i;68101:236::-;;;;;;;;;;-1:-1:-1;68101:236:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3669:55:1;;;3651:74;;3756:2;3741:18;;3734:34;;;;3624:18;68101:236:0;3477:297:1;69519:175:0;;;;;;;;;;-1:-1:-1;69519:175:0;;;;;:::i;:::-;;:::i;54485:26::-;;;;;;;;;;;;;;;;54715:28;;;;;;;;;;;;;;;;68485:91;;;;;;;;;;-1:-1:-1;68485:91:0;;;;;:::i;:::-;;:::i;70447:121::-;;;;;;;;;;-1:-1:-1;70447:121:0;;;;;:::i;:::-;-1:-1:-1;;;;;70533:27:0;70509:4;70533:27;;;:17;:27;;;;;;;;;70447:121;56247:190;;;;;;;;;;-1:-1:-1;56247:190:0;;;;;:::i;:::-;;:::i;75314:151::-;;;;;;;;;;-1:-1:-1;75314:151:0;;;;;:::i;:::-;;:::i;82372:315::-;;;;;;;;;;-1:-1:-1;82372:315:0;;;;;:::i;:::-;;:::i;76542:204::-;;;;;;;;;;-1:-1:-1;76542:204:0;;;;;:::i;:::-;;:::i;79043:215::-;;;;;;;;;;-1:-1:-1;79043:215:0;;;;;:::i;:::-;;:::i;54604:33::-;;;;;;;;;;;;;;;;54444:31;;;;;;;;;;;;;;;;77974:102;;;;;;;;;;-1:-1:-1;77974:102:0;;;;;:::i;:::-;;:::i;69706:195::-;;;;;;;;;;-1:-1:-1;69706:195:0;;;;;:::i;:::-;;:::i;68931:207::-;;;;;;;;;;-1:-1:-1;68931:207:0;;;;;:::i;:::-;;:::i;53689:42::-;;;;;;;;;;-1:-1:-1;53689:42:0;;;;-1:-1:-1;;;;;53689:42:0;;;67890:203;;;;;;;;;;-1:-1:-1;67890:203:0;;;;;:::i;:::-;;:::i;70705:183::-;;;;;;;;;;-1:-1:-1;70705:183:0;;;;;:::i;:::-;;:::i;69353:158::-;;;;;;;;;;-1:-1:-1;69353:158:0;;;;;:::i;:::-;;:::i;76054:123::-;;;;;;;;;;-1:-1:-1;76054:123:0;;;;;:::i;:::-;-1:-1:-1;;;;;76145:16:0;76118:7;76145:16;;;:9;:16;;;;;;;76054:123;54222:42;;;;;;;;;;;;;;;;79956:220;;;;;;;;;;-1:-1:-1;79956:220:0;;;;;:::i;:::-;;:::i;80282:463::-;;;;;;;;;;;;;:::i;58722:695::-;;;;;;;;;;-1:-1:-1;58722:695:0;;;;;:::i;:::-;;:::i;69909:106::-;;;;;;;;;;-1:-1:-1;69909:106:0;;;;;:::i;:::-;;:::i;74705:104::-;;;;;;:::i;:::-;;:::i;54556:41::-;;;;;;;;;;;;;;;70027:153;;;;;;;;;;-1:-1:-1;70027:153:0;;;;;:::i;:::-;;:::i;58510:104::-;;;;;;;;;;;;;:::i;71045:2794::-;;;;;;:::i;:::-;;:::i;77509:285::-;;;;;;;;;;-1:-1:-1;77509:285:0;;;;;:::i;:::-;;:::i;68345:132::-;;;;;;;;;;-1:-1:-1;68345:132:0;;;;;:::i;:::-;;:::i;54359:34::-;;;;;;;;;;;;;;;;56581:132;;;;;;;;;;-1:-1:-1;56581:132:0;;;;;:::i;:::-;56648:13;56681:24;;;:15;:24;;;;;;;56581:132;74202:80;;;;;;;;;;-1:-1:-1;74202:80:0;;;;;:::i;:::-;;:::i;75473:265::-;;;;;;;;;;-1:-1:-1;75473:265:0;;;;;:::i;:::-;;:::i;68675:139::-;;;;;;;;;;-1:-1:-1;68675:139:0;;;;;:::i;:::-;;:::i;78585:450::-;;;;;;;;;;-1:-1:-1;78585:450:0;;;;;:::i;:::-;;:::i;56445:128::-;;;;;;;;;;-1:-1:-1;56445:128:0;;;;;:::i;:::-;;:::i;69146:199::-;;;;;;;;;;-1:-1:-1;69146:199:0;;;;;:::i;:::-;;:::i;70191:248::-;;;;;;;;;;-1:-1:-1;70191:248:0;;;;;:::i;:::-;;:::i;68822:101::-;;;;;;;;;;-1:-1:-1;68822:101:0;;;;;:::i;:::-;;:::i;54865:74::-;;;;;;;;;;;;54897:42;54865:74;;54402:33;;;;;;;;;;;;;;;;77802:164;;;;;;;;;;-1:-1:-1;77802:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;77923:25:0;;;77899:4;77923:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;77802:164;79732:212;;;;;;;;;;-1:-1:-1;79732:212:0;;;;;:::i;:::-;;:::i;54778:22::-;;;;;;;;;;-1:-1:-1;54778:22:0;;;;-1:-1:-1;;;;;54778:22:0;;;54521:26;;;;;;;;;;;;;;;;70576:121;;;;;;;;;;-1:-1:-1;70576:121:0;;;;;:::i;:::-;-1:-1:-1;;;;;70662:27:0;70638:4;70662:27;;;:17;:27;;;;;;;;;70576:121;81927:435;82012:4;82029:28;82068;82107:29;82147:36;-1:-1:-1;;;;;;82201:23:0;;;;;:64;;-1:-1:-1;;;;;;;82242:23:0;;;;;;;82201:64;:105;;;-1:-1:-1;;;;;;;82282:24:0;;;;;;;82201:105;:153;;;-1:-1:-1;;;;;;;82323:31:0;;;;;;;82201:153;82194:160;81927:435;-1:-1:-1;;;;;;81927:435:0:o;58402:100::-;58456:13;58489:5;58482:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58402:100;:::o;77302:199::-;77378:7;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;77398:46;;;;-1:-1:-1;;;77398:46:0;;7106:2:1;77398:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;77398:46:0;;;;;;;;;-1:-1:-1;77469:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;77469:24:0;;77302:199::o;76754:361::-;76835:13;76851:16;76859:7;76851;:16::i;:::-;76835:32;;76892:5;-1:-1:-1;;;;;76886:11:0;:2;-1:-1:-1;;;;;76886:11:0;;;76878:49;;;;-1:-1:-1;;;76878:49:0;;7452:2:1;76878:49:0;;;7434:21:1;7491:2;7471:18;;;7464:30;7530:27;7510:18;;;7503:55;7575:18;;76878:49:0;7250:349:1;76878:49:0;80256:10;-1:-1:-1;;;;;76948:21:0;;;;:62;;-1:-1:-1;76973:37:0;76990:5;80256:10;77802:164;:::i;76973:37::-;76940:128;;;;-1:-1:-1;;;76940:128:0;;7806:2:1;76940:128:0;;;7788:21:1;7845:2;7825:18;;;7818:30;7884:32;7864:18;;;7857:60;7934:18;;76940:128:0;7604:354:1;76940:128:0;77079:28;77088:5;77095:2;77099:7;77079:8;:28::i;:::-;76824:291;76754:361;;:::o;76359:175::-;76425:13;76459:16;;;:7;:16;;;;;;76494:10;76486:40;;;;-1:-1:-1;;;76486:40:0;;7106:2:1;76486:40:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;76486:40:0;6904:341:1;76486:40:0;76359:175;;;:::o;68584:83::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68646:5:::1;:13:::0;;-1:-1:-1;;;;;;68646:13:0::1;-1:-1:-1::0;;;;;68646:13:0;;;::::1;::::0;;;::::1;::::0;;68584:83::o;79266:229::-;79350:7;79370:23;79387:5;79370:16;:23::i;:::-;79404:27;79423:7;79404:18;:27::i;:::-;79479:7;79451:24;53869:6;79451:5;:24;:::i;:::-;79450:36;;;;:::i;:::-;79442:45;79266:229;-1:-1:-1;;;79266:229:0:o;75746:300::-;75847:13;;75888:41;80256:10;75907:12;75921:7;75888:18;:41::i;:::-;75846:83;;;;75948:17;75940:52;;;;-1:-1:-1;;;75940:52:0;;9010:2:1;75940:52:0;;;8992:21:1;9049:2;9029:18;;;9022:30;9088:24;9068:18;;;9061:52;9130:18;;75940:52:0;8808:346:1;75940:52:0;76003:35;76013:5;76020:4;76026:2;76030:7;76003:9;:35::i;:::-;75835:211;;75746:300;;;:::o;76185:166::-;76250:7;76270:13;76286:19;76297:7;76286:10;:19::i;:::-;76270:35;;76323:20;76337:5;76323:13;:20::i;79503:221::-;79570:7;79579;79599:13;79615:18;79627:5;79615:11;:18::i;:::-;79599:34;;79644:15;79662:20;79676:5;79662:13;:20::i;:::-;79701:5;;79644:38;;-1:-1:-1;79503:221:0;;-1:-1:-1;;;79503:221:0:o;74817:489::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74887:15:::1;74905:13;74932:11;;74920:8;73977:156:::0;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;74920:8:::1;:24;;;;:::i;:::-;74919:30;::::0;74948:1:::1;74919:30;:::i;:::-;74905:45;;;;;;;:::i;:::-;;;74887:63;;74961:18;74990:281;75026:18;75036:7;75026:9;:18::i;:::-;75009:13;::::0;73977:156;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;74998:24:::1;;;;:::i;:::-;74997:47;74990:281;;;75073:13;75100:11;;75088:8;73977:156:::0;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;75088:8:::1;:24;;;;:::i;:::-;75087:30;::::0;75116:1:::1;75087:30;:::i;:::-;75073:45;;;;;;;:::i;:::-;;;75060:58;;75148:10;75137:7;:21;75133:127;;;75178:5;;75133:127;75234:10;75224:20;;74990:281;;;75281:17;75290:7;75281:8;:17::i;:::-;74876:430;;74817:489::o:0;68101:236::-;68181:7;68190;68210:21;68269:16;68247:18;;68235:9;:30;;;;:::i;:::-;68234:51;;;;:::i;:::-;68304:9;;-1:-1:-1;;;;;68304:9:0;;68210:75;;-1:-1:-1;68101:236:0;-1:-1:-1;;;;68101:236:0:o;69519:175::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69608:6:::1;69593:11;;:21;;:45;;;;;69628:10;;69618:6;:20;;69593:45;69585:71;;;::::0;-1:-1:-1;;;69585:71:0;;9981:2:1;69585:71:0::1;::::0;::::1;9963:21:1::0;10020:2;10000:18;;;9993:30;10059:15;10039:18;;;10032:43;10092:18;;69585:71:0::1;9779:337:1::0;69585:71:0::1;69667:10;:19:::0;69519:175::o;68485:91::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68551:7:::1;:17:::0;;-1:-1:-1;;;;;;68551:17:0::1;-1:-1:-1::0;;;;;68551:17:0;;;::::1;::::0;;;::::1;::::0;;68485:91::o;56247:190::-;56310:20;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;56343:46;;;;-1:-1:-1;;;56343:46:0;;7106:2:1;56343:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;56343:46:0;6904:341:1;56343:46:0;-1:-1:-1;56407:22:0;;;;:13;:22;;;;;;;56247:190::o;75314:151::-;75418:39;75435:4;75441:2;75445:7;75418:39;;;;;;;;;;;;:16;:39::i;82372:315::-;57005:6;;-1:-1:-1;;;57005:6:0;;;;57004:7;56996:35;;;;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0;;;10305:21:1;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0;10121:339:1;56996:35:0;82432:13:::1;::::0;82473:41:::1;80256:10:::0;82492:12:::1;80184:90:::0;82473:41:::1;82431:83;;;;82533:17;82525:52;;;::::0;-1:-1:-1;;;82525:52:0;;9010:2:1;82525:52:0::1;::::0;::::1;8992:21:1::0;9049:2;9029:18;;;9022:30;9088:24;9068:18;;;9061:52;9130:18;;82525:52:0::1;8808:346:1::0;82525:52:0::1;82590:35;82610:5;82617:7;82590:19;:35::i;:::-;82643:36;::::0;82671:7;;82667:1:::1;::::0;-1:-1:-1;;;;;82643:36:0;::::1;::::0;::::1;::::0;82667:1;;82643:36:::1;82420:267;;82372:315:::0;:::o;76542:204::-;-1:-1:-1;;;;;70533:27:0;;76603:7;70533:27;;;:17;:27;;;;;;;;76631:21;76623:51;;;;-1:-1:-1;;;76623:51:0;;10667:2:1;76623:51:0;;;10649:21:1;10706:2;10686:18;;;10679:30;10745:19;10725:18;;;10718:47;10782:18;;76623:51:0;10465:341:1;76623:51:0;-1:-1:-1;;;;;;76701:14:0;76685:13;76701:14;;;:7;:14;;;;;;;76542:204::o;79043:215::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;78141:4;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;79126:46:::1;;;::::0;-1:-1:-1;;;79126:46:0;;7106:2:1;79126:46:0::1;::::0;::::1;7088:21:1::0;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;79126:46:0::1;6904:341:1::0;79126:46:0::1;79202:48;79224:5;79231:18;79241:7;79231:9;:18::i;79202:48::-;79183:16;::::0;;;:7:::1;:16;::::0;;;;;:67;;;;-1:-1:-1;79043:215:0:o;77974:102::-;78028:4;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;:30;;78052:16;78045:23;77974:102;-1:-1:-1;;77974:102:0:o;69706:195::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69800:8:::1;69783:13;;:25;;:57;;;;-1:-1:-1::0;54193:20:0::1;54212:1;53869:6;54193:20;:::i;:::-;69812:8;:28;;69783:57;69775:85;;;::::0;-1:-1:-1;;;69775:85:0;;11143:2:1;69775:85:0::1;::::0;::::1;11125:21:1::0;11182:2;11162:18;;;11155:30;11221:17;11201:18;;;11194:45;11256:18;;69775:85:0::1;10941:339:1::0;69775:85:0::1;69871:11;:22:::0;69706:195::o;68931:207::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69040:12:::1;;69027:10;:25;69005:87;;;::::0;-1:-1:-1;;;69005:87:0;;11487:2:1;69005:87:0::1;::::0;::::1;11469:21:1::0;11526:2;11506:18;;;11499:30;-1:-1:-1;;;11545:18:1;;;11538:42;11597:18;;69005:87:0::1;11285:336:1::0;69005:87:0::1;69103:14;:27:::0;68931:207::o;67890:203::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68000:16:::1;67978:18;:38;;67970:65;;;::::0;-1:-1:-1;;;67970:65:0;;11828:2:1;67970:65:0::1;::::0;::::1;11810:21:1::0;11867:2;11847:18;;;11840:30;11906:16;11886:18;;;11879:44;11940:18;;67970:65:0::1;11626:338:1::0;67970:65:0::1;68046:18;:39:::0;67890:203::o;70705:183::-;70769:13;70803:16;;;:7;:16;;;;;;-1:-1:-1;;;;;70803:16:0;70839:19;70831:49;;;;-1:-1:-1;;;70831:49:0;;7106:2:1;70831:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;70831:49:0;6904:341:1;69353:158:0;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69442:6:::1;69427:11;;:21;;69419:54;;;::::0;-1:-1:-1;;;69419:54:0;;12171:2:1;69419:54:0::1;::::0;::::1;12153:21:1::0;12210:2;12190:18;;;12183:30;12249:22;12229:18;;;12222:50;12289:18;;69419:54:0::1;11969:344:1::0;69419:54:0::1;69484:10;:19:::0;69353:158::o;79956:220::-;80015:15;80053:24;53869:6;80053:5;:24;:::i;:::-;80043:34;;80141:27;80160:7;80141:18;:27::i;80282:463::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;80352:21:::1;80392:14:::0;80384:23:::1;;;::::0;::::1;;80433:4;::::0;80422:7:::1;::::0;-1:-1:-1;;;;;80422:7:0;;::::1;80433:4:::0;::::1;80422:15;80418:320;;;80463:4;::::0;80453:38:::1;::::0;-1:-1:-1;;;;;80463:4:0::1;80469:21;80453:9;:38::i;:::-;80320:425;80282:463::o:0;80418:320::-:1;80534:7;::::0;80524:34:::1;::::0;-1:-1:-1;;;;;80534:7:0::1;80543:14;80556:1;80543:10:::0;:14:::1;:::i;:::-;80524:9;:34::i;:::-;80590:5;::::0;80580:32:::1;::::0;-1:-1:-1;;;;;80590:5:0::1;80597:14;80610:1;80597:10:::0;:14:::1;:::i;80580:32::-;80691:4;::::0;80681:38:::1;::::0;-1:-1:-1;;;;;80691:4:0::1;80697:21;80681:9;:38::i;58722:695::-:0;80256:10;58828:19;56882:31;;;:17;:31;;;;;;;;56874:62;;;;-1:-1:-1;;;56874:62:0;;12520:2:1;56874:62:0;;;12502:21:1;12559:2;12539:18;;;12532:30;12598:20;12578:18;;;12571:48;12636:18;;56874:62:0;12318:342:1;56874:62:0;57005:6:::1;::::0;-1:-1:-1;;;57005:6:0;::::1;;;57004:7;56996:35;;;::::0;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0::1;::::0;::::1;10305:21:1::0;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0::1;10121:339:1::0;56996:35:0::1;58868:13:::2;58884:20;58892:11;58884:7;:20::i;:::-;58868:36;;58932:20;58940:11;58932:7;:20::i;:::-;-1:-1:-1::0;;;;;58923:29:0::2;:5;-1:-1:-1::0;;;;;58923:29:0::2;;58915:57;;;::::0;-1:-1:-1;;;58915:57:0;;12867:2:1;58915:57:0::2;::::0;::::2;12849:21:1::0;12906:2;12886:18;;;12879:30;12945:17;12925:18;;;12918:45;12980:18;;58915:57:0::2;12665:339:1::0;58915:57:0::2;80256:10:::0;-1:-1:-1;;;;;58991:21:0;::::2;;58983:50;;;::::0;-1:-1:-1;;;58983:50:0;;13211:2:1;58983:50:0::2;::::0;::::2;13193:21:1::0;13250:2;13230:18;;;13223:30;13289:18;13269;;;13262:46;13325:18;;58983:50:0::2;13009:340:1::0;58983:50:0::2;-1:-1:-1::0;;;;;59120:16:0;::::2;;::::0;;;:9:::2;:16;::::0;;;;:21;;59140:1:::2;::::0;59120:16;:21:::2;::::0;59140:1;;59120:21:::2;:::i;:::-;::::0;;;-1:-1:-1;59168:34:0::2;::::0;-1:-1:-1;59177:11:0;59190;59168:8:::2;:34::i;:::-;59264:20;::::0;;;:7:::2;:20;::::0;;;;;59257:27;;-1:-1:-1;;;;;;59257:27:0::2;::::0;;59369:40;59154:48;;-1:-1:-1;59154:48:0;;-1:-1:-1;;;;;59369:40:0;::::2;::::0;::::2;::::0;59264:20;;59369:40:::2;58849:568;58722:695:::0;;;;:::o;69909:106::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69986:9:::1;:21:::0;;-1:-1:-1;;;;;;69986:21:0::1;-1:-1:-1::0;;;;;69986:21:0;;;::::1;::::0;;;::::1;::::0;;69909:106::o;74705:104::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74784:17:::1;74793:7;74784:8;:17::i;70027:153::-:0;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;70115:18:::1;:57:::0;;-1:-1:-1;;;;;;70115:57:0::1;-1:-1:-1::0;;;;;70115:57:0;;;::::1;::::0;;;::::1;::::0;;70027:153::o;58510:104::-;58566:13;58599:7;58592:14;;;;;:::i;71045:2794::-;71152:14;;71133:15;:33;;:67;;;;;71188:12;;71170:15;:30;71133:67;71111:130;;;;-1:-1:-1;;;71111:130:0;;13556:2:1;71111:130:0;;;13538:21:1;13595:2;13575:18;;;13568:30;13634:15;13614:18;;;13607:43;13667:18;;71111:130:0;13354:337:1;71111:130:0;71274:10;;71260:11;;:24;71252:55;;;;-1:-1:-1;;;71252:55:0;;13898:2:1;71252:55:0;;;13880:21:1;13937:2;13917:18;;;13910:30;13976:20;13956:18;;;13949:48;14014:18;;71252:55:0;13696:342:1;71252:55:0;71469:9;71482:10;71469:23;71447:99;;;;-1:-1:-1;;;71447:99:0;;14245:2:1;71447:99:0;;;14227:21:1;14284:2;14264:18;;;14257:30;14323:28;14303:18;;;14296:56;14369:18;;71447:99:0;14043:350:1;71447:99:0;71585:10;71559:13;71575:21;;;:9;:21;;;;;;71712:11;;71752:8;;71794:13;;71885:4;;71575:26;;;;71712:11;;71752:8;;71794:13;;71840:14;;-1:-1:-1;;;;;71885:4:0;;;71871:18;71867:216;;;-1:-1:-1;71917:1:0;71867:216;;;72021:10;;72012:5;:19;;:32;;;;;72036:8;72035:9;72012:32;72008:75;;;72060:11;;;;:::i;:::-;;;;72008:75;72142:10;;72130:22;;:9;:22;:::i;:::-;72117:9;:35;;72095:101;;;;-1:-1:-1;;;72095:101:0;;14741:2:1;72095:101:0;;;14723:21:1;14780:2;14760:18;;;14753:30;14819:18;14799;;;14792:46;14855:18;;72095:101:0;14539:340:1;72095:101:0;72317:13;;72290:24;72367:33;72386:14;72317:13;72367:33;:::i;:::-;72341:59;;72452:11;;72433:15;:30;;72411:105;;;;-1:-1:-1;;;72411:105:0;;15086:2:1;72411:105:0;;;15068:21:1;15125:2;15105:18;;;15098:30;15164:27;15144:18;;;15137:55;15209:18;;72411:105:0;14884:349:1;72411:105:0;72527:13;:31;;;72651:192;;;;72702:10;70509:4;70533:27;;;:17;:27;;;;;;;;72687:26;72679:63;;;;-1:-1:-1;;;72679:63:0;;15440:2:1;72679:63:0;;;15422:21:1;15479:2;15459:18;;;15452:30;15518:26;15498:18;;;15491:54;15562:18;;72679:63:0;15238:348:1;72679:63:0;72757:53;72774:19;72782:10;72774:7;:19::i;:::-;72795:14;72757:16;:53::i;:::-;72825:7;;;;;;;71045:2794;:::o;72651:192::-;72901:13;72936:1;72929:3;72918:8;73977:156;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;72918:8;:14;;;;:::i;:::-;72917:20;:28;;72944:1;72917:28;;;72940:1;72917:28;72901:44;;;;72975;72997:5;73004:14;72975:21;:44::i;:::-;72958:14;;;;:7;:14;;;;;;;;:61;;;;73039:7;:14;;;;;:27;;-1:-1:-1;;;;;;73039:27:0;73056:10;73039:27;;;73113:11;:13;;;;;;:::i;:::-;;;;;;73158:14;73143:12;:29;73139:120;;;73203:14;73188:29;;73242:5;73232:15;;73139:120;73294:5;73271:13;73285:5;73271:20;;;;;;;:::i;:::-;;:28;73310:22;;;;:15;:22;;;;;:30;;;73353:52;;73310:22;73387:10;73335:5;73353:9;:52::i;:::-;73475:7;;;;:::i;:::-;;;;73556:5;73542:11;:19;;;;73666:7;73654:8;;:19;73651:173;;73690:8;:18;;;73723:13;:28;;;73771:41;;784:25:1;;;73690:18:0;;73771:41;;772:2:1;757:18;73771:41:0;;;;;;;73651:173;71100:2739;;;;;;;;71045:2794;:::o;77509:285::-;-1:-1:-1;;;;;77612:24:0;;80256:10;77612:24;;77604:54;;;;-1:-1:-1;;;77604:54:0;;15933:2:1;77604:54:0;;;15915:21:1;15972:2;15952:18;;;15945:30;16011:19;15991:18;;;15984:47;16048:18;;77604:54:0;15731:341:1;77604:54:0;80256:10;77669:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;77669:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;77669:53:0;;;;;;;;;;77738:48;;586:41:1;;;77669:42:0;;80256:10;77738:48;;559:18:1;77738:48:0;;;;;;;77509:285;;:::o;68345:132::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;-1:-1:-1;;;;;68433:27:0;;;::::1;;::::0;;;:17:::1;:27;::::0;;;;:36;;-1:-1:-1;;68433:36:0::1;::::0;::::1;;::::0;;;::::1;::::0;;68345:132::o;74202:80::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74259:6:::1;:15:::0;;;::::1;;-1:-1:-1::0;;;74259:15:0::1;::::0;;;::::1;::::0;;;::::1;::::0;;74202:80::o;75473:265::-;75597:31;75610:4;75616:2;75620:7;75597:12;:31::i;:::-;75647:48;75670:4;75676:2;75680:7;75689:5;75647:22;:48::i;:::-;75639:91;;;;-1:-1:-1;;;75639:91:0;;16279:2:1;75639:91:0;;;16261:21:1;16318:2;16298:18;;;16291:30;16357:32;16337:18;;;16330:60;16407:18;;75639:91:0;16077:354:1;75639:91:0;75473:265;;;;:::o;68675:139::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68765:4:::1;68741:21;:28;68733:51;;;::::0;-1:-1:-1;;;68733:51:0;;16638:2:1;68733:51:0::1;::::0;::::1;16620:21:1::0;16677:2;16657:18;;;16650:30;16716:12;16696:18;;;16689:40;16746:18;;68733:51:0::1;16436:334:1::0;68733:51:0::1;68795:4;:11:::0;;-1:-1:-1;;;;;;68795:11:0::1;-1:-1:-1::0;;;;;68795:11:0;;;::::1;::::0;;;::::1;::::0;;68675:139::o;78585:450::-;78141:4;78165:16;;;:7;:16;;;;;;78658:13;;-1:-1:-1;;;;;78165:16:0;78684:46;;;;-1:-1:-1;;;78684:46:0;;7106:2:1;78684:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;78684:46:0;6904:341:1;78684:46:0;78758:18;;;78840:16;;;:7;:16;;;;;;;-1:-1:-1;;;;;78758:18:0;;;;:32;;78805:7;;78828:29;;:11;:29::i;:::-;78887:16;;;;:7;:16;;;;;;78873:31;;:13;:31::i;:::-;78942:8;;78934:17;;;;:7;:17;;;;;;78920:32;;:13;:32::i;:::-;78979:8;;78968:7;:19;79002:24;79018:7;79002:15;:24::i;:::-;78758:269;;-1:-1:-1;;;;;;78758:269:0;;;;;;;;;;17056:25:1;;;;17097:18;;;17090:34;;;;17140:18;;;17133:34;;;;17183:18;;;17176:34;17254:14;17247:22;17226:19;;;17219:51;17286:19;;;17279:35;17028:19;;78758:269:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;78758:269:0;;;;;;;;;;;;:::i;56445:128::-;56510:15;56545:13;56559:5;56545:20;;;;;;;:::i;:::-;;;;56445:128;-1:-1:-1;;56445:128:0:o;69146:199::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69255:8:::1;69238:14;;:25;69216:87;;;::::0;-1:-1:-1;;;69216:87:0;;11487:2:1;69216:87:0::1;::::0;::::1;11469:21:1::0;11526:2;11506:18;;;11499:30;-1:-1:-1;;;11545:18:1;;;11538:42;11597:18;;69216:87:0::1;11285:336:1::0;69216:87:0::1;69314:12;:23:::0;69146:199::o;70191:248::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;70280:15;70277:106:::1;;70343:1;70320:19;70330:8;-1:-1:-1::0;;;;;76145:16:0;76118:7;76145:16;;;:9;:16;;;;;;;76054:123;70320:19:::1;:24;;70312:59;;;::::0;-1:-1:-1;;;70312:59:0;;18167:2:1;70312:59:0::1;::::0;::::1;18149:21:1::0;18206:2;18186:18;;;18179:30;18245:24;18225:18;;;18218:52;18287:18;;70312:59:0::1;17965:346:1::0;70312:59:0::1;-1:-1:-1::0;;;;;70395:27:0;;;::::1;;::::0;;;:17:::1;:27;::::0;;;;:36;;-1:-1:-1;;70395:36:0::1;::::0;::::1;;::::0;;;::::1;::::0;;70191:248::o;68822:101::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68892:10:::1;:23:::0;68822:101::o;79732:212::-;79789:13;79823:24;53869:6;79823:5;:24;:::i;:::-;79815:32;;79913:23;79930:5;79913:16;:23::i;77123:171::-;77213:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;77213:29:0;-1:-1:-1;;;;;77213:29:0;;;;;;;;;77258:28;;77213:24;;77258:28;;;;;;;77123:171;;;:::o;57059:156::-;57150:5;53980:1;57132:23;;:50;;;;;54031:1;57159:5;:23;;57132:50;57124:83;;;;-1:-1:-1;;;57124:83:0;;18518:2:1;57124:83:0;;;18500:21:1;18557:2;18537:18;;;18530:30;18596:22;18576:18;;;18569:50;18636:18;;57124:83:0;18316:344:1;57223:174:0;57320:7;54140:1;57300:27;;:57;;;;-1:-1:-1;54193:20:0;54212:1;53869:6;54193:20;:::i;:::-;57331:7;:26;57300:57;57292:97;;;;-1:-1:-1;;;57292:97:0;;18867:2:1;57292:97:0;;;18849:21:1;18906:2;18886:18;;;18879:30;18945:29;18925:18;;;18918:57;18992:18;;57292:97:0;18665:351:1;78211:363:0;78304:13;78362:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78362:16:0;;78399:19;78391:49;;;;-1:-1:-1;;;78391:49:0;;7106:2:1;78391:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;78391:49:0;6904:341:1;78391:49:0;78485:5;-1:-1:-1;;;;;78474:16:0;:7;-1:-1:-1;;;;;78474:16:0;;:55;;;-1:-1:-1;78494:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;78494:35:0;;;:24;;:35;78474:55;:91;;;-1:-1:-1;;;;;;77923:25:0;;;77899:4;77923:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;78533:32;78453:113;;78211:363;;;;;:::o;59425:6443::-;57005:6;;-1:-1:-1;;;57005:6:0;;;;57004:7;56996:35;;;;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0;;;10305:21:1;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0;10121:339:1;56996:35:0;59549:4:::1;-1:-1:-1::0;;;;;59540:13:0::1;:5;-1:-1:-1::0;;;;;59540:13:0::1;;59532:39;;;::::0;-1:-1:-1;;;59532:39:0;;19223:2:1;59532:39:0::1;::::0;::::1;19205:21:1::0;19262:2;19242:18;;;19235:30;19301:15;19281:18;;;19274:43;19334:18;;59532:39:0::1;19021:337:1::0;59532:39:0::1;-1:-1:-1::0;;;;;59590:16:0;::::1;59582:57;;;::::0;-1:-1:-1;;;59582:57:0;;19565:2:1;59582:57:0::1;::::0;::::1;19547:21:1::0;19604:2;19584:18;;;19577:30;19643;19623:18;;;19616:58;19691:18;;59582:57:0::1;19363:352:1::0;59582:57:0::1;-1:-1:-1::0;;;;;59659:21:0;::::1;;::::0;;;:17:::1;:21;::::0;;;;;::::1;;59658:22;59650:63;;;::::0;-1:-1:-1;;;59650:63:0;;19922:2:1;59650:63:0::1;::::0;::::1;19904:21:1::0;19961:2;19941:18;;;19934:30;20000;19980:18;;;19973:58;20048:18;;59650:63:0::1;19720:352:1::0;59650:63:0::1;-1:-1:-1::0;;;;;59812:11:0;::::1;54897:42;59812:11;59808:6053;;;59840:35;59860:5;59867:7;59840:19;:35::i;:::-;59897:30;::::0;59919:7;;54897:42:::1;::::0;-1:-1:-1;;;;;59897:30:0;::::1;::::0;::::1;::::0;;;::::1;59947:36;::::0;59975:7;;59971:1:::1;::::0;54897:42:::1;::::0;59947:36:::1;::::0;59971:1;;59947:36:::1;59808:6053;;;60111:36;60120:5;60135:1;60139:7;60111:8;:36::i;:::-;60334:7;60330:2;-1:-1:-1::0;;;;;60315:27:0::1;60324:4;-1:-1:-1::0;;;;;60315:27:0::1;;;;;;;;;;;60371:2;-1:-1:-1::0;;;;;60363:10:0::1;:4;-1:-1:-1::0;;;;;60363:10:0::1;;60359:254;;;60591:7;;60359:254;-1:-1:-1::0;;;;;70533:27:0;;;61346:22:::1;70533:27:::0;;;:17;:27;;;;;;;;;;;;;;;;;;;;;61671:609;::::1;;;-1:-1:-1::0;;;;;61856:15:0;::::1;;::::0;;;:9:::1;:15;::::0;;;;:20;;61875:1:::1;::::0;61856:15;:20:::1;::::0;61875:1;;61856:20:::1;:::i;:::-;::::0;;;-1:-1:-1;61671:609:0::1;::::0;-1:-1:-1;61671:609:0::1;;-1:-1:-1::0;;;;;62249:15:0;::::1;;::::0;;;:9:::1;:15;::::0;;;;62242:22;61671:609:::1;62440:15;62436:845;;;-1:-1:-1::0;;;;;62619:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;:18;;62636:1:::1;::::0;62619:13;:18:::1;::::0;62636:1;;62619:18:::1;:::i;:::-;::::0;;;-1:-1:-1;62436:845:0::1;::::0;-1:-1:-1;62436:845:0::1;;-1:-1:-1::0;;;;;62663:11:0;::::1;;::::0;;;:7:::1;:11;::::0;;;;;62659:622:::1;;-1:-1:-1::0;;;;;62949:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;62965:1:::1;62949:17:::0;;62659:622:::1;63328:15;63324:2272;;;63719:16;::::0;;;:7:::1;:16;::::0;;;;:21;;-1:-1:-1;;;;;;63719:21:0::1;-1:-1:-1::0;;;;;63719:21:0;::::1;;::::0;;63324:2272:::1;;;-1:-1:-1::0;;;;;63884:11:0;::::1;63859:22;63884:11:::0;;;:7:::1;:11;::::0;;;;;63920:19;63916:1665:::1;;64061:16;::::0;;;:7:::1;:16;::::0;;;;;;;:21;;-1:-1:-1;;;;;;64061:21:0::1;-1:-1:-1::0;;;;;64061:21:0;::::1;::::0;;::::1;::::0;;;64191:11;;:7:::1;:11:::0;;;;;:21;;;63916:1665:::1;;;64283:7:::0;64261:19:::1;64409:37;64418:14:::0;64283:7;64409:8:::1;:37::i;:::-;64653;::::0;64387:59;;-1:-1:-1;64387:59:0;;64674:1:::1;::::0;-1:-1:-1;;;;;64653:37:0;::::1;::::0;::::1;::::0;64674:1;;64653:37:::1;64793:14:::0;64834:29;;::::1;64830:112;;;-1:-1:-1::0;64907:11:0;64830:112:::1;65078:20;::::0;;;:7:::1;:20;::::0;;;;65071:27;;-1:-1:-1;;;;;;65071:27:0::1;::::0;;65198:30;;::::1;65194:368;;65365:21;::::0;;;:7:::1;:21;::::0;;;;;;;:26;;-1:-1:-1;;;;;;65365:26:0::1;-1:-1:-1::0;;;;;65365:26:0;::::1;::::0;;::::1;::::0;;;65512:11;;:7:::1;:11:::0;;;;;:26;;;65194:368:::1;64238:1343;;;63916:1665;63762:1834;63324:2272;65776:17;65771:79;;-1:-1:-1::0;;;;;65821:13:0;::::1;;::::0;;;:7:::1;:13;::::0;;;;65814:20;65771:79:::1;60001:5860;;59425:6443:::0;;;;:::o;74290:407::-;74344:13;74360:16;;;:7;:16;;;;;;-1:-1:-1;;;;;74360:16:0;74395:19;74387:49;;;;-1:-1:-1;;;74387:49:0;;7106:2:1;74387:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;74387:49:0;6904:341:1;74387:49:0;74447:35;74467:5;74474:7;74447:19;:35::i;:::-;74497:9;:13;74493:145;;74527:12;74544:5;-1:-1:-1;;;;;74544:10:0;74562:9;74544:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74526:50;;;74599:7;74591:35;;;;-1:-1:-1;;;74591:35:0;;20980:2:1;74591:35:0;;;20962:21:1;21019:2;20999:18;;;20992:30;21058:17;21038:18;;;21031:45;21093:18;;74591:35:0;20778:339:1;74591:35:0;74511:127;74493:145;74653:36;;74681:7;;74677:1;;-1:-1:-1;;;;;74653:36:0;;;;;74677:1;;74653:36;74333:364;74290:407;:::o;82695:635::-;82776:36;82785:5;82800:1;82804:7;82776:8;:36::i;:::-;82856:16;;;;:7;:16;;;;;;82842:31;;:13;:31::i;:::-;82825:13;;:48;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;82893:14:0;;;;;;:7;:14;;;;;;;;82886:21;;;82925:16;;;:7;:16;;;;;82918:23;;-1:-1:-1;;;;;;82918:23:0;;;82959:7;:16;;;;;82952:23;;;83013:15;:24;;;;;;83084:11;;83013:24;;82893:14;83070:13;;:26;;;;;;;:::i;:::-;;;83048:48;;83139:11;83107:13;83121:14;83107:29;;;;;;;:::i;:::-;;:43;83161:28;;;;:15;:28;;;;;:45;;;83217:11;:13;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;83247:16:0;;;;;;:9;:16;;;;;:21;;83267:1;;83247:16;:21;;83267:1;;83247:21;:::i;:::-;;;;-1:-1:-1;;83294:28:0;;83317:1;784:25:1;;;83317:1:0;83308:7;;83294:28;;772:2:1;757:18;83294:28:0;;;;;;;;82765:565;;82695:635;;:::o;80753:166::-;80821:12;80838:5;-1:-1:-1;;;;;80838:10:0;80856:4;80838:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80820:45;;;80884:7;80876:35;;;;-1:-1:-1;;;80876:35:0;;20980:2:1;80876:35:0;;;20962:21:1;21019:2;20999:18;;;20992:30;21058:17;21038:18;;;21031:45;21093:18;;80876:35:0;20778:339:1;66370:1512:0;66448:19;66503:11;66488;:26;;66480:56;;;;-1:-1:-1;;;66480:56:0;;21514:2:1;66480:56:0;;;21496:21:1;21553:2;21533:18;;;21526:30;21592:19;21572:18;;;21565:47;21629:18;;66480:56:0;21312:341:1;66480:56:0;66549:19;66585:20;;;:7;:20;;;;;;66571:35;;:13;:35::i;:::-;66617:19;66653:20;;;:7;:20;;;;;;66549:57;;-1:-1:-1;66617:19:0;66639:35;;:13;:35::i;:::-;66617:57;-1:-1:-1;66718:11:0;66617:57;66810:11;66855;66883:26;;;66879:212;;-1:-1:-1;66943:11:0;;-1:-1:-1;66984:11:0;;-1:-1:-1;67027:11:0;;-1:-1:-1;67068:11:0;66879:212;67103:21;;;;:7;:21;;;;;:37;;67128:12;;67103:21;:37;;67128:12;;67103:37;:::i;:::-;;;;-1:-1:-1;67153:23:0;;-1:-1:-1;67179:27:0;67194:12;67179;:27;:::i;:::-;67153:53;;67240:13;;67222:15;:31;67219:197;;;67270:8;:23;;;67308:13;:31;;;67359:45;;784:25:1;;;67270:23:0;;67359:45;;772:2:1;757:18;67359:45:0;;;;;;;67219:197;67436:27;;;;:13;:27;;;;;:29;;;;;;:::i;:::-;;;;-1:-1:-1;;67485:21:0;;;;:7;:21;;;;;;;;67478:28;;;67544:15;:29;;;;;;67620:11;;67544:29;;67485:21;67606:13;;:26;;;;;;;:::i;:::-;;;67584:48;;67675:11;67643:13;67657:14;67643:29;;;;;;;:::i;:::-;;:43;67697:28;;;;:15;:28;;;;;:45;;;67753:11;:13;;;;;;:::i;:::-;;;;;;67812:12;67798;67784:58;67826:15;67784:58;;;;784:25:1;;772:2;757:18;;638:177;67784:58:0;;;;;;;;-1:-1:-1;67862:12:0;;66370:1512;-1:-1:-1;;;;;;;;;;66370:1512:0:o;65876:486::-;65956:22;65995:16;;;:7;:16;;;;;;65981:31;;:13;:31::i;:::-;65956:56;;66043:8;66023:7;:16;66031:7;66023:16;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;66064:18:0;;-1:-1:-1;66085:25:0;66102:8;66085:14;:25;:::i;:::-;66064:46;;66139:13;;66126:10;:26;66123:177;;;66169:8;:18;;;66202:13;:26;;;66248:40;;784:25:1;;;66169:18:0;;66248:40;;772:2:1;757:18;66248:40:0;;;;;;;66123:177;66334:7;66331:1;66317:37;66343:10;66317:37;;;;784:25:1;;772:2;757:18;;638:177;80932:744:0;81044:4;81864:20;;81903:8;81061:586;;81100:72;;-1:-1:-1;;;81100:72:0;;-1:-1:-1;;;;;81100:36:0;;;;;:72;;80256:10;;81151:4;;81157:7;;81166:5;;81100:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81100:72:0;;;;;;;;-1:-1:-1;;81100:72:0;;;;;;;;;;;;:::i;:::-;;;81096:540;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81346:13:0;;81342:107;;81389:40;;-1:-1:-1;;;81389:40:0;;16279:2:1;81389:40:0;;;16261:21:1;16318:2;16298:18;;;16291:30;16357:32;16337:18;;;16330:60;16407:18;;81389:40:0;16077:354:1;81342:107:0;81594:6;81588:13;81579:6;81575:2;81571:15;81564:38;81096:540;-1:-1:-1;;;;;;81223:55:0;-1:-1:-1;;;81223:55:0;;-1:-1:-1;81216:62:0;;81096:540;-1:-1:-1;81664:4:0;80932:744;;;;;;;:::o;14:177:1:-;-1:-1:-1;;;;;;92:5:1;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;1051:258::-;1123:1;1133:113;1147:6;1144:1;1141:13;1133:113;;;1223:11;;;1217:18;1204:11;;;1197:39;1169:2;1162:10;1133:113;;;1264:6;1261:1;1258:13;1255:48;;;-1:-1:-1;;1299:1:1;1281:16;;1274:27;1051:258::o;1314:::-;1356:3;1394:5;1388:12;1421:6;1416:3;1409:19;1437:63;1493:6;1486:4;1481:3;1477:14;1470:4;1463:5;1459:16;1437:63;:::i;:::-;1554:2;1533:15;-1:-1:-1;;1529:29:1;1520:39;;;;1561:4;1516:50;;1314:258;-1:-1:-1;;1314:258:1:o;1577:220::-;1726:2;1715:9;1708:21;1689:4;1746:45;1787:2;1776:9;1772:18;1764:6;1746:45;:::i;1802:180::-;1861:6;1914:2;1902:9;1893:7;1889:23;1885:32;1882:52;;;1930:1;1927;1920:12;1882:52;-1:-1:-1;1953:23:1;;1802:180;-1:-1:-1;1802:180:1:o;1987:196::-;2055:20;;-1:-1:-1;;;;;2104:54:1;;2094:65;;2084:93;;2173:1;2170;2163:12;2188:254;2256:6;2264;2317:2;2305:9;2296:7;2292:23;2288:32;2285:52;;;2333:1;2330;2323:12;2285:52;2356:29;2375:9;2356:29;:::i;:::-;2346:39;2432:2;2417:18;;;;2404:32;;-1:-1:-1;;;2188:254:1:o;2447:186::-;2506:6;2559:2;2547:9;2538:7;2534:23;2530:32;2527:52;;;2575:1;2572;2565:12;2527:52;2598:29;2617:9;2598:29;:::i;2638:248::-;2706:6;2714;2767:2;2755:9;2746:7;2742:23;2738:32;2735:52;;;2783:1;2780;2773:12;2735:52;-1:-1:-1;;2806:23:1;;;2876:2;2861:18;;;2848:32;;-1:-1:-1;2638:248:1:o;2891:328::-;2968:6;2976;2984;3037:2;3025:9;3016:7;3012:23;3008:32;3005:52;;;3053:1;3050;3043:12;3005:52;3076:29;3095:9;3076:29;:::i;:::-;3066:39;;3124:38;3158:2;3147:9;3143:18;3124:38;:::i;:::-;3114:48;;3209:2;3198:9;3194:18;3181:32;3171:42;;2891:328;;;;;:::o;4035:160::-;4100:20;;4156:13;;4149:21;4139:32;;4129:60;;4185:1;4182;4175:12;4200:254;4265:6;4273;4326:2;4314:9;4305:7;4301:23;4297:32;4294:52;;;4342:1;4339;4332:12;4294:52;4365:29;4384:9;4365:29;:::i;:::-;4355:39;;4413:35;4444:2;4433:9;4429:18;4413:35;:::i;4459:180::-;4515:6;4568:2;4556:9;4547:7;4543:23;4539:32;4536:52;;;4584:1;4581;4574:12;4536:52;4607:26;4623:9;4607:26;:::i;4644:184::-;-1:-1:-1;;;4693:1:1;4686:88;4793:4;4790:1;4783:15;4817:4;4814:1;4807:15;4833:275;4904:2;4898:9;4969:2;4950:13;;-1:-1:-1;;4946:27:1;4934:40;;5004:18;4989:34;;5025:22;;;4986:62;4983:88;;;5051:18;;:::i;:::-;5087:2;5080:22;4833:275;;-1:-1:-1;4833:275:1:o;5113:186::-;5161:4;5194:18;5186:6;5183:30;5180:56;;;5216:18;;:::i;:::-;-1:-1:-1;5282:2:1;5261:15;-1:-1:-1;;5257:29:1;5288:4;5253:40;;5113:186::o;5304:888::-;5399:6;5407;5415;5423;5476:3;5464:9;5455:7;5451:23;5447:33;5444:53;;;5493:1;5490;5483:12;5444:53;5516:29;5535:9;5516:29;:::i;:::-;5506:39;;5564:38;5598:2;5587:9;5583:18;5564:38;:::i;:::-;5554:48;;5649:2;5638:9;5634:18;5621:32;5611:42;;5704:2;5693:9;5689:18;5676:32;5731:18;5723:6;5720:30;5717:50;;;5763:1;5760;5753:12;5717:50;5786:22;;5839:4;5831:13;;5827:27;-1:-1:-1;5817:55:1;;5868:1;5865;5858:12;5817:55;5904:2;5891:16;5929:48;5945:31;5973:2;5945:31;:::i;:::-;5929:48;:::i;:::-;6000:2;5993:5;5986:17;6040:7;6035:2;6030;6026;6022:11;6018:20;6015:33;6012:53;;;6061:1;6058;6051:12;6012:53;6116:2;6111;6107;6103:11;6098:2;6091:5;6087:14;6074:45;6160:1;6155:2;6150;6143:5;6139:14;6135:23;6128:34;6181:5;6171:15;;;;;5304:888;;;;;;;:::o;6197:260::-;6265:6;6273;6326:2;6314:9;6305:7;6301:23;6297:32;6294:52;;;6342:1;6339;6332:12;6294:52;6365:29;6384:9;6365:29;:::i;:::-;6355:39;;6413:38;6447:2;6436:9;6432:18;6413:38;:::i;6462:437::-;6541:1;6537:12;;;;6584;;;6605:61;;6659:4;6651:6;6647:17;6637:27;;6605:61;6712:2;6704:6;6701:14;6681:18;6678:38;6675:218;;;-1:-1:-1;;;6746:1:1;6739:88;6850:4;6847:1;6840:15;6878:4;6875:1;6868:15;6675:218;;6462:437;;;:::o;8313:184::-;-1:-1:-1;;;8362:1:1;8355:88;8462:4;8459:1;8452:15;8486:4;8483:1;8476:15;8502:168;8542:7;8608:1;8604;8600:6;8596:14;8593:1;8590:21;8585:1;8578:9;8571:17;8567:45;8564:71;;;8615:18;;:::i;:::-;-1:-1:-1;8655:9:1;;8502:168::o;8675:128::-;8715:3;8746:1;8742:6;8739:1;8736:13;8733:39;;;8752:18;;:::i;:::-;-1:-1:-1;8788:9:1;;8675:128::o;9159:184::-;-1:-1:-1;;;9208:1:1;9201:88;9308:4;9305:1;9298:15;9332:4;9329:1;9322:15;9348:112;9380:1;9406;9396:35;;9411:18;;:::i;:::-;-1:-1:-1;9445:9:1;;9348:112::o;9465:184::-;-1:-1:-1;;;9514:1:1;9507:88;9614:4;9611:1;9604:15;9638:4;9635:1;9628:15;9654:120;9694:1;9720;9710:35;;9725:18;;:::i;:::-;-1:-1:-1;9759:9:1;;9654:120::o;10811:125::-;10851:4;10879:1;10876;10873:8;10870:34;;;10884:18;;:::i;:::-;-1:-1:-1;10921:9:1;;10811:125::o;14398:136::-;14437:3;14465:5;14455:39;;14474:18;;:::i;:::-;-1:-1:-1;;;14510:18:1;;14398:136::o;15591:135::-;15630:3;-1:-1:-1;;15651:17:1;;15648:43;;;15671:18;;:::i;:::-;-1:-1:-1;15718:1:1;15707:13;;15591:135::o;17325:635::-;17405:6;17458:2;17446:9;17437:7;17433:23;17429:32;17426:52;;;17474:1;17471;17464:12;17426:52;17507:9;17501:16;17540:18;17532:6;17529:30;17526:50;;;17572:1;17569;17562:12;17526:50;17595:22;;17648:4;17640:13;;17636:27;-1:-1:-1;17626:55:1;;17677:1;17674;17667:12;17626:55;17706:2;17700:9;17731:48;17747:31;17775:2;17747:31;:::i;17731:48::-;17802:2;17795:5;17788:17;17842:7;17837:2;17832;17828;17824:11;17820:20;17817:33;17814:53;;;17863:1;17860;17853:12;17814:53;17876:54;17927:2;17922;17915:5;17911:14;17906:2;17902;17898:11;17876:54;:::i;:::-;17949:5;17325:635;-1:-1:-1;;;;;17325:635:1:o;21658:512::-;21852:4;-1:-1:-1;;;;;21962:2:1;21954:6;21950:15;21939:9;21932:34;22014:2;22006:6;22002:15;21997:2;21986:9;21982:18;21975:43;;22054:6;22049:2;22038:9;22034:18;22027:34;22097:3;22092:2;22081:9;22077:18;22070:31;22118:46;22159:3;22148:9;22144:19;22136:6;22118:46;:::i;22175:249::-;22244:6;22297:2;22285:9;22276:7;22272:23;22268:32;22265:52;;;22313:1;22310;22303:12;22265:52;22345:9;22339:16;22364:30;22388:5;22364:30;:::i

Swarm Source

ipfs://1e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f628

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.