ETH Price: $2,525.13 (-1.80%)

Token

Collages (CLG)
 

Overview

Max Total Supply

416 CLG

Holders

159

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
jacksun.eth
Balance
1 CLG
0x8fac841807e21807f511daf3c04a34cd78661f4c
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
MixedStems_V1_1

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-05-29
*/

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

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

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

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

        bytes memory table = TABLE;

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

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

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

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

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

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

            mstore(result, encodedLen)
        }

        return string(result);
    }

    function decode(bytes memory data) internal pure returns (bytes memory) {
        uint8[128] memory toInt;

        for (uint8 i = 0; i < bytes(TABLE).length; i++) {
            toInt[uint8(bytes(TABLE)[i])] = i;
        }

        uint256 delta;
        uint256 len = data.length;
        if (data[len - 2] == "=" && data[len - 1] == "=") {
            delta = 2;
        } else if (data[len - 1] == "=") {
            delta = 1;
        } else {
            delta = 0;
        }
        uint256 decodedLen = (len * 3) / 4 - delta;
        bytes memory buffer = new bytes(decodedLen);
        uint256 index;
        uint8 mask = 0xFF;

        for (uint256 i = 0; i < len; i += 4) {
            uint8 c0 = toInt[uint8(data[i])];
            uint8 c1 = toInt[uint8(data[i + 1])];
            buffer[index++] = (bytes1)(((c0 << 2) | (c1 >> 4)) & mask);
            if (index >= buffer.length) {
                return buffer;
            }
            uint8 c2 = toInt[uint8(data[i + 2])];
            buffer[index++] = (bytes1)(((c1 << 4) | (c2 >> 2)) & mask);
            if (index >= buffer.length) {
                return buffer;
            }
            uint8 c3 = toInt[uint8(data[i + 3])];
            buffer[index++] = (bytes1)(((c2 << 6) | c3) & mask);
        }
        return buffer;
    }
}


interface DateTimeAPI {
    /*
     *  Abstract contract for interfacing with the DateTime contract.
     *
     */
    function isLeapYear(uint16 year) external returns (bool);

    function getYear(uint256 timestamp) external returns (uint16);

    function getMonth(uint256 timestamp) external returns (uint8);

    function getDay(uint256 timestamp) external returns (uint8);

    function getHour(uint256 timestamp) external returns (uint8);

    function getMinute(uint256 timestamp) external returns (uint8);

    function getSecond(uint256 timestamp) external returns (uint8);

    function getWeekday(uint256 timestamp) external returns (uint8);

    function toTimestamp(
        uint16 year,
        uint8 month,
        uint8 day
    ) external returns (uint256 timestamp);

    function toTimestamp(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour
    ) external returns (uint256 timestamp);

    function toTimestamp(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour,
        uint8 minute
    ) external returns (uint256 timestamp);

    function toTimestamp(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour,
        uint8 minute,
        uint8 second
    ) external returns (uint256 timestamp);
}


/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;


library BytesLib {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
        internal
        pure
        returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
        internal
        view
        returns (bool)
    {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}


library Bytecode {
  error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);

  /**
    @notice Generate a creation code that results on a contract with `_code` as bytecode
    @param _code The returning value of the resulting `creationCode`
    @return creationCode (constructor) for new contract
  */
  function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) {
    /*
      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size
      0x01    0x80         0x80        DUP1                size size
      0x02    0x60         0x600e      PUSH1 14            14 size size
      0x03    0x60         0x6000      PUSH1 00            0 14 size size
      0x04    0x39         0x39        CODECOPY            size
      0x05    0x60         0x6000      PUSH1 00            0 size
      0x06    0xf3         0xf3        RETURN
      <CODE>
    */

    return abi.encodePacked(
      hex"63",
      uint32(_code.length),
      hex"80_60_0E_60_00_39_60_00_F3",
      _code
    );
  }

  /**
    @notice Returns the size of the code on a given address
    @param _addr Address that may or may not contain code
    @return size of the code on the given `_addr`
  */
  function codeSize(address _addr) internal view returns (uint256 size) {
    assembly { size := extcodesize(_addr) }
  }

  /**
    @notice Returns the code of a given address
    @dev It will fail if `_end < _start`
    @param _addr Address that may or may not contain code
    @param _start number of bytes of code to skip on read
    @param _end index before which to end extraction
    @return oCode read from `_addr` deployed bytecode

    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd
  */
  function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) {
    uint256 csize = codeSize(_addr);
    if (csize == 0) return bytes("");

    if (_start > csize) return bytes("");
    if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end); 

    unchecked {
      uint256 reqSize = _end - _start;
      uint256 maxSize = csize - _start;

      uint256 size = maxSize < reqSize ? maxSize : reqSize;

      assembly {
        // allocate output byte array - this could also be done without assembly
        // by using o_code = new bytes(size)
        oCode := mload(0x40)
        // new "memory end" including padding
        mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))
        // store length in memory
        mstore(oCode, size)
        // actually retrieve the code, this needs assembly
        extcodecopy(_addr, add(oCode, 0x20), _start, size)
      }
    }
  }
}


/**
  @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost.
  @author Agustin Aguilar <[email protected]>

  Readme: https://github.com/0xsequence/sstore2#readme
*/
library SSTORE2 {
  error WriteError();

  /**
    @notice Stores `_data` and returns `pointer` as key for later retrieval
    @dev The pointer is a contract address with `_data` as code
    @param _data to be written
    @return pointer Pointer to the written `_data`
  */
  function write(bytes memory _data) internal returns (address pointer) {
    // Append 00 to _data so contract can't be called
    // Build init code
    bytes memory code = Bytecode.creationCodeFor(
      abi.encodePacked(
        hex'00',
        _data
      )
    );

    // Deploy contract using create
    assembly { pointer := create(0, add(code, 32), mload(code)) }

    // Address MUST be non-zero
    if (pointer == address(0)) revert WriteError();
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @return data read from `_pointer` contract
  */
  function read(address _pointer) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, _end + 1);
  }
}


/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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



/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `tokenId` must be already minted.
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}



// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            IERC165
    // ==============================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // ==============================
    //            IERC721
    // ==============================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

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

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

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

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

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

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

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

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

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

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

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

    // ==============================
    //        IERC721Metadata
    // ==============================

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

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

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


/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to `_startTokenId()`
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (_addressToUint256(owner) == 0) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return
            (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) &
            BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return
            (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) &
            BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_AUX);
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly {
            // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId)
        private
        view
        returns (uint256)
    {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed)
        private
        pure
        returns (TokenOwnership memory ownership)
    {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
    }

    /**
     * Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index)
        internal
        view
        returns (TokenOwnership memory)
    {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId)
        internal
        view
        returns (TokenOwnership memory)
    {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value)
        private
        pure
        returns (uint256 result)
    {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
        public
        view
        override
        returns (address)
    {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

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

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, "");
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (_addressToUint256(to) == 0) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] +=
                quantity *
                ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (
                        !_checkContractOnERC721Received(
                            address(0),
                            to,
                            updatedIndex++,
                            _data
                        )
                    ) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (_addressToUint256(to) == 0) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] +=
                quantity *
                ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from)
            revert TransferFromIncorrectOwner();

        address approvedAddress = _tokenApprovals[tokenId];

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            approvedAddress == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (_addressToUint256(to) == 0) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));
        address approvedAddress = _tokenApprovals[tokenId];

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                approvedAddress == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED |
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

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

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value)
        internal
        pure
        returns (string memory ptr)
    {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}


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

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


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

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}



/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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


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

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

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

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

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

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

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

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


/**
 * Slightly adjusted version of PaymentSplitter by OpenZeppelin
 *
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(
        IERC20 indexed token,
        address to,
        uint256 amount
    );
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(
            payees.length == shares_.length,
            "PaymentSplitter: payees and shares length mismatch"
        );
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

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

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleased(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function released(IERC20 token, address account)
        public
        view
        returns (uint256)
    {
        return _erc20Released[token][account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(
            account,
            totalReceived,
            released(account)
        );

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _released[account] += payment;
        _totalReleased += payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function release(IERC20 token, address account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = token.balanceOf(address(this)) +
            totalReleased(token);
        uint256 payment = _pendingPayment(
            account,
            totalReceived,
            released(token, account)
        );

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _erc20Released[token][account] += payment;
        _erc20TotalReleased[token] += payment;

        SafeERC20.safeTransfer(token, account, payment);
        emit ERC20PaymentReleased(token, account, payment);
    }

    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        return
            (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) internal {
        require(
            account != address(0),
            "PaymentSplitter: account is the zero address"
        );
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(
            _shares[account] == 0,
            "PaymentSplitter: account already has shares"
        );

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }

    /**
     * @dev Update a payee on the contract.
     * @param index The array index of the payee to update.
     * @param shares_ The number of shares owned by the payee.
     */
    function _updatePayee(uint256 index, uint256 shares_) internal {
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        uint256 temp = _shares[payee(index)];
        _shares[payee(index)] = shares_;
        _totalShares = _totalShares - temp + shares_;
    }

    /**
     * @dev Remove a payee from the contract.
     * @param index The array index of the payee to update.
     */
    function _removePayee(uint256 index) internal {
        uint256 temp = _shares[payee(index)];
        _shares[payee(index)] = 0;
        _payees[index] = _payees[_payees.length - 1];
        _payees.pop();
        _totalShares = _totalShares - temp;
    }
}


contract Royalties_V1_1 is PaymentSplitter, Ownable {
    constructor(
        address[] memory payees_,
        uint256[] memory shares_,
        address owner_
    ) PaymentSplitter(payees_, shares_) {
        transferOwnership(owner_);
    }

    function addPayee(address payee, uint256 shares) public onlyOwner {
        _addPayee(payee, shares);
    }

    function updatePayee(uint256 payeeIndex, uint256 shares) public onlyOwner {
        _updatePayee(payeeIndex, shares);
    }

    function removePayee(uint256 payeeIndex) public onlyOwner {
        _removePayee(payeeIndex);
    }
}


contract MixedStems_V1_1 is ERC721A, ERC2981, Ownable {
    using Strings for uint256;
    using Address for address payable;
    using BytesLib for bytes;

    enum Phase {
        INIT,
        ALLOWLIST,
        PUBLIC,
        RESERVE
    }

    type SongID is uint256;
    type TrackID is uint256;

    Royalties_V1_1 public immutable royaltyContract;

    DateTimeAPI public constant dateTimeAPI = DateTimeAPI(0x1a6184CD4C5Bea62B0116de7962EE7315B7bcBce);
    uint256 public presaleMintStartTime;
    uint256 public publicMintStartTime;
    uint256 public reserveMintStartTime;

    string public baseURI;
    string public prerevealURI;

    uint256 public numVariableTracks;
    uint256 public mintPrice;
    uint256 public maxSupply;
    uint256 public maxPerMint;

    // metadata values
    string public composer;
    string private _singular;
    string public description;

    // song ID -> track ID -> array of pointers to SSTORE2 MIDI data
    mapping(SongID => mapping(TrackID => address[])) private _tracks;
    // song ID -> array of pointers to SSTORE2 MIDI data
    mapping(SongID => address[]) private _staticTracks;
    // song ID -> time division
    mapping(SongID => bytes2) private _timeDivisions;
    // song ID -> song name
    mapping(SongID => string) private _songNames;
    // song ID -> variant -> variant name
    mapping(SongID => mapping(uint256 => string)) private _variantNames;
    // song ID -> track ID -> track name
    mapping(SongID => mapping(TrackID => string)) private _stemTypeNames;
    // stem address -> stem name
    mapping(address => string) private _stemNames;

    bytes private _seeds;

    bytes32 private _allowlistMerkleRoot;

    // MODIFIERS -----------------------------------------------------

    modifier mustAfter(uint256 time) {
        require(
            block.timestamp > time && time > 0,
            "MixedStems_V1_1: OperationRequiresTime"
        );
        _;
    }

    modifier mustPrice(uint256 _price) {
        require(msg.value == _price, "MixedStems_V1_1: WrongPrice");
        _;
    }

    // CONSTRUCTOR ---------------------------------------------------

    constructor(
        string memory name_,
        string memory singular_,
        string memory description_,
        string memory symbol_,
        string memory composer_,
        uint256 numVariableTracks_,
        address[] memory royaltyReceivers_,
        uint256[] memory royaltyShares_,
        uint256 royaltyPercent_
    ) ERC721A(name_, symbol_) {
        _singular = singular_;
        description = description_;
        numVariableTracks = numVariableTracks_;
        composer = composer_;
        Royalties_V1_1 p = new Royalties_V1_1(
            royaltyReceivers_,
            royaltyShares_,
            msg.sender
        );
        royaltyContract = p;
        _setDefaultRoyalty(address(p), uint96(royaltyPercent_));
    }

    // ADMIN FUNCTIONS ---------------------------------------------------

    function withdraw(address payable to, uint256 amount) public onlyOwner {
        require(
            address(this).balance >= amount,
            "MixedStems_V1_1: InsufficientBalance"
        );

        if (amount == 0) {
            amount = address(this).balance;
        }
        if (to == address(0)) {
            to = payable(owner());
        }
        to.sendValue(amount);
    }

    function setBaseURI(string memory _baseURI) public onlyOwner {
        baseURI = _baseURI;
    }

    function setPreRevealURI(string memory _prerevealURI) public onlyOwner {
        prerevealURI = _prerevealURI;
    }

    function setComposer(string memory composer_) public onlyOwner {
        composer = composer_;
    }

    function setDescription(string memory description_) public onlyOwner {
        description = description_;
    }

    function setMintPrice(uint256 value) public onlyOwner {
        mintPrice = value;
    }

    function setMaxPerMint(uint256 value) public onlyOwner {
        maxPerMint = value;
    }

    function setMaxSupply(uint256 value) public onlyOwner {
        maxSupply = value;
    }

    function setSeeds(bytes memory seeds) public onlyOwner {
        _seeds = seeds;
    }

    function setAllowlistMerkleRoot(bytes32 value) public onlyOwner {
        _allowlistMerkleRoot = value;
    }

    function setRoyaltyPercentage(uint96 percent) public onlyOwner {
        _setDefaultRoyalty(address(royaltyContract), percent);
    }

    function setSongNames(SongID[] memory songs, string[] memory songNames)
        public
        onlyOwner
    {
        require(songs.length == songNames.length);
        for (uint256 i = 0; i < songNames.length; i++) {
            _songNames[songs[i]] = songNames[i];
        }
    }

    function setVariantNames(
        SongID song,
        uint256[] memory variants,
        string[] memory variantNames
    ) public onlyOwner {
        require(variants.length == variantNames.length);
        for (uint256 i = 0; i < variants.length; i++) {
            _variantNames[song][variants[i]] = variantNames[i];
        }
    }

    function setTrackNames(
        SongID song,
        TrackID[] memory tracks,
        string[] memory trackNames
    ) public onlyOwner {
        require(tracks.length == trackNames.length);
        for (uint256 i = 0; i < trackNames.length; i++) {
            _stemTypeNames[song][tracks[i]] = trackNames[i];
        }
    }

    function setPresaleStart(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour,
        uint8 minute,
        uint8 second
    ) public onlyOwner {
        presaleMintStartTime = dateTimeAPI.toTimestamp(
            year,
            month,
            day,
            hour,
            minute,
            second
        );
    }

    function setPublicStart(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour,
        uint8 minute,
        uint8 second
    ) public onlyOwner {
        publicMintStartTime = dateTimeAPI.toTimestamp(
            year,
            month,
            day,
            hour,
            minute,
            second
        );
    }

    function setReserveStart(
        uint16 year,
        uint8 month,
        uint8 day,
        uint8 hour,
        uint8 minute,
        uint8 second
    ) public onlyOwner {
        reserveMintStartTime = dateTimeAPI.toTimestamp(
            year,
            month,
            day,
            hour,
            minute,
            second
        );
    }

    function addVariableTrack(
        SongID song,
        TrackID trackNum,
        bytes calldata track,
        string calldata trackName
    ) external onlyOwner {
        require(TrackID.unwrap(trackNum) < numVariableTracks);
        address pointer = SSTORE2.write(track);
        _tracks[song][trackNum].push(pointer);
        _stemNames[pointer] = trackName;
    }

    function removeVariableTrack(
        SongID song,
        TrackID trackNum,
        uint256 index
    ) external onlyOwner {
        _tracks[song][trackNum][index] = _tracks[song][trackNum][
            _tracks[song][trackNum].length - 1
        ];
        _tracks[song][trackNum].pop();
    }

    function resetVariableTracks(SongID song, TrackID trackNum)
        external
        onlyOwner
    {
        delete _tracks[song][trackNum];
    }

    function addStaticTrack(
        SongID song,
        bytes calldata track
    ) external onlyOwner {
        address pointer = SSTORE2.write(track);
        _staticTracks[song].push(pointer);
    }

    function removeStaticTrack(SongID song, uint256 index) external onlyOwner {
        _staticTracks[song][index] = _staticTracks[song][
            _staticTracks[song].length - 1
        ];
        _staticTracks[song].pop();
    }

    function resetStaticTracks(SongID song) external onlyOwner {
        delete _staticTracks[song];
    }

    function setTimeDivision(SongID song, bytes2 timeDivision)
        public
        onlyOwner
    {
        _timeDivisions[song] = timeDivision;
    }

    // ERC-721 FUNCTIONS ---------------------------------------------------

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) {
            revert URIQueryForNonexistentToken();
        }

        if (_seeds.length == 0) {
            return string(abi.encodePacked(prerevealURI, tokenId.toString()));
        }

        bytes32 seed = getSeed(tokenId);
        uint256 variant = getVariant(tokenId);
        SongID song = SongID.wrap(uint8(seed[0]));

        string memory mid = midi(tokenId);

        bytes memory json = abi.encodePacked(
            '{"name":"',
            _singular,
            " #",
            tokenId.toString(),
            '", "description": "',
            description,
            '", "image": "',
            baseURI,
            "/image/",
            uint256(seed).toHexString(),
            '", "animation_url": "',
            baseURI,
            "/animation/",
            uint256(seed).toHexString()
        );
        json = abi.encodePacked(
            json,
            '", "midi": "data:audio/midi;base64,',
            mid,
            '", "external_url": "https://beatfoundry.xyz", "composer": "',
            composer,
            '", "attributes": [{"trait_type": "Song", "value": "',
            _songNames[song],
            '"}'
        );

        json = abi.encodePacked(
            json,
            ', {"trait_type": "Cover Art", "value": "',
            _variantNames[song][variant],
            '"}'
        );

        for (uint256 i = 0; i < numVariableTracks; i++) {
            json = abi.encodePacked(
                json,
                ', {"trait_type": "',
                _stemTypeNames[song][TrackID.wrap(i)],
                '", "value": "',
                _stemNames[_tracks[song][TrackID.wrap(i)][uint8(seed[i + 1])]],
                '"}'
            );
        }
        json = abi.encodePacked(json, "]}");
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(json)
                )
            );
    }

    function midi(uint256 tokenId) public view returns (string memory) {
        if (!_exists(tokenId)) {
            revert URIQueryForNonexistentToken();
        }
        bytes32 seed = getSeed(tokenId);

        SongID song = SongID.wrap(uint8(seed[0]));

        uint256 lenStatic = _staticTracks[song].length;

        bytes memory mid = newMidi(uint8(lenStatic + numVariableTracks), song);

        for (uint256 i = 0; i < numVariableTracks; i++) {
            bytes memory track = SSTORE2.read(
                _tracks[song][TrackID.wrap(i)][uint8(seed[i + 1])]
            );
            mid = bytes.concat(mid, newTrack(track));
        }

        for (uint256 i = 0; i < lenStatic; i++) {
            bytes memory track = SSTORE2.read(_staticTracks[song][i]);
            mid = bytes.concat(mid, newTrack(track));
        }

        return Base64.encode(mid);
    }

    function getVariant(uint256 tokenId) public view returns (uint256) {
        if (!_exists(tokenId)) {
            revert URIQueryForNonexistentToken();
        }
        return
            uint8(
                _seeds[
                    tokenId * (numVariableTracks + 2) + (numVariableTracks + 1)
                ]
            );
    }

    function getSeed(uint256 tokenId) public view returns (bytes32) {
        if (!_exists(tokenId)) {
            revert URIQueryForNonexistentToken();
        }

        require(_seeds.length > 0, "MixedStems_V1_1: NoSeeds");

        return
            bytes32(
                _seeds.slice(
                    tokenId * (numVariableTracks + 2),
                    (numVariableTracks + 2)
                )
            );
    }

    // MINTING FUNCTIONS ---------------------------------------------------

    function mint(uint256 amount)
        external
        payable
        mustAfter(publicMintStartTime)
        mustPrice(mintPrice * amount)
    {
        require(
            _nextTokenId() + amount <= maxSupply,
            "MixedStems_V1_1: MintingLimitReached"
        );
        require(
            amount <= maxPerMint,
            "MixedStems_V1_1: AmountGreaterThanMaxMintPerTx"
        );

        _safeMint(_msgSender(), amount);
    }

    function mintReserve(address to, uint256 amount)
        external
        mustAfter(reserveMintStartTime)
        onlyOwner
    {
        require(
            _nextTokenId() + amount <= maxSupply,
            "MixedStems_V1_1: MintingLimitReached"
        );
        _safeMint(to, amount);
    }

    function mintAllowlist(
        uint256 amount,
        uint256 allotted,
        bytes32[] calldata allowlistProof
    )
        external
        payable
        mustAfter(presaleMintStartTime)
        mustPrice(mintPrice * amount)
    {
        require(
            _nextTokenId() + amount <= maxSupply,
            "MixedStems_V1_1: MintingLimitReached"
        );
        require(
            balanceOf(_msgSender()) + amount <= allotted,
            "MixedStems_V1_1: AllocationExceeded"
        );
        require(
            isAllowlistedFor(_msgSender(), allotted, allowlistProof),
            "MixedStems_V1_1: NotAllowlisted"
        );
        _safeMint(_msgSender(), amount);
    }

    // MIDI FUNCTIONS ---------------------------------------------------

    function newMidi(uint8 numTracks, SongID song)
        private
        view
        returns (bytes memory)
    {
        bytes2 timeDivision = _timeDivisions[song];
        if (uint16(timeDivision) == 0) {
            timeDivision = bytes2(uint16(256));
        }
        bytes memory data = new bytes(14);
        data[0] = bytes1(0x4D);
        data[1] = bytes1(0x54);
        data[2] = bytes1(0x68);
        data[3] = bytes1(0x64);
        data[4] = bytes1(0x00);
        data[5] = bytes1(0x00);
        data[6] = bytes1(0x00);
        data[7] = bytes1(0x06);
        data[8] = bytes1(0x00);
        if (numTracks == 1) {
            data[9] = bytes1(0x00);
        } else {
            data[9] = bytes1(0x01);
        }
        data[10] = bytes1(0x00);
        data[11] = bytes1(numTracks);
        data[12] = timeDivision[0];
        data[13] = timeDivision[1];
        return data;
    }

    function newTrack(bytes memory data) private pure returns (bytes memory) {
        bytes memory it = new bytes(8);
        it[0] = bytes1(0x4D);
        it[1] = bytes1(0x54);
        it[2] = bytes1(0x72);
        it[3] = bytes1(0x6b);
        bytes memory asBytes = abi.encodePacked(data.length);
        it[4] = asBytes[asBytes.length - 4];
        it[5] = asBytes[asBytes.length - 3];
        it[6] = asBytes[asBytes.length - 2];
        it[7] = asBytes[asBytes.length - 1];
        return bytes.concat(it, data);
    }

    // HELPERS ------------------------------------------------------------------

    function isAllowlistedFor(
        address _allowlistee,
        uint256 _amount,
        bytes32[] calldata _proof
    ) private view returns (bool) {
        return
            MerkleProof.verify(
                _proof,
                _allowlistMerkleRoot,
                keccak256(abi.encodePacked(_allowlistee, _amount))
            );
    }

    function mintingPhase() public view returns (Phase) {
        if (block.timestamp > reserveMintStartTime) {
            return Phase.RESERVE;
        } else if (block.timestamp > publicMintStartTime) {
            return Phase.PUBLIC;
        } else if (block.timestamp > presaleMintStartTime) {
            return Phase.ALLOWLIST;
        } else {
            return Phase.INIT;
        }
    }

     function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) {
        // IERC165: 0x01ffc9a7, IERC721: 0x80ac58cd, IERC721Metadata: 0x5b5e139f, IERC29081: 0x2a55205a
        return ERC721A.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId);
    }

     function _feeDenominator() internal pure override returns (uint96) {
        return 100;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"singular_","type":"string"},{"internalType":"string","name":"description_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"composer_","type":"string"},{"internalType":"uint256","name":"numVariableTracks_","type":"uint256"},{"internalType":"address[]","name":"royaltyReceivers_","type":"address[]"},{"internalType":"uint256[]","name":"royaltyShares_","type":"uint256[]"},{"internalType":"uint256","name":"royaltyPercent_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WriteError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"bytes","name":"track","type":"bytes"}],"name":"addStaticTrack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"MixedStems_V1_1.TrackID","name":"trackNum","type":"uint256"},{"internalType":"bytes","name":"track","type":"bytes"},{"internalType":"string","name":"trackName","type":"string"}],"name":"addVariableTrack","outputs":[],"stateMutability":"nonpayable","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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"composer","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dateTimeAPI","outputs":[{"internalType":"contract DateTimeAPI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"getSeed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getVariant","outputs":[{"internalType":"uint256","name":"","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":[],"name":"maxPerMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"midi","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"allotted","type":"uint256"},{"internalType":"bytes32[]","name":"allowlistProof","type":"bytes32[]"}],"name":"mintAllowlist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingPhase","outputs":[{"internalType":"enum MixedStems_V1_1.Phase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numVariableTracks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prerevealURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleMintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeStaticTrack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"MixedStems_V1_1.TrackID","name":"trackNum","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeVariableTrack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveMintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"}],"name":"resetStaticTracks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"MixedStems_V1_1.TrackID","name":"trackNum","type":"uint256"}],"name":"resetVariableTracks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltyContract","outputs":[{"internalType":"contract Royalties_V1_1","name":"","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":"bytes32","name":"value","type":"bytes32"}],"name":"setAllowlistMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"composer_","type":"string"}],"name":"setComposer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"description_","type":"string"}],"name":"setDescription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMaxPerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_prerevealURI","type":"string"}],"name":"setPreRevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"year","type":"uint16"},{"internalType":"uint8","name":"month","type":"uint8"},{"internalType":"uint8","name":"day","type":"uint8"},{"internalType":"uint8","name":"hour","type":"uint8"},{"internalType":"uint8","name":"minute","type":"uint8"},{"internalType":"uint8","name":"second","type":"uint8"}],"name":"setPresaleStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"year","type":"uint16"},{"internalType":"uint8","name":"month","type":"uint8"},{"internalType":"uint8","name":"day","type":"uint8"},{"internalType":"uint8","name":"hour","type":"uint8"},{"internalType":"uint8","name":"minute","type":"uint8"},{"internalType":"uint8","name":"second","type":"uint8"}],"name":"setPublicStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"year","type":"uint16"},{"internalType":"uint8","name":"month","type":"uint8"},{"internalType":"uint8","name":"day","type":"uint8"},{"internalType":"uint8","name":"hour","type":"uint8"},{"internalType":"uint8","name":"minute","type":"uint8"},{"internalType":"uint8","name":"second","type":"uint8"}],"name":"setReserveStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"percent","type":"uint96"}],"name":"setRoyaltyPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"seeds","type":"bytes"}],"name":"setSeeds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID[]","name":"songs","type":"uint256[]"},{"internalType":"string[]","name":"songNames","type":"string[]"}],"name":"setSongNames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"bytes2","name":"timeDivision","type":"bytes2"}],"name":"setTimeDivision","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"MixedStems_V1_1.TrackID[]","name":"tracks","type":"uint256[]"},{"internalType":"string[]","name":"trackNames","type":"string[]"}],"name":"setTrackNames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"MixedStems_V1_1.SongID","name":"song","type":"uint256"},{"internalType":"uint256[]","name":"variants","type":"uint256[]"},{"internalType":"string[]","name":"variantNames","type":"string[]"}],"name":"setVariantNames","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":"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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162006e6038038062006e60833981016040819052620000349162000520565b8851899087906200004d9060029060208501906200027c565b508051620000639060039060208401906200027c565b50506000805550620000753362000126565b87516200008a9060159060208b01906200027c565b508651620000a09060169060208a01906200027c565b5060108490558451620000bb9060149060208801906200027c565b506000838333604051620000cf906200030b565b620000dd9392919062000664565b604051809103906000f080158015620000fa573d6000803e3d6000fd5b506001600160a01b038116608052905062000116818362000178565b505050505050505050506200073f565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60646001600160601b0382161115620001eb5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620002435760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620001e2565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b8280546200028a9062000703565b90600052602060002090601f016020900481019282620002ae5760008555620002f9565b82601f10620002c957805160ff1916838001178555620002f9565b82800160010185558215620002f9579182015b82811115620002f9578251825591602001919060010190620002dc565b506200030792915062000319565b5090565b611a3b806200542583390190565b5b808211156200030757600081556001016200031a565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000371576200037162000330565b604052919050565b600082601f8301126200038b57600080fd5b81516001600160401b03811115620003a757620003a762000330565b6020620003bd601f8301601f1916820162000346565b8281528582848701011115620003d257600080fd5b60005b83811015620003f2578581018301518282018401528201620003d5565b83811115620004045760008385840101525b5095945050505050565b60006001600160401b038211156200042a576200042a62000330565b5060051b60200190565b600082601f8301126200044657600080fd5b815160206200045f62000459836200040e565b62000346565b82815260059290921b840181019181810190868411156200047f57600080fd5b8286015b84811015620004b35780516001600160a01b0381168114620004a55760008081fd5b835291830191830162000483565b509695505050505050565b600082601f830112620004d057600080fd5b81516020620004e362000459836200040e565b82815260059290921b840181019181810190868411156200050357600080fd5b8286015b84811015620004b3578051835291830191830162000507565b60008060008060008060008060006101208a8c0312156200054057600080fd5b89516001600160401b03808211156200055857600080fd5b620005668d838e0162000379565b9a5060208c01519150808211156200057d57600080fd5b6200058b8d838e0162000379565b995060408c0151915080821115620005a257600080fd5b620005b08d838e0162000379565b985060608c0151915080821115620005c757600080fd5b620005d58d838e0162000379565b975060808c0151915080821115620005ec57600080fd5b620005fa8d838e0162000379565b965060a08c0151955060c08c01519150808211156200061857600080fd5b620006268d838e0162000434565b945060e08c01519150808211156200063d57600080fd5b506200064c8c828d01620004be565b9250506101008a015190509295985092959850929598565b606080825284519082018190526000906020906080840190828801845b82811015620006a85781516001600160a01b03168452928401929084019060010162000681565b5050508381038285015285518082528683019183019060005b81811015620006df57835183529284019291840191600101620006c1565b50506001600160a01b03861660408601529250620006fb915050565b949350505050565b600181811c908216806200071857607f821691505b6020821081036200073957634e487b7160e01b600052602260045260246000fd5b50919050565b608051614cc362000762600039600081816104750152611a530152614cc36000f3fe6080604052600436106103ad5760003560e01c806374e1ee41116101e7578063bdcea4bc1161010d578063e0d4ea37116100a0578063f3fef3a31161006f578063f3fef3a314610ae8578063f4a0a52814610b08578063f95df41414610b28578063faff57d114610b4857600080fd5b8063e0d4ea3714610a3f578063e985e9c514610a5f578063ef14817714610aa8578063f2fde38b14610ac857600080fd5b8063d4e55d3c116100dc578063d4e55d3c146109d4578063d5abeb01146109f4578063d62280b214610a0a578063db6242c314610a1f57600080fd5b8063bdcea4bc1461095e578063c87b56dd1461097e578063ca3bd3251461099e578063d3cf00a3146109be57600080fd5b80639f6d68b011610185578063aeb1fe5111610154578063aeb1fe51146108f3578063b09e44fa14610908578063b79697f81461091e578063b88d4fde1461093e57600080fd5b80639f6d68b014610880578063a0712d68146108a0578063a22cb465146108b3578063a3114cde146108d357600080fd5b80638da5cb5b116101c15780638da5cb5b1461080d5780638e825be01461082b57806390c3f38f1461084b57806395d89b411461086b57600080fd5b806374e1ee41146107ab5780637ad63f18146107cb5780637e5ac09a146107eb57600080fd5b80633d241e6a116102d757806367a44c641161026a5780636f8b44b0116102395780636f8b44b01461074157806370a0823114610761578063715018a6146107815780637284e4161461079657600080fd5b806367a44c64146106e05780636817c76c146107005780636c0360eb146107165780636cf3884d1461072b57600080fd5b8063507e094f116102a6578063507e094f1461066a578063521993e31461068057806355f804b3146106a05780636352211e146106c057600080fd5b80633d241e6a146105e257806342842e0e1461060257806345657735146106225780634e926bc91461064257600080fd5b80631cb4ffb21161034f5780632a55205a1161031e5780632a55205a146105435780632a85db55146105825780632c7a6dc7146105a257806333ba01a1146105c257600080fd5b80631cb4ffb2146104da57806323b872dd146104fa5780632792e5e81461051a5780632992cd641461053057600080fd5b8063095ea7b31161038b578063095ea7b3146104415780631663ee031461046357806318160ddd146104975780631a62ae32146104ba57600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613ca8565b610b68565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610b88565b6040516103de9190613d1d565b34801561041557600080fd5b50610429610424366004613d30565b610c1a565b6040516001600160a01b0390911681526020016103de565b34801561044d57600080fd5b5061046161045c366004613d5e565b610c5e565b005b34801561046f57600080fd5b506104297f000000000000000000000000000000000000000000000000000000000000000081565b3480156104a357600080fd5b50600154600054035b6040519081526020016103de565b3480156104c657600080fd5b506104616104d5366004613d30565b610d30565b3480156104e657600080fd5b506104616104f5366004613da0565b610d7d565b34801561050657600080fd5b50610461610515366004613e1d565b610e36565b34801561052657600080fd5b506104ac600b5481565b61046161053e366004613e5e565b610e46565b34801561054f57600080fd5b5061056361055e366004613ee0565b610fdf565b604080516001600160a01b0390931683526020830191909152016103de565b34801561058e57600080fd5b5061046161059d366004613fb7565b61108c565b3480156105ae57600080fd5b506104616105bd36600461409d565b6110cd565b3480156105ce57600080fd5b506104616105dd366004614160565b611194565b3480156105ee57600080fd5b506104616105fd366004614259565b611244565b34801561060e57600080fd5b5061046161061d366004613e1d565b611322565b34801561062e57600080fd5b5061046161063d366004613ee0565b61133d565b34801561064e57600080fd5b50610429731a6184cd4c5bea62b0116de7962ee7315b7bcbce81565b34801561067657600080fd5b506104ac60135481565b34801561068c57600080fd5b5061046161069b366004613fb7565b61143a565b3480156106ac57600080fd5b506104616106bb366004613fb7565b611477565b3480156106cc57600080fd5b506104296106db366004613d30565b6114b4565b3480156106ec57600080fd5b506103fc6106fb366004613d30565b6114bf565b34801561070c57600080fd5b506104ac60115481565b34801561072257600080fd5b506103fc611662565b34801561073757600080fd5b506104ac60105481565b34801561074d57600080fd5b5061046161075c366004613d30565b6116f0565b34801561076d57600080fd5b506104ac61077c3660046142db565b61171f565b34801561078d57600080fd5b50610461611767565b3480156107a257600080fd5b506103fc61179d565b3480156107b757600080fd5b506104ac6107c6366004613d30565b6117aa565b3480156107d757600080fd5b506104616107e6366004613da0565b611850565b3480156107f757600080fd5b50610800611909565b6040516103de91906142f8565b34801561081957600080fd5b50600a546001600160a01b0316610429565b34801561083757600080fd5b50610461610846366004613d5e565b611941565b34801561085757600080fd5b50610461610866366004613fb7565b6119d8565b34801561087757600080fd5b506103fc611a15565b34801561088c57600080fd5b5061046161089b366004614320565b611a24565b6104616108ae366004613d30565b611a78565b3480156108bf57600080fd5b506104616108ce366004614349565b611bab565b3480156108df57600080fd5b506104616108ee36600461409d565b611c40565b3480156108ff57600080fd5b506103fc611d01565b34801561091457600080fd5b506104ac600d5481565b34801561092a57600080fd5b50610461610939366004613fb7565b611d0e565b34801561094a57600080fd5b50610461610959366004614387565b611d4b565b34801561096a57600080fd5b506104616109793660046143f2565b611d8f565b34801561098a57600080fd5b506103fc610999366004613d30565b611ea6565b3480156109aa57600080fd5b506104616109b936600461441e565b612115565b3480156109ca57600080fd5b506104ac600c5481565b3480156109e057600080fd5b506104616109ef366004613da0565b612163565b348015610a0057600080fd5b506104ac60125481565b348015610a1657600080fd5b506103fc61221c565b348015610a2b57600080fd5b50610461610a3a366004613d30565b612229565b348015610a4b57600080fd5b506104ac610a5a366004613d30565b612258565b348015610a6b57600080fd5b506103d2610a7a366004614450565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610ab457600080fd5b50610461610ac3366004613ee0565b6123ab565b348015610ad457600080fd5b50610461610ae33660046142db565b6123f7565b348015610af457600080fd5b50610461610b03366004613d5e565b61248f565b348015610b1457600080fd5b50610461610b23366004613d30565b612550565b348015610b3457600080fd5b50610461610b43366004613d30565b61257f565b348015610b5457600080fd5b50610461610b6336600461447e565b6125ae565b6000610b738261265c565b80610b825750610b82826126aa565b92915050565b606060028054610b97906144c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc3906144c9565b8015610c105780601f10610be557610100808354040283529160200191610c10565b820191906000526020600020905b815481529060010190602001808311610bf357829003601f168201915b5050505050905090565b6000610c25826126df565b610c42576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610c6982612706565b9050806001600160a01b0316836001600160a01b031603610c9d5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610cd457610cb78133610a7a565b610cd4576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600a546001600160a01b03163314610d635760405162461bcd60e51b8152600401610d5a906144fd565b60405180910390fd5b6000818152601860205260408120610d7a91613b67565b50565b600a546001600160a01b03163314610da75760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec90610de890899089908990899089908990600401614532565b6020604051808303816000875af1158015610e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2b9190614568565b600b55505050505050565b610e41838383612774565b505050565b600b548042118015610e585750600081115b610e745760405162461bcd60e51b8152600401610d5a90614581565b84601154610e8291906145dd565b803414610ed15760405162461bcd60e51b815260206004820152601b60248201527f4d697865645374656d735f56315f313a2057726f6e67507269636500000000006044820152606401610d5a565b60125486610ede60005490565b610ee891906145fc565b1115610f065760405162461bcd60e51b8152600401610d5a90614614565b8486610f113361171f565b610f1b91906145fc565b1115610f755760405162461bcd60e51b815260206004820152602360248201527f4d697865645374656d735f56315f313a20416c6c6f636174696f6e457863656560448201526219195960ea1b6064820152608401610d5a565b610f813386868661292a565b610fcd5760405162461bcd60e51b815260206004820152601f60248201527f4d697865645374656d735f56315f313a204e6f74416c6c6f776c6973746564006044820152606401610d5a565b610fd733876129b4565b505050505050565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916110545750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090606490611072906001600160601b0316876145dd565b61107c919061466e565b91519350909150505b9250929050565b600a546001600160a01b031633146110b65760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990600f906020840190613b85565b5050565b600a546001600160a01b031633146110f75760405162461bcd60e51b8152600401610d5a906144fd565b805182511461110557600080fd5b60005b815181101561118e5781818151811061112357611123614682565b6020026020010151601c6000868152602001908152602001600020600085848151811061115257611152614682565b60200260200101518152602001908152602001600020908051906020019061117b929190613b85565b508061118681614698565b915050611108565b50505050565b600a546001600160a01b031633146111be5760405162461bcd60e51b8152600401610d5a906144fd565b80518251146111cc57600080fd5b60005b8151811015610e41578181815181106111ea576111ea614682565b6020026020010151601a600085848151811061120857611208614682565b602002602001015181526020019081526020016000209080519060200190611231929190613b85565b508061123c81614698565b9150506111cf565b600a546001600160a01b0316331461126e5760405162461bcd60e51b8152600401610d5a906144fd565b601054851061127c57600080fd5b60006112bd85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129ce92505050565b60008881526017602090815260408083208a8452825280832080546001810182559084528284200180546001600160a01b0319166001600160a01b0386169081179091558352601d9091529020909150611318908484613c09565b5050505050505050565b610e4183838360405180602001604052806000815250611d4b565b600a546001600160a01b031633146113675760405162461bcd60e51b8152600401610d5a906144fd565b60008281526018602052604090208054611383906001906146b1565b8154811061139357611393614682565b60009182526020808320909101548483526018909152604090912080546001600160a01b0390921691839081106113cc576113cc614682565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255838152601890915260409020805480611414576114146146c8565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b600a546001600160a01b031633146114645760405162461bcd60e51b8152600401610d5a906144fd565b80516110c9906014906020840190613b85565b600a546001600160a01b031633146114a15760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990600e906020840190613b85565b6000610b8282612706565b60606114ca826126df565b6114e757604051630a14c4b560e41b815260040160405180910390fd5b60006114f283612258565b9050600081811a600081815260186020526040812054601054929350916115239061151d90846145fc565b84612a33565b905060005b6010548110156115db5760008481526017602090815260408083208484529091528120611599908761155b8560016145fc565b6020811061156b5761156b614682565b825491901a90811061157f5761157f614682565b6000918252602090912001546001600160a01b0316612d5a565b9050826115a582612d6a565b6040516020016115b69291906146de565b60405160208183030381529060405292505080806115d390614698565b915050611528565b5060005b8281101561164e576000848152601860205260408120805461160c91908490811061157f5761157f614682565b90508261161882612d6a565b6040516020016116299291906146de565b604051602081830303815290604052925050808061164690614698565b9150506115df565b5061165881612fed565b9695505050505050565b600e805461166f906144c9565b80601f016020809104026020016040519081016040528092919081815260200182805461169b906144c9565b80156116e85780601f106116bd576101008083540402835291602001916116e8565b820191906000526020600020905b8154815290600101906020018083116116cb57829003601f168201915b505050505081565b600a546001600160a01b0316331461171a5760405162461bcd60e51b8152600401610d5a906144fd565b601255565b600081600003611742576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b600a546001600160a01b031633146117915760405162461bcd60e51b8152600401610d5a906144fd565b61179b6000613156565b565b6016805461166f906144c9565b60006117b5826126df565b6117d257604051630a14c4b560e41b815260040160405180910390fd5b601e60105460016117e391906145fc565b6010546117f19060026145fc565b6117fb90856145dd565b61180591906145fc565b8154611810906144c9565b811061181e5761181e614682565b81546001161561183d5790600052602060002090602091828204019190065b9054600160f81b911a0260f81c92915050565b600a546001600160a01b0316331461187a5760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec906118bb90899089908990899089908990600401614532565b6020604051808303816000875af11580156118da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fe9190614568565b600c55505050505050565b6000600d5442111561191b5750600390565b600c5442111561192b5750600290565b600b5442111561193b5750600190565b50600090565b600d5480421180156119535750600081115b61196f5760405162461bcd60e51b8152600401610d5a90614581565b600a546001600160a01b031633146119995760405162461bcd60e51b8152600401610d5a906144fd565b601254826119a660005490565b6119b091906145fc565b11156119ce5760405162461bcd60e51b8152600401610d5a90614614565b610e4183836129b4565b600a546001600160a01b03163314611a025760405162461bcd60e51b8152600401610d5a906144fd565b80516110c9906016906020840190613b85565b606060038054610b97906144c9565b600a546001600160a01b03163314611a4e5760405162461bcd60e51b8152600401610d5a906144fd565b610d7a7f0000000000000000000000000000000000000000000000000000000000000000826131a8565b600c548042118015611a8a5750600081115b611aa65760405162461bcd60e51b8152600401610d5a90614581565b81601154611ab491906145dd565b803414611b035760405162461bcd60e51b815260206004820152601b60248201527f4d697865645374656d735f56315f313a2057726f6e67507269636500000000006044820152606401610d5a565b60125483611b1060005490565b611b1a91906145fc565b1115611b385760405162461bcd60e51b8152600401610d5a90614614565b601354831115611ba15760405162461bcd60e51b815260206004820152602e60248201527f4d697865645374656d735f56315f313a20416d6f756e7447726561746572546860448201526d0c2dc9ac2f09ad2dce8a0cae4a8f60931b6064820152608401610d5a565b610e4133846129b4565b336001600160a01b03831603611bd45760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b03163314611c6a5760405162461bcd60e51b8152600401610d5a906144fd565b8051825114611c7857600080fd5b60005b825181101561118e57818181518110611c9657611c96614682565b6020026020010151601b60008681526020019081526020016000206000858481518110611cc557611cc5614682565b602002602001015181526020019081526020016000209080519060200190611cee929190613b85565b5080611cf981614698565b915050611c7b565b6014805461166f906144c9565b600a546001600160a01b03163314611d385760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990601e906020840190613b85565b611d56848484612774565b6001600160a01b0383163b1561118e57611d72848484846132a4565b61118e576040516368d2bf6b60e11b815260040160405180910390fd5b600a546001600160a01b03163314611db95760405162461bcd60e51b8152600401610d5a906144fd565b600083815260176020908152604080832085845290915290208054611de0906001906146b1565b81548110611df057611df0614682565b6000918252602080832090910154858352601782526040808420868552909252912080546001600160a01b039092169183908110611e3057611e30614682565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925584815260178252604080822085835290925220805480611e7f57611e7f6146c8565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b6060611eb1826126df565b611ece57604051630a14c4b560e41b815260040160405180910390fd5b601e8054611edb906144c9565b9050600003611f1657600f611eef8361338c565b604051602001611f009291906147a6565b6040516020818303038152906040529050919050565b6000611f2183612258565b90506000611f2e846117aa565b9050600082811a90611f3f866114bf565b905060006015611f4e8861338c565b6016600e611f5b8961348c565b600e611f668b61348c565b604051602001611f7c97969594939291906147c2565b60408051601f198184030181528282526000868152601a6020908152929020909350611fb192849286926014929091016148d4565b60408051601f198184030181528282526000868152601b60209081528382208983528152929020909350611fe7928492016149ef565b604051602081830303815290604052905060005b6010548110156120be576000848152601c6020908152604080832084845282528083208784526017835281842085855290925282208492601d918a6120418760016145fc565b6020811061205157612051614682565b825491901a90811061206557612065614682565b60009182526020808320909101546001600160a01b031683528281019390935260409182019020905161209a94939201614a5a565b604051602081830303815290604052915080806120b690614698565b915050611ffb565b50806040516020016120d09190614acc565b60405160208183030381529060405290506120ea81612fed565b6040516020016120fa9190614af2565b60405160208183030381529060405295505050505050919050565b600a546001600160a01b0316331461213f5760405162461bcd60e51b8152600401610d5a906144fd565b600091825260196020526040909120805461ffff191660f09290921c919091179055565b600a546001600160a01b0316331461218d5760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec906121ce90899089908990899089908990600401614532565b6020604051808303816000875af11580156121ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122119190614568565b600d55505050505050565b600f805461166f906144c9565b600a546001600160a01b031633146122535760405162461bcd60e51b8152600401610d5a906144fd565b601355565b6000612263826126df565b61228057604051630a14c4b560e41b815260040160405180910390fd5b6000601e805461228f906144c9565b9050116122de5760405162461bcd60e51b815260206004820152601860248201527f4d697865645374656d735f56315f313a204e6f536565647300000000000000006044820152606401610d5a565b6123a260105460026122f091906145fc565b6122fa90846145dd565b6010546123089060026145fc565b601e8054612315906144c9565b80601f0160208091040260200160405190810160405280929190818152602001828054612341906144c9565b801561238e5780601f106123635761010080835404028352916020019161238e565b820191906000526020600020905b81548152906001019060200180831161237157829003601f168201915b50505050506134e39092919063ffffffff16565b610b8290614b37565b600a546001600160a01b031633146123d55760405162461bcd60e51b8152600401610d5a906144fd565b600082815260176020908152604080832084845290915281206110c991613b67565b600a546001600160a01b031633146124215760405162461bcd60e51b8152600401610d5a906144fd565b6001600160a01b0381166124865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d5a565b610d7a81613156565b600a546001600160a01b031633146124b95760405162461bcd60e51b8152600401610d5a906144fd565b804710156125155760405162461bcd60e51b8152602060048201526024808201527f4d697865645374656d735f56315f313a20496e73756666696369656e7442616c604482015263616e636560e01b6064820152608401610d5a565b806000036125205750475b6001600160a01b03821661253d57600a546001600160a01b031691505b6110c96001600160a01b038316826135f0565b600a546001600160a01b0316331461257a5760405162461bcd60e51b8152600401610d5a906144fd565b601155565b600a546001600160a01b031633146125a95760405162461bcd60e51b8152600401610d5a906144fd565b601f55565b600a546001600160a01b031633146125d85760405162461bcd60e51b8152600401610d5a906144fd565b600061261983838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129ce92505050565b600094855260186020908152604086208054600181018255908752952090940180546001600160a01b0319166001600160a01b0390951694909417909355505050565b60006301ffc9a760e01b6001600160e01b03198316148061268d57506380ac58cd60e01b6001600160e01b03198316145b80610b825750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b1480610b8257506301ffc9a760e01b6001600160e01b0319831614610b82565b6000805482108015610b82575050600090815260046020526040902054600160e01b161590565b60008160005481101561275b5760008181526004602052604081205490600160e01b82169003612759575b80600003612752575060001901600081815260046020526040902054612731565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600061277f82612706565b9050836001600160a01b0316816001600160a01b0316146127b25760405162a1148160e81b815260040160405180910390fd5b6000828152600660205260408120546001600160a01b03908116919086163314806127e257506127e28633610a7a565b806127f557506001600160a01b03821633145b90508061281557604051632ce44b5f60e11b815260040160405180910390fd5b8460000361283657604051633a954ecd60e21b815260040160405180910390fd5b811561285957600084815260066020526040902080546001600160a01b03191690555b6001600160a01b038681166000908152600560209081526040808320805460001901905592881682528282208054600101905586825260049052908120600160e11b4260a01b88178117909155841690036128e4576001840160008181526004602052604081205490036128e25760005481146128e25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610fd7565b60006129a983838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601f546040516bffffffffffffffffffffffff1960608c901b166020820152603481018a9052909250605401905060405160208183030381529060405280519060200120613709565b90505b949350505050565b6110c982826040518060200160405280600081525061371f565b6000806129f9836040516020016129e59190614b5b565b60405160208183030381529060405261388d565b90508051602082016000f091506001600160a01b038216612a2d5760405163046a55db60e11b815260040160405180910390fd5b50919050565b60008181526019602052604081205460609160f082901b9161ffff169003612a5c5750600160f81b5b60408051600e808252818301909252600091602082018180368337019050509050604d60f81b81600081518110612a9557612a95614682565b60200101906001600160f81b031916908160001a905350605460f81b81600181518110612ac457612ac4614682565b60200101906001600160f81b031916908160001a905350606860f81b81600281518110612af357612af3614682565b60200101906001600160f81b031916908160001a905350606460f81b81600381518110612b2257612b22614682565b60200101906001600160f81b031916908160001a905350600060f81b81600481518110612b5157612b51614682565b60200101906001600160f81b031916908160001a905350600060f81b81600581518110612b8057612b80614682565b60200101906001600160f81b031916908160001a905350600060f81b81600681518110612baf57612baf614682565b60200101906001600160f81b031916908160001a905350600660f81b81600781518110612bde57612bde614682565b60200101906001600160f81b031916908160001a905350600060f81b81600881518110612c0d57612c0d614682565b60200101906001600160f81b031916908160001a9053508460ff16600103612c6357600060f81b81600981518110612c4757612c47614682565b60200101906001600160f81b031916908160001a905350612c93565b600160f81b81600981518110612c7b57612c7b614682565b60200101906001600160f81b031916908160001a9053505b600060f81b81600a81518110612cab57612cab614682565b60200101906001600160f81b031916908160001a9053508460f81b81600b81518110612cd957612cd9614682565b60200101906001600160f81b031916908160001a9053508160001a60f81b81600c81518110612d0a57612d0a614682565b60200101906001600160f81b031916908160001a9053508160011a60f81b81600d81518110612d3b57612d3b614682565b60200101906001600160f81b031916908160001a905350949350505050565b6060610b828260016000196138a3565b60408051600880825281830190925260609160009190602082018180368337019050509050604d60f81b81600081518110612da757612da7614682565b60200101906001600160f81b031916908160001a905350605460f81b81600181518110612dd657612dd6614682565b60200101906001600160f81b031916908160001a905350607260f81b81600281518110612e0557612e05614682565b60200101906001600160f81b031916908160001a905350606b60f81b81600381518110612e3457612e34614682565b60200101906001600160f81b031916908160001a90535060008351604051602001612e6191815260200190565b60405160208183030381529060405290508060048251612e8191906146b1565b81518110612e9157612e91614682565b602001015160f81c60f81b82600481518110612eaf57612eaf614682565b60200101906001600160f81b031916908160001a9053508060038251612ed591906146b1565b81518110612ee557612ee5614682565b602001015160f81c60f81b82600581518110612f0357612f03614682565b60200101906001600160f81b031916908160001a9053508060028251612f2991906146b1565b81518110612f3957612f39614682565b602001015160f81c60f81b82600681518110612f5757612f57614682565b60200101906001600160f81b031916908160001a9053508060018251612f7d91906146b1565b81518110612f8d57612f8d614682565b602001015160f81c60f81b82600781518110612fab57612fab614682565b60200101906001600160f81b031916908160001a9053508184604051602001612fd59291906146de565b60405160208183030381529060405292505050919050565b80516060906000819003613011575050604080516020810190915260008152919050565b600060036130208360026145fc565b61302a919061466e565b6130359060046145dd565b905060006130448260206145fc565b6001600160401b0381111561305b5761305b613f02565b6040519080825280601f01601f191660200182016040528015613085576020820181803683370190505b5090506000604051806060016040528060408152602001614c4e604091399050600181016020830160005b86811015613111576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016130b0565b50600386066001811461312b576002811461313c57613148565b613d3d60f01b600119830152613148565b603d60f81b6000198301525b505050918152949350505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60646001600160601b03821611156132155760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610d5a565b6001600160a01b03821661326b5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610d5a565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906132d9903390899088908890600401614b81565b6020604051808303816000875af1925050508015613314575060408051601f3d908101601f1916820190925261331191810190614bb4565b60015b613372573d808015613342576040519150601f19603f3d011682016040523d82523d6000602084013e613347565b606091505b50805160000361336a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506129ac565b6060816000036133b35750506040805180820190915260018152600360fc1b602082015290565b8160005b81156133dd57806133c781614698565b91506133d69050600a8361466e565b91506133b7565b6000816001600160401b038111156133f7576133f7613f02565b6040519080825280601f01601f191660200182016040528015613421576020820181803683370190505b5090505b84156129ac576134366001836146b1565b9150613443600a86614bd1565b61344e9060306145fc565b60f81b81838151811061346357613463614682565b60200101906001600160f81b031916908160001a905350613485600a8661466e565b9450613425565b6060816000036134b65750506040805180820190915260048152630307830360e41b602082015290565b8160005b81156134d957806134ca81614698565b915050600882901c91506134ba565b6129ac8482613958565b6060816134f181601f6145fc565b10156135305760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610d5a565b61353a82846145fc565b8451101561357e5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610d5a565b60608215801561359d57604051915060008252602082016040526135e7565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156135d65780518352602092830192016135be565b5050858452601f01601f1916604052505b50949350505050565b804710156136405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610d5a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461368d576040519150601f19603f3d011682016040523d82523d6000602084013e613692565b606091505b5050905080610e415760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610d5a565b6000826137168584613af3565b14949350505050565b6000548360000361374257604051622e076360e81b815260040160405180910390fd5b826000036137635760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03841660008181526005602090815260408083208054680100000000000000018902019055848352600490915290204260a01b86176001861460e11b1790558190818501903b15613838575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461380160008784806001019550876132a4565b61381e576040516368d2bf6b60e11b815260040160405180910390fd5b8082106137b657826000541461383357600080fd5b61387d565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210613839575b50600090815561118e9085838684565b6060815182604051602001611f00929190614be5565b6060833b60008190036138c6575050604080516020810190915260008152612752565b808411156138e4575050604080516020810190915260008152612752565b838310156139165760405163162544fd60e11b8152600481018290526024810185905260448101849052606401610d5a565b838303848203600082821061392b578261392d565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b606060006139678360026145dd565b6139729060026145fc565b6001600160401b0381111561398957613989613f02565b6040519080825280601f01601f1916602001820160405280156139b3576020820181803683370190505b509050600360fc1b816000815181106139ce576139ce614682565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106139fd576139fd614682565b60200101906001600160f81b031916908160001a9053506000613a218460026145dd565b613a2c9060016145fc565b90505b6001811115613aa4576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a6057613a60614682565b1a60f81b828281518110613a7657613a76614682565b60200101906001600160f81b031916908160001a90535060049490941c93613a9d81614c36565b9050613a2f565b5083156127525760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d5a565b600081815b8451811015613b5f576000858281518110613b1557613b15614682565b60200260200101519050808311613b3b5760008381526020829052604090209250613b4c565b600081815260208490526040902092505b5080613b5781614698565b915050613af8565b509392505050565b5080546000825590600052602060002090810190610d7a9190613c7d565b828054613b91906144c9565b90600052602060002090601f016020900481019282613bb35760008555613bf9565b82601f10613bcc57805160ff1916838001178555613bf9565b82800160010185558215613bf9579182015b82811115613bf9578251825591602001919060010190613bde565b50613c05929150613c7d565b5090565b828054613c15906144c9565b90600052602060002090601f016020900481019282613c375760008555613bf9565b82601f10613c505782800160ff19823516178555613bf9565b82800160010185558215613bf9579182015b82811115613bf9578235825591602001919060010190613c62565b5b80821115613c055760008155600101613c7e565b6001600160e01b031981168114610d7a57600080fd5b600060208284031215613cba57600080fd5b813561275281613c92565b60005b83811015613ce0578181015183820152602001613cc8565b8381111561118e5750506000910152565b60008151808452613d09816020860160208601613cc5565b601f01601f19169290920160200192915050565b6020815260006127526020830184613cf1565b600060208284031215613d4257600080fd5b5035919050565b6001600160a01b0381168114610d7a57600080fd5b60008060408385031215613d7157600080fd5b8235613d7c81613d49565b946020939093013593505050565b803560ff81168114613d9b57600080fd5b919050565b60008060008060008060c08789031215613db957600080fd5b863561ffff81168114613dcb57600080fd5b9550613dd960208801613d8a565b9450613de760408801613d8a565b9350613df560608801613d8a565b9250613e0360808801613d8a565b9150613e1160a08801613d8a565b90509295509295509295565b600080600060608486031215613e3257600080fd5b8335613e3d81613d49565b92506020840135613e4d81613d49565b929592945050506040919091013590565b60008060008060608587031215613e7457600080fd5b843593506020850135925060408501356001600160401b0380821115613e9957600080fd5b818701915087601f830112613ead57600080fd5b813581811115613ebc57600080fd5b8860208260051b8501011115613ed157600080fd5b95989497505060200194505050565b60008060408385031215613ef357600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f4057613f40613f02565b604052919050565b600082601f830112613f5957600080fd5b81356001600160401b03811115613f7257613f72613f02565b613f85601f8201601f1916602001613f18565b818152846020838601011115613f9a57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613fc957600080fd5b81356001600160401b03811115613fdf57600080fd5b6129ac84828501613f48565b60006001600160401b0382111561400457614004613f02565b5060051b60200190565b600082601f83011261401f57600080fd5b8135602061403461402f83613feb565b613f18565b82815260059290921b8401810191818101908684111561405357600080fd5b8286015b848110156140925780356001600160401b038111156140765760008081fd5b6140848986838b0101613f48565b845250918301918301614057565b509695505050505050565b6000806000606084860312156140b257600080fd5b833592506020808501356001600160401b03808211156140d157600080fd5b818701915087601f8301126140e557600080fd5b81356140f361402f82613feb565b81815260059190911b8301840190848101908a83111561411257600080fd5b938501935b8285101561413057843582529385019390850190614117565b96505050604087013592508083111561414857600080fd5b50506141568682870161400e565b9150509250925092565b6000806040838503121561417357600080fd5b82356001600160401b038082111561418a57600080fd5b818501915085601f83011261419e57600080fd5b813560206141ae61402f83613feb565b82815260059290921b840181019181810190898411156141cd57600080fd5b948201945b838610156141eb578535825294820194908201906141d2565b9650508601359250508082111561420157600080fd5b5061420e8582860161400e565b9150509250929050565b60008083601f84011261422a57600080fd5b5081356001600160401b0381111561424157600080fd5b60208301915083602082850101111561108557600080fd5b6000806000806000806080878903121561427257600080fd5b863595506020870135945060408701356001600160401b038082111561429757600080fd5b6142a38a838b01614218565b909650945060608901359150808211156142bc57600080fd5b506142c989828a01614218565b979a9699509497509295939492505050565b6000602082840312156142ed57600080fd5b813561275281613d49565b602081016004831061431a57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561433257600080fd5b81356001600160601b038116811461275257600080fd5b6000806040838503121561435c57600080fd5b823561436781613d49565b91506020830135801515811461437c57600080fd5b809150509250929050565b6000806000806080858703121561439d57600080fd5b84356143a881613d49565b935060208501356143b881613d49565b92506040850135915060608501356001600160401b038111156143da57600080fd5b6143e687828801613f48565b91505092959194509250565b60008060006060848603121561440757600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561443157600080fd5b8235915060208301356001600160f01b03198116811461437c57600080fd5b6000806040838503121561446357600080fd5b823561446e81613d49565b9150602083013561437c81613d49565b60008060006040848603121561449357600080fd5b8335925060208401356001600160401b038111156144b057600080fd5b6144bc86828701614218565b9497909650939450505050565b600181811c908216806144dd57607f821691505b602082108103612a2d57634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b61ffff96909616865260ff948516602087015292841660408601529083166060850152821660808401521660a082015260c00190565b60006020828403121561457a57600080fd5b5051919050565b60208082526026908201527f4d697865645374656d735f56315f313a204f7065726174696f6e526571756972604082015265657354696d6560d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156145f7576145f76145c7565b500290565b6000821982111561460f5761460f6145c7565b500190565b60208082526024908201527f4d697865645374656d735f56315f313a204d696e74696e674c696d697452656160408201526318da195960e21b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261467d5761467d614658565b500490565b634e487b7160e01b600052603260045260246000fd5b6000600182016146aa576146aa6145c7565b5060010190565b6000828210156146c3576146c36145c7565b500390565b634e487b7160e01b600052603160045260246000fd5b600083516146f0818460208801613cc5565b835190830190614704818360208801613cc5565b01949350505050565b8054600090600181811c908083168061472757607f831692505b6020808410820361474857634e487b7160e01b600052602260045260246000fd5b81801561475c576001811461476d5761479a565b60ff1986168952848901965061479a565b60008881526020902060005b868110156147925781548b820152908501908301614779565b505084890196505b50505050505092915050565b60006147b2828561470d565b8351614704818360208801613cc5565b683d913730b6b2911d1160b91b815260006147e0600983018a61470d565b61202360f01b815288516147fb816002840160208d01613cc5565b72111610113232b9b1b934b83a34b7b7111d101160691b60029290910191820152614829601582018961470d565b6c1116101134b6b0b3b2911d101160991b8152905061484b600d82018861470d565b9050662f696d6167652f60c81b8152855161486d816007840160208a01613cc5565b741116101130b734b6b0ba34b7b72fbab936111d101160591b6007929091019182015261489d601c82018661470d565b90506a2f616e696d6174696f6e2f60a81b815283516148c381600b840160208801613cc5565b01600b019998505050505050505050565b600085516148e6818460208a01613cc5565b80830190507f222c20226d696469223a2022646174613a617564696f2f6d6964693b626173658152620d8d0b60ea1b6020820152855161492d816023840160208a01613cc5565b7f222c202265787465726e616c5f75726c223a202268747470733a2f2f62656174602392909101918201527f666f756e6472792e78797a222c2022636f6d706f736572223a20220000000000604382015261498b605e82018661470d565b7f222c202261747472696275746573223a205b7b2274726169745f74797065223a815272101129b7b733911610113b30b63ab2911d101160691b602082015290506149d9603382018561470d565b61227d60f01b8152600201979650505050505050565b60008351614a01818460208801613cc5565b7f2c207b2274726169745f74797065223a2022436f76657220417274222c2022769083019081526730b63ab2911d101160c11b6020820152614a46602882018561470d565b61227d60f01b815260020195945050505050565b60008451614a6c818460208901613cc5565b7116103d913a3930b4ba2fba3cb832911d101160711b908301908152614a95601282018661470d565b6c111610113b30b63ab2911d101160991b81529050614ab7600d82018561470d565b61227d60f01b81526002019695505050505050565b60008251614ade818460208701613cc5565b615d7d60f01b920191825250600201919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614b2a81601d850160208701613cc5565b91909101601d0192915050565b80516020808301519190811015612a2d5760001960209190910360031b1b16919050565b6000815260008251614b74816001850160208701613cc5565b9190910160010192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061165890830184613cf1565b600060208284031215614bc657600080fd5b815161275281613c92565b600082614be057614be0614658565b500690565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090614c2881600e850160208701613cc5565b91909101600e019392505050565b600081614c4557614c456145c7565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212209cbe21c883e6318f07eccb9ede9f2701283e048b7aedf3153e210b1a452f377a64736f6c634300080d003360806040523480156200001157600080fd5b5060405162001a3b38038062001a3b8339810160408190526200003491620005aa565b82828051825114620000a85760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b6000825111620000fb5760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f2070617965657300000000000060448201526064016200009f565b60005b82518110156200016757620001528382815181106200012157620001216200068c565b60200260200101518383815181106200013e576200013e6200068c565b60200260200101516200019860201b60201c565b806200015e81620006b8565b915050620000fe565b505050620001846200017e6200038460201b60201c565b62000388565b6200018f81620003da565b505050620006ef565b6001600160a01b038216620002055760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b60648201526084016200009f565b60008111620002575760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a2073686172657320617265203000000060448201526064016200009f565b6001600160a01b03821660009081526002602052604090205415620002d35760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b60648201526084016200009f565b60048054600181019091557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091556000908152600260205260408120829055546200033b908290620006d4565b600055604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b3390565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6007546001600160a01b03163314620004365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200009f565b6001600160a01b0381166200049d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200009f565b620004a88162000388565b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004ec57620004ec620004ab565b604052919050565b60006001600160401b03821115620005105762000510620004ab565b5060051b60200190565b80516001600160a01b03811681146200053257600080fd5b919050565b600082601f8301126200054957600080fd5b81516020620005626200055c83620004f4565b620004c1565b82815260059290921b840181019181810190868411156200058257600080fd5b8286015b848110156200059f578051835291830191830162000586565b509695505050505050565b600080600060608486031215620005c057600080fd5b83516001600160401b0380821115620005d857600080fd5b818601915086601f830112620005ed57600080fd5b81516020620006006200055c83620004f4565b82815260059290921b8401810191818101908a8411156200062057600080fd5b948201945b83861015620006495762000639866200051a565b8252948201949082019062000625565b918901519197509093505050808211156200066357600080fd5b50620006728682870162000537565b92505062000683604085016200051a565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620006cd57620006cd620006a2565b5060010190565b60008219821115620006ea57620006ea620006a2565b500190565b61133c80620006ff6000396000f3fe6080604052600436106100ec5760003560e01c80638b83209b1161008a578063ce7c2ac211610059578063ce7c2ac2146102e7578063d79779b21461031d578063e33b7de314610353578063f2fde38b1461036857600080fd5b80638b83209b1461023b5780638da5cb5b146102735780639852595c14610291578063b4047692146102c757600080fd5b80633a98ef39116100c65780633a98ef391461019c578063406072a9146101c057806348b7504414610206578063715018a61461022657600080fd5b806308bf2d601461013a57806318f9b0231461015c578063191655871461017c57600080fd5b36610135577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561014657600080fd5b5061015a610155366004611002565b610388565b005b34801561016857600080fd5b5061015a610177366004611039565b6103c9565b34801561018857600080fd5b5061015a610197366004611065565b6103fd565b3480156101a857600080fd5b506000545b6040519081526020015b60405180910390f35b3480156101cc57600080fd5b506101ad6101db366004611082565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b34801561021257600080fd5b5061015a610221366004611082565b61052e565b34801561023257600080fd5b5061015a61070a565b34801561024757600080fd5b5061025b6102563660046110bb565b610740565b6040516001600160a01b0390911681526020016101b7565b34801561027f57600080fd5b506007546001600160a01b031661025b565b34801561029d57600080fd5b506101ad6102ac366004611065565b6001600160a01b031660009081526003602052604090205490565b3480156102d357600080fd5b5061015a6102e23660046110bb565b610770565b3480156102f357600080fd5b506101ad610302366004611065565b6001600160a01b031660009081526002602052604090205490565b34801561032957600080fd5b506101ad610338366004611065565b6001600160a01b031660009081526005602052604090205490565b34801561035f57600080fd5b506001546101ad565b34801561037457600080fd5b5061015a610383366004611065565b6107a6565b6007546001600160a01b031633146103bb5760405162461bcd60e51b81526004016103b2906110d4565b60405180910390fd5b6103c5828261083e565b5050565b6007546001600160a01b031633146103f35760405162461bcd60e51b81526004016103b2906110d4565b6103c58282610913565b6001600160a01b0381166000908152600260205260409020546104325760405162461bcd60e51b81526004016103b290611109565b600061043d60015490565b6104479047611165565b90506000610474838361046f866001600160a01b031660009081526003602052604090205490565b610af7565b9050806000036104965760405162461bcd60e51b81526004016103b29061117d565b6001600160a01b038316600090815260036020526040812080548392906104be908490611165565b9250508190555080600160008282546104d79190611165565b909155506104e790508382610b3c565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b6001600160a01b0381166000908152600260205260409020546105635760405162461bcd60e51b81526004016103b290611109565b6001600160a01b0382166000908152600560205260408120546040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156105c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e491906111c8565b6105ee9190611165565b90506000610627838361046f87876001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b9050806000036106495760405162461bcd60e51b81526004016103b29061117d565b6001600160a01b03808516600090815260066020908152604080832093871683529290529081208054839290610680908490611165565b90915550506001600160a01b038416600090815260056020526040812080548392906106ad908490611165565b909155506106be9050848483610c5a565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6007546001600160a01b031633146107345760405162461bcd60e51b81526004016103b2906110d4565b61073e6000610cac565b565b600060048281548110610755576107556111e1565b6000918252602090912001546001600160a01b031692915050565b6007546001600160a01b0316331461079a5760405162461bcd60e51b81526004016103b2906110d4565b6107a381610cfe565b50565b6007546001600160a01b031633146107d05760405162461bcd60e51b81526004016103b2906110d4565b6001600160a01b0381166108355760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b2565b6107a381610cac565b6000811161088e5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a2073686172657320617265203000000060448201526064016103b2565b60006002600061089d85610740565b6001600160a01b03166001600160a01b0316815260200190815260200160002054905081600260006108ce86610740565b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550818160005461090191906111f7565b61090b9190611165565b600055505050565b6001600160a01b03821661097e5760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b60648201526084016103b2565b600081116109ce5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a2073686172657320617265203000000060448201526064016103b2565b6001600160a01b03821660009081526002602052604090205415610a485760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b60648201526084016103b2565b60048054600181019091557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b038416908117909155600090815260026020526040812082905554610aae908290611165565b600055604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b600080546001600160a01b038516825260026020526040822054839190610b1e908661120e565b610b28919061122d565b610b3291906111f7565b90505b9392505050565b80471015610b8c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016103b2565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610bd9576040519150601f19603f3d011682016040523d82523d6000602084013e610bde565b606091505b5050905080610c555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016103b2565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c55908490610e1c565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060026000610d0d84610740565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050600060026000610d3f85610740565b6001600160a01b0316815260208101919091526040016000205560048054610d69906001906111f7565b81548110610d7957610d796111e1565b600091825260209091200154600480546001600160a01b039092169184908110610da557610da56111e1565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480610de457610de461124f565b600082815260208120820160001990810180546001600160a01b031916905590910190915554610e159082906111f7565b6000555050565b6000610e71826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610eee9092919063ffffffff16565b805190915015610c555780806020019051810190610e8f9190611265565b610c555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103b2565b6060610b328484600085856001600160a01b0385163b610f505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103b2565b600080866001600160a01b03168587604051610f6c91906112b7565b60006040518083038185875af1925050503d8060008114610fa9576040519150601f19603f3d011682016040523d82523d6000602084013e610fae565b606091505b5091509150610fbe828286610fc9565b979650505050505050565b60608315610fd8575081610b35565b825115610fe85782518084602001fd5b8160405162461bcd60e51b81526004016103b291906112d3565b6000806040838503121561101557600080fd5b50508035926020909101359150565b6001600160a01b03811681146107a357600080fd5b6000806040838503121561104c57600080fd5b823561105781611024565b946020939093013593505050565b60006020828403121561107757600080fd5b8135610b3581611024565b6000806040838503121561109557600080fd5b82356110a081611024565b915060208301356110b081611024565b809150509250929050565b6000602082840312156110cd57600080fd5b5035919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082198211156111785761117861114f565b500190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b6000602082840312156111da57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000828210156112095761120961114f565b500390565b60008160001904831182151516156112285761122861114f565b500290565b60008261124a57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603160045260246000fd5b60006020828403121561127757600080fd5b81518015158114610b3557600080fd5b60005b838110156112a257818101518382015260200161128a565b838111156112b1576000848401525b50505050565b600082516112c9818460208701611287565b9190910192915050565b60208152600082518060208401526112f2816040850160208701611287565b601f01601f1916919091016040019291505056fea264697066735822122048f242caf7b01229c96339e2a2d210e23f58499c5d8dab7cdb45c5295f7937ef64736f6c634300080d00330000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008436f6c6c616765730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007436f6c6c616765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071436f6c6c61676573206f662076696e746167652c20656c656374726f6e69632062656174732074686174206f7665726c617020746f206372656174652067656e6572617469766520736f6e6773206f6e2d636861696e2e20436f6d706f7365642062792044616e69656c20416c6c616e2e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003434c470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c44616e69656c20416c6c616e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000b7327099300682e0b5562e3be7ce226e6f17f5000000000000000000000000eb57180709ea54d1e33be87d238000dafe0413200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000046

Deployed Bytecode

0x6080604052600436106103ad5760003560e01c806374e1ee41116101e7578063bdcea4bc1161010d578063e0d4ea37116100a0578063f3fef3a31161006f578063f3fef3a314610ae8578063f4a0a52814610b08578063f95df41414610b28578063faff57d114610b4857600080fd5b8063e0d4ea3714610a3f578063e985e9c514610a5f578063ef14817714610aa8578063f2fde38b14610ac857600080fd5b8063d4e55d3c116100dc578063d4e55d3c146109d4578063d5abeb01146109f4578063d62280b214610a0a578063db6242c314610a1f57600080fd5b8063bdcea4bc1461095e578063c87b56dd1461097e578063ca3bd3251461099e578063d3cf00a3146109be57600080fd5b80639f6d68b011610185578063aeb1fe5111610154578063aeb1fe51146108f3578063b09e44fa14610908578063b79697f81461091e578063b88d4fde1461093e57600080fd5b80639f6d68b014610880578063a0712d68146108a0578063a22cb465146108b3578063a3114cde146108d357600080fd5b80638da5cb5b116101c15780638da5cb5b1461080d5780638e825be01461082b57806390c3f38f1461084b57806395d89b411461086b57600080fd5b806374e1ee41146107ab5780637ad63f18146107cb5780637e5ac09a146107eb57600080fd5b80633d241e6a116102d757806367a44c641161026a5780636f8b44b0116102395780636f8b44b01461074157806370a0823114610761578063715018a6146107815780637284e4161461079657600080fd5b806367a44c64146106e05780636817c76c146107005780636c0360eb146107165780636cf3884d1461072b57600080fd5b8063507e094f116102a6578063507e094f1461066a578063521993e31461068057806355f804b3146106a05780636352211e146106c057600080fd5b80633d241e6a146105e257806342842e0e1461060257806345657735146106225780634e926bc91461064257600080fd5b80631cb4ffb21161034f5780632a55205a1161031e5780632a55205a146105435780632a85db55146105825780632c7a6dc7146105a257806333ba01a1146105c257600080fd5b80631cb4ffb2146104da57806323b872dd146104fa5780632792e5e81461051a5780632992cd641461053057600080fd5b8063095ea7b31161038b578063095ea7b3146104415780631663ee031461046357806318160ddd146104975780631a62ae32146104ba57600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613ca8565b610b68565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610b88565b6040516103de9190613d1d565b34801561041557600080fd5b50610429610424366004613d30565b610c1a565b6040516001600160a01b0390911681526020016103de565b34801561044d57600080fd5b5061046161045c366004613d5e565b610c5e565b005b34801561046f57600080fd5b506104297f00000000000000000000000074440865f1a1eccd9fa91cef62f32a4465fa59e881565b3480156104a357600080fd5b50600154600054035b6040519081526020016103de565b3480156104c657600080fd5b506104616104d5366004613d30565b610d30565b3480156104e657600080fd5b506104616104f5366004613da0565b610d7d565b34801561050657600080fd5b50610461610515366004613e1d565b610e36565b34801561052657600080fd5b506104ac600b5481565b61046161053e366004613e5e565b610e46565b34801561054f57600080fd5b5061056361055e366004613ee0565b610fdf565b604080516001600160a01b0390931683526020830191909152016103de565b34801561058e57600080fd5b5061046161059d366004613fb7565b61108c565b3480156105ae57600080fd5b506104616105bd36600461409d565b6110cd565b3480156105ce57600080fd5b506104616105dd366004614160565b611194565b3480156105ee57600080fd5b506104616105fd366004614259565b611244565b34801561060e57600080fd5b5061046161061d366004613e1d565b611322565b34801561062e57600080fd5b5061046161063d366004613ee0565b61133d565b34801561064e57600080fd5b50610429731a6184cd4c5bea62b0116de7962ee7315b7bcbce81565b34801561067657600080fd5b506104ac60135481565b34801561068c57600080fd5b5061046161069b366004613fb7565b61143a565b3480156106ac57600080fd5b506104616106bb366004613fb7565b611477565b3480156106cc57600080fd5b506104296106db366004613d30565b6114b4565b3480156106ec57600080fd5b506103fc6106fb366004613d30565b6114bf565b34801561070c57600080fd5b506104ac60115481565b34801561072257600080fd5b506103fc611662565b34801561073757600080fd5b506104ac60105481565b34801561074d57600080fd5b5061046161075c366004613d30565b6116f0565b34801561076d57600080fd5b506104ac61077c3660046142db565b61171f565b34801561078d57600080fd5b50610461611767565b3480156107a257600080fd5b506103fc61179d565b3480156107b757600080fd5b506104ac6107c6366004613d30565b6117aa565b3480156107d757600080fd5b506104616107e6366004613da0565b611850565b3480156107f757600080fd5b50610800611909565b6040516103de91906142f8565b34801561081957600080fd5b50600a546001600160a01b0316610429565b34801561083757600080fd5b50610461610846366004613d5e565b611941565b34801561085757600080fd5b50610461610866366004613fb7565b6119d8565b34801561087757600080fd5b506103fc611a15565b34801561088c57600080fd5b5061046161089b366004614320565b611a24565b6104616108ae366004613d30565b611a78565b3480156108bf57600080fd5b506104616108ce366004614349565b611bab565b3480156108df57600080fd5b506104616108ee36600461409d565b611c40565b3480156108ff57600080fd5b506103fc611d01565b34801561091457600080fd5b506104ac600d5481565b34801561092a57600080fd5b50610461610939366004613fb7565b611d0e565b34801561094a57600080fd5b50610461610959366004614387565b611d4b565b34801561096a57600080fd5b506104616109793660046143f2565b611d8f565b34801561098a57600080fd5b506103fc610999366004613d30565b611ea6565b3480156109aa57600080fd5b506104616109b936600461441e565b612115565b3480156109ca57600080fd5b506104ac600c5481565b3480156109e057600080fd5b506104616109ef366004613da0565b612163565b348015610a0057600080fd5b506104ac60125481565b348015610a1657600080fd5b506103fc61221c565b348015610a2b57600080fd5b50610461610a3a366004613d30565b612229565b348015610a4b57600080fd5b506104ac610a5a366004613d30565b612258565b348015610a6b57600080fd5b506103d2610a7a366004614450565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610ab457600080fd5b50610461610ac3366004613ee0565b6123ab565b348015610ad457600080fd5b50610461610ae33660046142db565b6123f7565b348015610af457600080fd5b50610461610b03366004613d5e565b61248f565b348015610b1457600080fd5b50610461610b23366004613d30565b612550565b348015610b3457600080fd5b50610461610b43366004613d30565b61257f565b348015610b5457600080fd5b50610461610b6336600461447e565b6125ae565b6000610b738261265c565b80610b825750610b82826126aa565b92915050565b606060028054610b97906144c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc3906144c9565b8015610c105780601f10610be557610100808354040283529160200191610c10565b820191906000526020600020905b815481529060010190602001808311610bf357829003601f168201915b5050505050905090565b6000610c25826126df565b610c42576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610c6982612706565b9050806001600160a01b0316836001600160a01b031603610c9d5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610cd457610cb78133610a7a565b610cd4576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600a546001600160a01b03163314610d635760405162461bcd60e51b8152600401610d5a906144fd565b60405180910390fd5b6000818152601860205260408120610d7a91613b67565b50565b600a546001600160a01b03163314610da75760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec90610de890899089908990899089908990600401614532565b6020604051808303816000875af1158015610e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2b9190614568565b600b55505050505050565b610e41838383612774565b505050565b600b548042118015610e585750600081115b610e745760405162461bcd60e51b8152600401610d5a90614581565b84601154610e8291906145dd565b803414610ed15760405162461bcd60e51b815260206004820152601b60248201527f4d697865645374656d735f56315f313a2057726f6e67507269636500000000006044820152606401610d5a565b60125486610ede60005490565b610ee891906145fc565b1115610f065760405162461bcd60e51b8152600401610d5a90614614565b8486610f113361171f565b610f1b91906145fc565b1115610f755760405162461bcd60e51b815260206004820152602360248201527f4d697865645374656d735f56315f313a20416c6c6f636174696f6e457863656560448201526219195960ea1b6064820152608401610d5a565b610f813386868661292a565b610fcd5760405162461bcd60e51b815260206004820152601f60248201527f4d697865645374656d735f56315f313a204e6f74416c6c6f776c6973746564006044820152606401610d5a565b610fd733876129b4565b505050505050565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916110545750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090606490611072906001600160601b0316876145dd565b61107c919061466e565b91519350909150505b9250929050565b600a546001600160a01b031633146110b65760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990600f906020840190613b85565b5050565b600a546001600160a01b031633146110f75760405162461bcd60e51b8152600401610d5a906144fd565b805182511461110557600080fd5b60005b815181101561118e5781818151811061112357611123614682565b6020026020010151601c6000868152602001908152602001600020600085848151811061115257611152614682565b60200260200101518152602001908152602001600020908051906020019061117b929190613b85565b508061118681614698565b915050611108565b50505050565b600a546001600160a01b031633146111be5760405162461bcd60e51b8152600401610d5a906144fd565b80518251146111cc57600080fd5b60005b8151811015610e41578181815181106111ea576111ea614682565b6020026020010151601a600085848151811061120857611208614682565b602002602001015181526020019081526020016000209080519060200190611231929190613b85565b508061123c81614698565b9150506111cf565b600a546001600160a01b0316331461126e5760405162461bcd60e51b8152600401610d5a906144fd565b601054851061127c57600080fd5b60006112bd85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129ce92505050565b60008881526017602090815260408083208a8452825280832080546001810182559084528284200180546001600160a01b0319166001600160a01b0386169081179091558352601d9091529020909150611318908484613c09565b5050505050505050565b610e4183838360405180602001604052806000815250611d4b565b600a546001600160a01b031633146113675760405162461bcd60e51b8152600401610d5a906144fd565b60008281526018602052604090208054611383906001906146b1565b8154811061139357611393614682565b60009182526020808320909101548483526018909152604090912080546001600160a01b0390921691839081106113cc576113cc614682565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255838152601890915260409020805480611414576114146146c8565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b600a546001600160a01b031633146114645760405162461bcd60e51b8152600401610d5a906144fd565b80516110c9906014906020840190613b85565b600a546001600160a01b031633146114a15760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990600e906020840190613b85565b6000610b8282612706565b60606114ca826126df565b6114e757604051630a14c4b560e41b815260040160405180910390fd5b60006114f283612258565b9050600081811a600081815260186020526040812054601054929350916115239061151d90846145fc565b84612a33565b905060005b6010548110156115db5760008481526017602090815260408083208484529091528120611599908761155b8560016145fc565b6020811061156b5761156b614682565b825491901a90811061157f5761157f614682565b6000918252602090912001546001600160a01b0316612d5a565b9050826115a582612d6a565b6040516020016115b69291906146de565b60405160208183030381529060405292505080806115d390614698565b915050611528565b5060005b8281101561164e576000848152601860205260408120805461160c91908490811061157f5761157f614682565b90508261161882612d6a565b6040516020016116299291906146de565b604051602081830303815290604052925050808061164690614698565b9150506115df565b5061165881612fed565b9695505050505050565b600e805461166f906144c9565b80601f016020809104026020016040519081016040528092919081815260200182805461169b906144c9565b80156116e85780601f106116bd576101008083540402835291602001916116e8565b820191906000526020600020905b8154815290600101906020018083116116cb57829003601f168201915b505050505081565b600a546001600160a01b0316331461171a5760405162461bcd60e51b8152600401610d5a906144fd565b601255565b600081600003611742576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b600a546001600160a01b031633146117915760405162461bcd60e51b8152600401610d5a906144fd565b61179b6000613156565b565b6016805461166f906144c9565b60006117b5826126df565b6117d257604051630a14c4b560e41b815260040160405180910390fd5b601e60105460016117e391906145fc565b6010546117f19060026145fc565b6117fb90856145dd565b61180591906145fc565b8154611810906144c9565b811061181e5761181e614682565b81546001161561183d5790600052602060002090602091828204019190065b9054600160f81b911a0260f81c92915050565b600a546001600160a01b0316331461187a5760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec906118bb90899089908990899089908990600401614532565b6020604051808303816000875af11580156118da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fe9190614568565b600c55505050505050565b6000600d5442111561191b5750600390565b600c5442111561192b5750600290565b600b5442111561193b5750600190565b50600090565b600d5480421180156119535750600081115b61196f5760405162461bcd60e51b8152600401610d5a90614581565b600a546001600160a01b031633146119995760405162461bcd60e51b8152600401610d5a906144fd565b601254826119a660005490565b6119b091906145fc565b11156119ce5760405162461bcd60e51b8152600401610d5a90614614565b610e4183836129b4565b600a546001600160a01b03163314611a025760405162461bcd60e51b8152600401610d5a906144fd565b80516110c9906016906020840190613b85565b606060038054610b97906144c9565b600a546001600160a01b03163314611a4e5760405162461bcd60e51b8152600401610d5a906144fd565b610d7a7f00000000000000000000000074440865f1a1eccd9fa91cef62f32a4465fa59e8826131a8565b600c548042118015611a8a5750600081115b611aa65760405162461bcd60e51b8152600401610d5a90614581565b81601154611ab491906145dd565b803414611b035760405162461bcd60e51b815260206004820152601b60248201527f4d697865645374656d735f56315f313a2057726f6e67507269636500000000006044820152606401610d5a565b60125483611b1060005490565b611b1a91906145fc565b1115611b385760405162461bcd60e51b8152600401610d5a90614614565b601354831115611ba15760405162461bcd60e51b815260206004820152602e60248201527f4d697865645374656d735f56315f313a20416d6f756e7447726561746572546860448201526d0c2dc9ac2f09ad2dce8a0cae4a8f60931b6064820152608401610d5a565b610e4133846129b4565b336001600160a01b03831603611bd45760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b03163314611c6a5760405162461bcd60e51b8152600401610d5a906144fd565b8051825114611c7857600080fd5b60005b825181101561118e57818181518110611c9657611c96614682565b6020026020010151601b60008681526020019081526020016000206000858481518110611cc557611cc5614682565b602002602001015181526020019081526020016000209080519060200190611cee929190613b85565b5080611cf981614698565b915050611c7b565b6014805461166f906144c9565b600a546001600160a01b03163314611d385760405162461bcd60e51b8152600401610d5a906144fd565b80516110c990601e906020840190613b85565b611d56848484612774565b6001600160a01b0383163b1561118e57611d72848484846132a4565b61118e576040516368d2bf6b60e11b815260040160405180910390fd5b600a546001600160a01b03163314611db95760405162461bcd60e51b8152600401610d5a906144fd565b600083815260176020908152604080832085845290915290208054611de0906001906146b1565b81548110611df057611df0614682565b6000918252602080832090910154858352601782526040808420868552909252912080546001600160a01b039092169183908110611e3057611e30614682565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925584815260178252604080822085835290925220805480611e7f57611e7f6146c8565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b6060611eb1826126df565b611ece57604051630a14c4b560e41b815260040160405180910390fd5b601e8054611edb906144c9565b9050600003611f1657600f611eef8361338c565b604051602001611f009291906147a6565b6040516020818303038152906040529050919050565b6000611f2183612258565b90506000611f2e846117aa565b9050600082811a90611f3f866114bf565b905060006015611f4e8861338c565b6016600e611f5b8961348c565b600e611f668b61348c565b604051602001611f7c97969594939291906147c2565b60408051601f198184030181528282526000868152601a6020908152929020909350611fb192849286926014929091016148d4565b60408051601f198184030181528282526000868152601b60209081528382208983528152929020909350611fe7928492016149ef565b604051602081830303815290604052905060005b6010548110156120be576000848152601c6020908152604080832084845282528083208784526017835281842085855290925282208492601d918a6120418760016145fc565b6020811061205157612051614682565b825491901a90811061206557612065614682565b60009182526020808320909101546001600160a01b031683528281019390935260409182019020905161209a94939201614a5a565b604051602081830303815290604052915080806120b690614698565b915050611ffb565b50806040516020016120d09190614acc565b60405160208183030381529060405290506120ea81612fed565b6040516020016120fa9190614af2565b60405160208183030381529060405295505050505050919050565b600a546001600160a01b0316331461213f5760405162461bcd60e51b8152600401610d5a906144fd565b600091825260196020526040909120805461ffff191660f09290921c919091179055565b600a546001600160a01b0316331461218d5760405162461bcd60e51b8152600401610d5a906144fd565b6040516324152f7b60e21b8152731a6184cd4c5bea62b0116de7962ee7315b7bcbce90639054bdec906121ce90899089908990899089908990600401614532565b6020604051808303816000875af11580156121ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122119190614568565b600d55505050505050565b600f805461166f906144c9565b600a546001600160a01b031633146122535760405162461bcd60e51b8152600401610d5a906144fd565b601355565b6000612263826126df565b61228057604051630a14c4b560e41b815260040160405180910390fd5b6000601e805461228f906144c9565b9050116122de5760405162461bcd60e51b815260206004820152601860248201527f4d697865645374656d735f56315f313a204e6f536565647300000000000000006044820152606401610d5a565b6123a260105460026122f091906145fc565b6122fa90846145dd565b6010546123089060026145fc565b601e8054612315906144c9565b80601f0160208091040260200160405190810160405280929190818152602001828054612341906144c9565b801561238e5780601f106123635761010080835404028352916020019161238e565b820191906000526020600020905b81548152906001019060200180831161237157829003601f168201915b50505050506134e39092919063ffffffff16565b610b8290614b37565b600a546001600160a01b031633146123d55760405162461bcd60e51b8152600401610d5a906144fd565b600082815260176020908152604080832084845290915281206110c991613b67565b600a546001600160a01b031633146124215760405162461bcd60e51b8152600401610d5a906144fd565b6001600160a01b0381166124865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d5a565b610d7a81613156565b600a546001600160a01b031633146124b95760405162461bcd60e51b8152600401610d5a906144fd565b804710156125155760405162461bcd60e51b8152602060048201526024808201527f4d697865645374656d735f56315f313a20496e73756666696369656e7442616c604482015263616e636560e01b6064820152608401610d5a565b806000036125205750475b6001600160a01b03821661253d57600a546001600160a01b031691505b6110c96001600160a01b038316826135f0565b600a546001600160a01b0316331461257a5760405162461bcd60e51b8152600401610d5a906144fd565b601155565b600a546001600160a01b031633146125a95760405162461bcd60e51b8152600401610d5a906144fd565b601f55565b600a546001600160a01b031633146125d85760405162461bcd60e51b8152600401610d5a906144fd565b600061261983838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129ce92505050565b600094855260186020908152604086208054600181018255908752952090940180546001600160a01b0319166001600160a01b0390951694909417909355505050565b60006301ffc9a760e01b6001600160e01b03198316148061268d57506380ac58cd60e01b6001600160e01b03198316145b80610b825750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b1480610b8257506301ffc9a760e01b6001600160e01b0319831614610b82565b6000805482108015610b82575050600090815260046020526040902054600160e01b161590565b60008160005481101561275b5760008181526004602052604081205490600160e01b82169003612759575b80600003612752575060001901600081815260046020526040902054612731565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600061277f82612706565b9050836001600160a01b0316816001600160a01b0316146127b25760405162a1148160e81b815260040160405180910390fd5b6000828152600660205260408120546001600160a01b03908116919086163314806127e257506127e28633610a7a565b806127f557506001600160a01b03821633145b90508061281557604051632ce44b5f60e11b815260040160405180910390fd5b8460000361283657604051633a954ecd60e21b815260040160405180910390fd5b811561285957600084815260066020526040902080546001600160a01b03191690555b6001600160a01b038681166000908152600560209081526040808320805460001901905592881682528282208054600101905586825260049052908120600160e11b4260a01b88178117909155841690036128e4576001840160008181526004602052604081205490036128e25760005481146128e25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610fd7565b60006129a983838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601f546040516bffffffffffffffffffffffff1960608c901b166020820152603481018a9052909250605401905060405160208183030381529060405280519060200120613709565b90505b949350505050565b6110c982826040518060200160405280600081525061371f565b6000806129f9836040516020016129e59190614b5b565b60405160208183030381529060405261388d565b90508051602082016000f091506001600160a01b038216612a2d5760405163046a55db60e11b815260040160405180910390fd5b50919050565b60008181526019602052604081205460609160f082901b9161ffff169003612a5c5750600160f81b5b60408051600e808252818301909252600091602082018180368337019050509050604d60f81b81600081518110612a9557612a95614682565b60200101906001600160f81b031916908160001a905350605460f81b81600181518110612ac457612ac4614682565b60200101906001600160f81b031916908160001a905350606860f81b81600281518110612af357612af3614682565b60200101906001600160f81b031916908160001a905350606460f81b81600381518110612b2257612b22614682565b60200101906001600160f81b031916908160001a905350600060f81b81600481518110612b5157612b51614682565b60200101906001600160f81b031916908160001a905350600060f81b81600581518110612b8057612b80614682565b60200101906001600160f81b031916908160001a905350600060f81b81600681518110612baf57612baf614682565b60200101906001600160f81b031916908160001a905350600660f81b81600781518110612bde57612bde614682565b60200101906001600160f81b031916908160001a905350600060f81b81600881518110612c0d57612c0d614682565b60200101906001600160f81b031916908160001a9053508460ff16600103612c6357600060f81b81600981518110612c4757612c47614682565b60200101906001600160f81b031916908160001a905350612c93565b600160f81b81600981518110612c7b57612c7b614682565b60200101906001600160f81b031916908160001a9053505b600060f81b81600a81518110612cab57612cab614682565b60200101906001600160f81b031916908160001a9053508460f81b81600b81518110612cd957612cd9614682565b60200101906001600160f81b031916908160001a9053508160001a60f81b81600c81518110612d0a57612d0a614682565b60200101906001600160f81b031916908160001a9053508160011a60f81b81600d81518110612d3b57612d3b614682565b60200101906001600160f81b031916908160001a905350949350505050565b6060610b828260016000196138a3565b60408051600880825281830190925260609160009190602082018180368337019050509050604d60f81b81600081518110612da757612da7614682565b60200101906001600160f81b031916908160001a905350605460f81b81600181518110612dd657612dd6614682565b60200101906001600160f81b031916908160001a905350607260f81b81600281518110612e0557612e05614682565b60200101906001600160f81b031916908160001a905350606b60f81b81600381518110612e3457612e34614682565b60200101906001600160f81b031916908160001a90535060008351604051602001612e6191815260200190565b60405160208183030381529060405290508060048251612e8191906146b1565b81518110612e9157612e91614682565b602001015160f81c60f81b82600481518110612eaf57612eaf614682565b60200101906001600160f81b031916908160001a9053508060038251612ed591906146b1565b81518110612ee557612ee5614682565b602001015160f81c60f81b82600581518110612f0357612f03614682565b60200101906001600160f81b031916908160001a9053508060028251612f2991906146b1565b81518110612f3957612f39614682565b602001015160f81c60f81b82600681518110612f5757612f57614682565b60200101906001600160f81b031916908160001a9053508060018251612f7d91906146b1565b81518110612f8d57612f8d614682565b602001015160f81c60f81b82600781518110612fab57612fab614682565b60200101906001600160f81b031916908160001a9053508184604051602001612fd59291906146de565b60405160208183030381529060405292505050919050565b80516060906000819003613011575050604080516020810190915260008152919050565b600060036130208360026145fc565b61302a919061466e565b6130359060046145dd565b905060006130448260206145fc565b6001600160401b0381111561305b5761305b613f02565b6040519080825280601f01601f191660200182016040528015613085576020820181803683370190505b5090506000604051806060016040528060408152602001614c4e604091399050600181016020830160005b86811015613111576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016130b0565b50600386066001811461312b576002811461313c57613148565b613d3d60f01b600119830152613148565b603d60f81b6000198301525b505050918152949350505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60646001600160601b03821611156132155760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610d5a565b6001600160a01b03821661326b5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610d5a565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906132d9903390899088908890600401614b81565b6020604051808303816000875af1925050508015613314575060408051601f3d908101601f1916820190925261331191810190614bb4565b60015b613372573d808015613342576040519150601f19603f3d011682016040523d82523d6000602084013e613347565b606091505b50805160000361336a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506129ac565b6060816000036133b35750506040805180820190915260018152600360fc1b602082015290565b8160005b81156133dd57806133c781614698565b91506133d69050600a8361466e565b91506133b7565b6000816001600160401b038111156133f7576133f7613f02565b6040519080825280601f01601f191660200182016040528015613421576020820181803683370190505b5090505b84156129ac576134366001836146b1565b9150613443600a86614bd1565b61344e9060306145fc565b60f81b81838151811061346357613463614682565b60200101906001600160f81b031916908160001a905350613485600a8661466e565b9450613425565b6060816000036134b65750506040805180820190915260048152630307830360e41b602082015290565b8160005b81156134d957806134ca81614698565b915050600882901c91506134ba565b6129ac8482613958565b6060816134f181601f6145fc565b10156135305760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610d5a565b61353a82846145fc565b8451101561357e5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610d5a565b60608215801561359d57604051915060008252602082016040526135e7565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156135d65780518352602092830192016135be565b5050858452601f01601f1916604052505b50949350505050565b804710156136405760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610d5a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461368d576040519150601f19603f3d011682016040523d82523d6000602084013e613692565b606091505b5050905080610e415760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610d5a565b6000826137168584613af3565b14949350505050565b6000548360000361374257604051622e076360e81b815260040160405180910390fd5b826000036137635760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03841660008181526005602090815260408083208054680100000000000000018902019055848352600490915290204260a01b86176001861460e11b1790558190818501903b15613838575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461380160008784806001019550876132a4565b61381e576040516368d2bf6b60e11b815260040160405180910390fd5b8082106137b657826000541461383357600080fd5b61387d565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210613839575b50600090815561118e9085838684565b6060815182604051602001611f00929190614be5565b6060833b60008190036138c6575050604080516020810190915260008152612752565b808411156138e4575050604080516020810190915260008152612752565b838310156139165760405163162544fd60e11b8152600481018290526024810185905260448101849052606401610d5a565b838303848203600082821061392b578261392d565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b606060006139678360026145dd565b6139729060026145fc565b6001600160401b0381111561398957613989613f02565b6040519080825280601f01601f1916602001820160405280156139b3576020820181803683370190505b509050600360fc1b816000815181106139ce576139ce614682565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106139fd576139fd614682565b60200101906001600160f81b031916908160001a9053506000613a218460026145dd565b613a2c9060016145fc565b90505b6001811115613aa4576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a6057613a60614682565b1a60f81b828281518110613a7657613a76614682565b60200101906001600160f81b031916908160001a90535060049490941c93613a9d81614c36565b9050613a2f565b5083156127525760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d5a565b600081815b8451811015613b5f576000858281518110613b1557613b15614682565b60200260200101519050808311613b3b5760008381526020829052604090209250613b4c565b600081815260208490526040902092505b5080613b5781614698565b915050613af8565b509392505050565b5080546000825590600052602060002090810190610d7a9190613c7d565b828054613b91906144c9565b90600052602060002090601f016020900481019282613bb35760008555613bf9565b82601f10613bcc57805160ff1916838001178555613bf9565b82800160010185558215613bf9579182015b82811115613bf9578251825591602001919060010190613bde565b50613c05929150613c7d565b5090565b828054613c15906144c9565b90600052602060002090601f016020900481019282613c375760008555613bf9565b82601f10613c505782800160ff19823516178555613bf9565b82800160010185558215613bf9579182015b82811115613bf9578235825591602001919060010190613c62565b5b80821115613c055760008155600101613c7e565b6001600160e01b031981168114610d7a57600080fd5b600060208284031215613cba57600080fd5b813561275281613c92565b60005b83811015613ce0578181015183820152602001613cc8565b8381111561118e5750506000910152565b60008151808452613d09816020860160208601613cc5565b601f01601f19169290920160200192915050565b6020815260006127526020830184613cf1565b600060208284031215613d4257600080fd5b5035919050565b6001600160a01b0381168114610d7a57600080fd5b60008060408385031215613d7157600080fd5b8235613d7c81613d49565b946020939093013593505050565b803560ff81168114613d9b57600080fd5b919050565b60008060008060008060c08789031215613db957600080fd5b863561ffff81168114613dcb57600080fd5b9550613dd960208801613d8a565b9450613de760408801613d8a565b9350613df560608801613d8a565b9250613e0360808801613d8a565b9150613e1160a08801613d8a565b90509295509295509295565b600080600060608486031215613e3257600080fd5b8335613e3d81613d49565b92506020840135613e4d81613d49565b929592945050506040919091013590565b60008060008060608587031215613e7457600080fd5b843593506020850135925060408501356001600160401b0380821115613e9957600080fd5b818701915087601f830112613ead57600080fd5b813581811115613ebc57600080fd5b8860208260051b8501011115613ed157600080fd5b95989497505060200194505050565b60008060408385031215613ef357600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f4057613f40613f02565b604052919050565b600082601f830112613f5957600080fd5b81356001600160401b03811115613f7257613f72613f02565b613f85601f8201601f1916602001613f18565b818152846020838601011115613f9a57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613fc957600080fd5b81356001600160401b03811115613fdf57600080fd5b6129ac84828501613f48565b60006001600160401b0382111561400457614004613f02565b5060051b60200190565b600082601f83011261401f57600080fd5b8135602061403461402f83613feb565b613f18565b82815260059290921b8401810191818101908684111561405357600080fd5b8286015b848110156140925780356001600160401b038111156140765760008081fd5b6140848986838b0101613f48565b845250918301918301614057565b509695505050505050565b6000806000606084860312156140b257600080fd5b833592506020808501356001600160401b03808211156140d157600080fd5b818701915087601f8301126140e557600080fd5b81356140f361402f82613feb565b81815260059190911b8301840190848101908a83111561411257600080fd5b938501935b8285101561413057843582529385019390850190614117565b96505050604087013592508083111561414857600080fd5b50506141568682870161400e565b9150509250925092565b6000806040838503121561417357600080fd5b82356001600160401b038082111561418a57600080fd5b818501915085601f83011261419e57600080fd5b813560206141ae61402f83613feb565b82815260059290921b840181019181810190898411156141cd57600080fd5b948201945b838610156141eb578535825294820194908201906141d2565b9650508601359250508082111561420157600080fd5b5061420e8582860161400e565b9150509250929050565b60008083601f84011261422a57600080fd5b5081356001600160401b0381111561424157600080fd5b60208301915083602082850101111561108557600080fd5b6000806000806000806080878903121561427257600080fd5b863595506020870135945060408701356001600160401b038082111561429757600080fd5b6142a38a838b01614218565b909650945060608901359150808211156142bc57600080fd5b506142c989828a01614218565b979a9699509497509295939492505050565b6000602082840312156142ed57600080fd5b813561275281613d49565b602081016004831061431a57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561433257600080fd5b81356001600160601b038116811461275257600080fd5b6000806040838503121561435c57600080fd5b823561436781613d49565b91506020830135801515811461437c57600080fd5b809150509250929050565b6000806000806080858703121561439d57600080fd5b84356143a881613d49565b935060208501356143b881613d49565b92506040850135915060608501356001600160401b038111156143da57600080fd5b6143e687828801613f48565b91505092959194509250565b60008060006060848603121561440757600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561443157600080fd5b8235915060208301356001600160f01b03198116811461437c57600080fd5b6000806040838503121561446357600080fd5b823561446e81613d49565b9150602083013561437c81613d49565b60008060006040848603121561449357600080fd5b8335925060208401356001600160401b038111156144b057600080fd5b6144bc86828701614218565b9497909650939450505050565b600181811c908216806144dd57607f821691505b602082108103612a2d57634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b61ffff96909616865260ff948516602087015292841660408601529083166060850152821660808401521660a082015260c00190565b60006020828403121561457a57600080fd5b5051919050565b60208082526026908201527f4d697865645374656d735f56315f313a204f7065726174696f6e526571756972604082015265657354696d6560d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156145f7576145f76145c7565b500290565b6000821982111561460f5761460f6145c7565b500190565b60208082526024908201527f4d697865645374656d735f56315f313a204d696e74696e674c696d697452656160408201526318da195960e21b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261467d5761467d614658565b500490565b634e487b7160e01b600052603260045260246000fd5b6000600182016146aa576146aa6145c7565b5060010190565b6000828210156146c3576146c36145c7565b500390565b634e487b7160e01b600052603160045260246000fd5b600083516146f0818460208801613cc5565b835190830190614704818360208801613cc5565b01949350505050565b8054600090600181811c908083168061472757607f831692505b6020808410820361474857634e487b7160e01b600052602260045260246000fd5b81801561475c576001811461476d5761479a565b60ff1986168952848901965061479a565b60008881526020902060005b868110156147925781548b820152908501908301614779565b505084890196505b50505050505092915050565b60006147b2828561470d565b8351614704818360208801613cc5565b683d913730b6b2911d1160b91b815260006147e0600983018a61470d565b61202360f01b815288516147fb816002840160208d01613cc5565b72111610113232b9b1b934b83a34b7b7111d101160691b60029290910191820152614829601582018961470d565b6c1116101134b6b0b3b2911d101160991b8152905061484b600d82018861470d565b9050662f696d6167652f60c81b8152855161486d816007840160208a01613cc5565b741116101130b734b6b0ba34b7b72fbab936111d101160591b6007929091019182015261489d601c82018661470d565b90506a2f616e696d6174696f6e2f60a81b815283516148c381600b840160208801613cc5565b01600b019998505050505050505050565b600085516148e6818460208a01613cc5565b80830190507f222c20226d696469223a2022646174613a617564696f2f6d6964693b626173658152620d8d0b60ea1b6020820152855161492d816023840160208a01613cc5565b7f222c202265787465726e616c5f75726c223a202268747470733a2f2f62656174602392909101918201527f666f756e6472792e78797a222c2022636f6d706f736572223a20220000000000604382015261498b605e82018661470d565b7f222c202261747472696275746573223a205b7b2274726169745f74797065223a815272101129b7b733911610113b30b63ab2911d101160691b602082015290506149d9603382018561470d565b61227d60f01b8152600201979650505050505050565b60008351614a01818460208801613cc5565b7f2c207b2274726169745f74797065223a2022436f76657220417274222c2022769083019081526730b63ab2911d101160c11b6020820152614a46602882018561470d565b61227d60f01b815260020195945050505050565b60008451614a6c818460208901613cc5565b7116103d913a3930b4ba2fba3cb832911d101160711b908301908152614a95601282018661470d565b6c111610113b30b63ab2911d101160991b81529050614ab7600d82018561470d565b61227d60f01b81526002019695505050505050565b60008251614ade818460208701613cc5565b615d7d60f01b920191825250600201919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614b2a81601d850160208701613cc5565b91909101601d0192915050565b80516020808301519190811015612a2d5760001960209190910360031b1b16919050565b6000815260008251614b74816001850160208701613cc5565b9190910160010192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061165890830184613cf1565b600060208284031215614bc657600080fd5b815161275281613c92565b600082614be057614be0614658565b500690565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090614c2881600e850160208701613cc5565b91909101600e019392505050565b600081614c4557614c456145c7565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212209cbe21c883e6318f07eccb9ede9f2701283e048b7aedf3153e210b1a452f377a64736f6c634300080d0033

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

0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008436f6c6c616765730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007436f6c6c616765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071436f6c6c61676573206f662076696e746167652c20656c656374726f6e69632062656174732074686174206f7665726c617020746f206372656174652067656e6572617469766520736f6e6773206f6e2d636861696e2e20436f6d706f7365642062792044616e69656c20416c6c616e2e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003434c470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c44616e69656c20416c6c616e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000b7327099300682e0b5562e3be7ce226e6f17f5000000000000000000000000eb57180709ea54d1e33be87d238000dafe0413200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000046

-----Decoded View---------------
Arg [0] : name_ (string): Collages
Arg [1] : singular_ (string): Collage
Arg [2] : description_ (string): Collages of vintage, electronic beats that overlap to create generative songs on-chain. Composed by Daniel Allan.
Arg [3] : symbol_ (string): CLG
Arg [4] : composer_ (string): Daniel Allan
Arg [5] : numVariableTracks_ (uint256): 3
Arg [6] : royaltyReceivers_ (address[]): 0x00b7327099300682E0B5562e3be7Ce226e6F17F5,0xeb57180709EA54D1E33bE87D238000DaFE041320
Arg [7] : royaltyShares_ (uint256[]): 30,70
Arg [8] : royaltyPercent_ (uint256): 5

-----Encoded View---------------
28 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000240
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000280
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 00000000000000000000000000000000000000000000000000000000000002c0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000320
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [10] : 436f6c6c61676573000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [12] : 436f6c6c61676500000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000071
Arg [14] : 436f6c6c61676573206f662076696e746167652c20656c656374726f6e696320
Arg [15] : 62656174732074686174206f7665726c617020746f206372656174652067656e
Arg [16] : 6572617469766520736f6e6773206f6e2d636861696e2e20436f6d706f736564
Arg [17] : 2062792044616e69656c20416c6c616e2e000000000000000000000000000000
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [19] : 434c470000000000000000000000000000000000000000000000000000000000
Arg [20] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [21] : 44616e69656c20416c6c616e0000000000000000000000000000000000000000
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [23] : 00000000000000000000000000b7327099300682e0b5562e3be7ce226e6f17f5
Arg [24] : 000000000000000000000000eb57180709ea54d1e33be87d238000dafe041320
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [26] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000046


Deployed Bytecode Sourcemap

107482:16732:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123786:320;;;;;;;;;;-1:-1:-1;123786:320:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;123786:320:0;;;;;;;;67272:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;69469:245::-;;;;;;;;;;-1:-1:-1;69469:245:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;69469:245:0;1528:203:1;68929:474:0;;;;;;;;;;-1:-1:-1;68929:474:0;;;;;:::i;:::-;;:::i;:::-;;107805:47;;;;;;;;;;;;;;;61060:315;;;;;;;;;;-1:-1:-1;61326:12:0;;61113:7;61310:13;:28;61060:315;;;2577:25:1;;;2565:2;2550:18;61060:315:0;2431:177:1;115533:104:0;;;;;;;;;;-1:-1:-1;115533:104:0;;;;;:::i;:::-;;:::i;113079:374::-;;;;;;;;;;-1:-1:-1;113079:374:0;;;;;:::i;:::-;;:::i;70478:170::-;;;;;;;;;;-1:-1:-1;70478:170:0;;;;;:::i;:::-;;:::i;107965:35::-;;;;;;;;;;;;;;;;120647:717;;;;;;:::i;:::-;;:::i;46403:442::-;;;;;;;;;;-1:-1:-1;46403:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;5278:32:1;;;5260:51;;5342:2;5327:18;;5320:34;;;;5233:18;46403:442:0;5086:274:1;111073:118:0;;;;;;;;;;-1:-1:-1;111073:118:0;;;;;:::i;:::-;;:::i;112737:334::-;;;;;;;;;;-1:-1:-1;112737:334:0;;;;;:::i;:::-;;:::i;112085:291::-;;;;;;;;;;-1:-1:-1;112085:291:0;;;;;:::i;:::-;;:::i;114223:379::-;;;;;;;;;;-1:-1:-1;114223:379:0;;;;;:::i;:::-;;:::i;70719:185::-;;;;;;;;;;-1:-1:-1;70719:185:0;;;;;:::i;:::-;;:::i;115292:233::-;;;;;;;;;;-1:-1:-1;115292:233:0;;;;;:::i;:::-;;:::i;107861:97::-;;;;;;;;;;;;107915:42;107861:97;;108256:25;;;;;;;;;;;;;;;;111199:102;;;;;;;;;;-1:-1:-1;111199:102:0;;;;;:::i;:::-;;:::i;110967:98::-;;;;;;;;;;-1:-1:-1;110967:98:0;;;;;:::i;:::-;;:::i;67061:144::-;;;;;;;;;;-1:-1:-1;67061:144:0;;;;;:::i;:::-;;:::i;118074:897::-;;;;;;;;;;-1:-1:-1;118074:897:0;;;;;:::i;:::-;;:::i;108194:24::-;;;;;;;;;;;;;;;;108092:21;;;;;;;;;;;;;:::i;108155:32::-;;;;;;;;;;;;;;;;111629:90;;;;;;;;;;-1:-1:-1;111629:90:0;;;;;:::i;:::-;;:::i;62735:234::-;;;;;;;;;;-1:-1:-1;62735:234:0;;;;;:::i;:::-;;:::i;90818:103::-;;;;;;;;;;;;;:::i;108374:25::-;;;;;;;;;;;;;:::i;118979:348::-;;;;;;;;;;-1:-1:-1;118979:348:0;;;;;:::i;:::-;;:::i;113461:372::-;;;;;;;;;;-1:-1:-1;113461:372:0;;;;;:::i;:::-;;:::i;123372:405::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;90167:87::-;;;;;;;;;;-1:-1:-1;90240:6:0;;-1:-1:-1;;;;;90240:6:0;90167:87;;120334:305;;;;;;;;;;-1:-1:-1;120334:305:0;;;;;:::i;:::-;;:::i;111309:114::-;;;;;;;;;;-1:-1:-1;111309:114:0;;;;;:::i;:::-;;:::i;67441:104::-;;;;;;;;;;;;;:::i;111942:135::-;;;;;;;;;;-1:-1:-1;111942:135:0;;;;;:::i;:::-;;:::i;119865:461::-;;;;;;:::i;:::-;;:::i;69786:340::-;;;;;;;;;;-1:-1:-1;69786:340:0;;;;;:::i;:::-;;:::i;112384:345::-;;;;;;;;;;-1:-1:-1;112384:345:0;;;;;:::i;:::-;;:::i;108314:22::-;;;;;;;;;;;;;:::i;108048:35::-;;;;;;;;;;;;;;;;111727:88;;;;;;;;;;-1:-1:-1;111727:88:0;;;;;:::i;:::-;;:::i;70975:396::-;;;;;;;;;;-1:-1:-1;70975:396:0;;;;;:::i;:::-;;:::i;114610:303::-;;;;;;;;;;-1:-1:-1;114610:303:0;;;;;:::i;:::-;;:::i;115886:2180::-;;;;;;;;;;-1:-1:-1;115886:2180:0;;;;;:::i;:::-;;:::i;115645:153::-;;;;;;;;;;-1:-1:-1;115645:153:0;;;;;:::i;:::-;;:::i;108007:34::-;;;;;;;;;;;;;;;;113841:374;;;;;;;;;;-1:-1:-1;113841:374:0;;;;;:::i;:::-;;:::i;108225:24::-;;;;;;;;;;;;;;;;108120:26;;;;;;;;;;;;;:::i;111529:92::-;;;;;;;;;;-1:-1:-1;111529:92:0;;;;;:::i;:::-;;:::i;119335:442::-;;;;;;;;;;-1:-1:-1;119335:442:0;;;;;:::i;:::-;;:::i;70197:214::-;;;;;;;;;;-1:-1:-1;70197:214:0;;;;;:::i;:::-;-1:-1:-1;;;;;70368:25:0;;;70339:4;70368:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;70197:214;114921:151;;;;;;;;;;-1:-1:-1;114921:151:0;;;;;:::i;:::-;;:::i;91076:201::-;;;;;;;;;;-1:-1:-1;91076:201:0;;;;;:::i;:::-;;:::i;110555:404::-;;;;;;;;;;-1:-1:-1;110555:404:0;;;;;:::i;:::-;;:::i;111431:90::-;;;;;;;;;;-1:-1:-1;111431:90:0;;;;;:::i;:::-;;:::i;111823:111::-;;;;;;;;;;-1:-1:-1;111823:111:0;;;;;:::i;:::-;;:::i;115080:204::-;;;;;;;;;;-1:-1:-1;115080:204:0;;;;;:::i;:::-;;:::i;123786:320::-;123889:4;124018:38;124044:11;124018:25;:38::i;:::-;:80;;;;124060:38;124086:11;124060:25;:38::i;:::-;124011:87;123786:320;-1:-1:-1;;123786:320:0:o;67272:100::-;67326:13;67359:5;67352:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67272:100;:::o;69469:245::-;69573:7;69603:16;69611:7;69603;:16::i;:::-;69598:64;;69628:34;;-1:-1:-1;;;69628:34:0;;;;;;;;;;;69598:64;-1:-1:-1;69682:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;69682:24:0;;69469:245::o;68929:474::-;69002:13;69034:27;69053:7;69034:18;:27::i;:::-;69002:61;;69084:5;-1:-1:-1;;;;;69078:11:0;:2;-1:-1:-1;;;;;69078:11:0;;69074:48;;69098:24;;-1:-1:-1;;;69098:24:0;;;;;;;;;;;69074:48;86367:10;-1:-1:-1;;;;;69139:28:0;;;69135:175;;69187:44;69204:5;86367:10;70197:214;:::i;69187:44::-;69182:128;;69259:35;;-1:-1:-1;;;69259:35:0;;;;;;;;;;;69182:128;69322:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;69322:29:0;-1:-1:-1;;;;;69322:29:0;;;;;;;;;69367:28;;69322:24;;69367:28;;;;;;;68991:412;68929:474;;:::o;115533:104::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;;;;;;;;;115610:19:::1;::::0;;;:13:::1;:19;::::0;;;;115603:26:::1;::::0;::::1;:::i;:::-;115533:104:::0;:::o;113079:374::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;113293:152:::1;::::0;-1:-1:-1;;;113293:152:0;;107915:42:::1;::::0;113293:23:::1;::::0;:152:::1;::::0;113331:4;;113350:5;;113370:3;;113388:4;;113407:6;;113428;;113293:152:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113270:20;:175:::0;-1:-1:-1;;;;;;113079:374:0:o;70478:170::-;70612:28;70622:4;70628:2;70632:7;70612:9;:28::i;:::-;70478:170;;;:::o;120647:717::-;120827:20;;109386:4;109368:15;:22;:34;;;;;109401:1;109394:4;:8;109368:34;109346:122;;;;-1:-1:-1;;;109346:122:0;;;;;;;:::i;:::-;120880:6:::1;120868:9;;:18;;;;:::i;:::-;109563:6;109550:9;:19;109542:59;;;::::0;-1:-1:-1;;;109542:59:0;;20710:2:1;109542:59:0::1;::::0;::::1;20692:21:1::0;20749:2;20729:18;;;20722:30;20788:29;20768:18;;;20761:57;20835:18;;109542:59:0::1;20508:351:1::0;109542:59:0::1;120953:9:::2;;120943:6;120926:14;60802:7:::0;60829:13;;60755:95;120926:14:::2;:23;;;;:::i;:::-;:36;;120904:122;;;;-1:-1:-1::0;;;120904:122:0::2;;;;;;;:::i;:::-;121095:8:::0;121085:6;121059:23:::2;86367:10:::0;62735:234;:::i;121059:23::-:2;:32;;;;:::i;:::-;:44;;121037:129;;;::::0;-1:-1:-1;;;121037:129:0;;21604:2:1;121037:129:0::2;::::0;::::2;21586:21:1::0;21643:2;21623:18;;;21616:30;21682:34;21662:18;;;21655:62;-1:-1:-1;;;21733:18:1;;;21726:33;21776:19;;121037:129:0::2;21402:399:1::0;121037:129:0::2;121199:56;86367:10:::0;121230:8:::2;121240:14;;121199:16;:56::i;:::-;121177:137;;;::::0;-1:-1:-1;;;121177:137:0;;22008:2:1;121177:137:0::2;::::0;::::2;21990:21:1::0;22047:2;22027:18;;;22020:30;22086:33;22066:18;;;22059:61;22137:18;;121177:137:0::2;21806:355:1::0;121177:137:0::2;121325:31;86367:10:::0;121349:6:::2;121325:9;:31::i;:::-;109479:1:::1;120647:717:::0;;;;;:::o;46403:442::-;46500:7;46558:27;;;:17;:27;;;;;;;;46529:56;;;;;;;;;-1:-1:-1;;;;;46529:56:0;;;;;-1:-1:-1;;;46529:56:0;;;-1:-1:-1;;;;;46529:56:0;;;;;;;;46500:7;;46598:92;;-1:-1:-1;46649:29:0;;;;;;;;;46659:19;46649:29;-1:-1:-1;;;;;46649:29:0;;;;-1:-1:-1;;;46649:29:0;;-1:-1:-1;;;;;46649:29:0;;;;;46598:92;46740:23;;;;46702:21;;124200:3;;46727:36;;-1:-1:-1;;;;;46727:36:0;:10;:36;:::i;:::-;46726:58;;;;:::i;:::-;46805:16;;;-1:-1:-1;46702:82:0;;-1:-1:-1;;46403:442:0;;;;;;:::o;111073:118::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111155:28;;::::1;::::0;:12:::1;::::0;:28:::1;::::0;::::1;::::0;::::1;:::i;:::-;;111073:118:::0;:::o;112737:334::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;112913:10:::1;:17;112896:6;:13;:34;112888:43;;;::::0;::::1;;112947:9;112942:122;112966:10;:17;112962:1;:21;112942:122;;;113039:10;113050:1;113039:13;;;;;;;;:::i;:::-;;;;;;;113005:14;:20;113020:4;113005:20;;;;;;;;;;;:31;113026:6;113033:1;113026:9;;;;;;;;:::i;:::-;;;;;;;113005:31;;;;;;;;;;;:47;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;112985:3:0;::::1;::::0;::::1;:::i;:::-;;;;112942:122;;;;112737:334:::0;;;:::o;112085:291::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;112232:9:::1;:16;112216:5;:12;:32;112208:41;;;::::0;::::1;;112265:9;112260:109;112284:9;:16;112280:1;:20;112260:109;;;112345:9;112355:1;112345:12;;;;;;;;:::i;:::-;;;;;;;112322:10;:20;112333:5;112339:1;112333:8;;;;;;;;:::i;:::-;;;;;;;112322:20;;;;;;;;;;;:35;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;112302:3:0;::::1;::::0;::::1;:::i;:::-;;;;112260:109;;114223:379:::0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;114437:17:::1;;114425:8;114410:44;114402:53;;;::::0;::::1;;114466:15;114484:20;114498:5;;114484:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;114484:13:0::1;::::0;-1:-1:-1;;;114484:20:0:i:1;:::-;114515:13;::::0;;;:7:::1;:13;::::0;;;;;;;:23;;;;;;;;:37;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;-1:-1:-1;;;;;;114515:37:0::1;-1:-1:-1::0;;;;;114515:37:0;::::1;::::0;;::::1;::::0;;;114563:19;;:10:::1;:19:::0;;;;;114515:37;;-1:-1:-1;114563:31:0::1;::::0;114585:9;;114563:31:::1;:::i;:::-;;114391:211;114223:379:::0;;;;;;:::o;70719:185::-;70857:39;70874:4;70880:2;70884:7;70857:39;;;;;;;;;;;;:16;:39::i;115292:233::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;115406:19:::1;::::0;;;:13:::1;:19;::::0;;;;115440:26;;:30:::1;::::0;115469:1:::1;::::0;115440:30:::1;:::i;:::-;115406:75;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;115377:19;;;:13:::1;:19:::0;;;;;;;:26;;-1:-1:-1;;;;;115406:75:0;;::::1;::::0;115397:5;;115377:26;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;;::::1;:104:::0;;-1:-1:-1;;;;;;115377:104:0::1;-1:-1:-1::0;;;;;115377:104:0;;;::::1;::::0;;;::::1;::::0;;;115492:19;;;:13:::1;:19:::0;;;;;;:25;;;::::1;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;115492:25:0;;;;;-1:-1:-1;;;;;;115492:25:0::1;::::0;;;;;-1:-1:-1;;115292:233:0:o;111199:102::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111273:20;;::::1;::::0;:8:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;110967:98::-:0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111039:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;67061:144::-:0;67125:7;67168:27;67187:7;67168:18;:27::i;118074:897::-;118126:13;118157:16;118165:7;118157;:16::i;:::-;118152:86;;118197:29;;-1:-1:-1;;;118197:29:0;;;;;;;;;;;118152:86;118248:12;118263:16;118271:7;118263;:16::i;:::-;118248:31;-1:-1:-1;118292:11:0;118248:31;118292:11;118324:7;118346:17;118366:19;;;:13;:19;;;;;:26;118450:17;;118324:7;;-1:-1:-1;118366:26:0;118424:51;;118438:29;;118366:26;118438:29;:::i;:::-;118470:4;118424:7;:51::i;:::-;118405:70;;118493:9;118488:247;118512:17;;118508:1;:21;118488:247;;;118551:18;118603:13;;;:7;:13;;;;;;;;:30;;;;;;;;118572:96;;118640:4;118645:5;118630:1;118649;118645:5;:::i;:::-;118640:11;;;;;;;:::i;:::-;118603:50;;118640:11;;;;118603:50;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;118603:50:0;118572:12;:96::i;:::-;118551:117;;118702:3;118707:15;118716:5;118707:8;:15::i;:::-;118689:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;118683:40;;118536:199;118531:3;;;;;:::i;:::-;;;;118488:247;;;;118752:9;118747:179;118771:9;118767:1;:13;118747:179;;;118802:18;118836:19;;;:13;:19;;;;;:22;;118823:36;;118836:19;118856:1;;118836:22;;;;;;:::i;118823:36::-;118802:57;;118893:3;118898:15;118907:5;118898:8;:15::i;:::-;118880:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;118874:40;;118787:139;118782:3;;;;;:::i;:::-;;;;118747:179;;;;118945:18;118959:3;118945:13;:18::i;:::-;118938:25;118074:897;-1:-1:-1;;;;;;118074:897:0:o;108092:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;111629:90::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111694:9:::1;:17:::0;111629:90::o;62735:234::-;62799:7;62841:5;62851:1;62823:29;62819:70;;62861:28;;-1:-1:-1;;;62861:28:0;;;;;;;;;;;62819:70;-1:-1:-1;;;;;;62907:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;62907:54:0;;62735:234::o;90818:103::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;90883:30:::1;90910:1;90883:18;:30::i;:::-;90818:103::o:0;108374:25::-;;;;;;;:::i;118979:348::-;119037:7;119062:16;119070:7;119062;:16::i;:::-;119057:86;;119102:29;;-1:-1:-1;;;119102:29:0;;;;;;;;;;;119057:86;119197:6;119263:17;;119283:1;119263:21;;;;:::i;:::-;119237:17;;:21;;119257:1;119237:21;:::i;:::-;119226:33;;:7;:33;:::i;:::-;:59;;;;:::i;:::-;119197:107;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;119197:107:0;;;119173:146;;;118979:348;-1:-1:-1;;118979:348:0:o;113461:372::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;113673:152:::1;::::0;-1:-1:-1;;;113673:152:0;;107915:42:::1;::::0;113673:23:::1;::::0;:152:::1;::::0;113711:4;;113730:5;;113750:3;;113768:4;;113787:6;;113808;;113673:152:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113651:19;:174:::0;-1:-1:-1;;;;;;113461:372:0:o;123372:405::-;123417:5;123457:20;;123439:15;:38;123435:335;;;-1:-1:-1;123501:13:0;;123372:405::o;123435:335::-;123554:19;;123536:15;:37;123532:238;;;-1:-1:-1;123597:12:0;;123372:405::o;123532:238::-;123649:20;;123631:15;:38;123627:143;;;-1:-1:-1;123693:15:0;;123372:405::o;123627:143::-;-1:-1:-1;123748:10:0;;123372:405::o;120334:305::-;120420:20;;109386:4;109368:15;:22;:34;;;;;109401:1;109394:4;:8;109368:34;109346:122;;;;-1:-1:-1;;;109346:122:0;;;;;;;:::i;:::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23:::1;90379:68;;;;-1:-1:-1::0;;;90379:68:0::1;;;;;;;:::i;:::-;120526:9:::2;;120516:6;120499:14;60802:7:::0;60829:13;;60755:95;120499:14:::2;:23;;;;:::i;:::-;:36;;120477:122;;;;-1:-1:-1::0;;;120477:122:0::2;;;;;;;:::i;:::-;120610:21;120620:2;120624:6;120610:9;:21::i;111309:114::-:0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111389:26;;::::1;::::0;:11:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;67441:104::-:0;67497:13;67530:7;67523:14;;;;;:::i;111942:135::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;112016:53:::1;112043:15;112061:7;112016:18;:53::i;119865:461::-:0;119949:19;;109386:4;109368:15;:22;:34;;;;;109401:1;109394:4;:8;109368:34;109346:122;;;;-1:-1:-1;;;109346:122:0;;;;;;;:::i;:::-;120001:6:::1;119989:9;;:18;;;;:::i;:::-;109563:6;109550:9;:19;109542:59;;;::::0;-1:-1:-1;;;109542:59:0;;20710:2:1;109542:59:0::1;::::0;::::1;20692:21:1::0;20749:2;20729:18;;;20722:30;20788:29;20768:18;;;20761:57;20835:18;;109542:59:0::1;20508:351:1::0;109542:59:0::1;120074:9:::2;;120064:6;120047:14;60802:7:::0;60829:13;;60755:95;120047:14:::2;:23;;;;:::i;:::-;:36;;120025:122;;;;-1:-1:-1::0;;;120025:122:0::2;;;;;;;:::i;:::-;120190:10;;120180:6;:20;;120158:116;;;::::0;-1:-1:-1;;;120158:116:0;;23630:2:1;120158:116:0::2;::::0;::::2;23612:21:1::0;23669:2;23649:18;;;23642:30;23708:34;23688:18;;;23681:62;-1:-1:-1;;;23759:18:1;;;23752:44;23813:19;;120158:116:0::2;23428:410:1::0;120158:116:0::2;120287:31;86367:10:::0;120311:6:::2;120287:9;:31::i;69786:340::-:0;86367:10;-1:-1:-1;;;;;69917:31:0;;;69913:61;;69957:17;;-1:-1:-1;;;69957:17:0;;;;;;;;;;;69913:61;86367:10;69987:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;69987:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;69987:60:0;;;;;;;;;;70063:55;;540:41:1;;;69987:49:0;;86367:10;70063:55;;513:18:1;70063:55:0;;;;;;;69786:340;;:::o;112384:345::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;112568:12:::1;:19;112549:8;:15;:38;112541:47;;;::::0;::::1;;112604:9;112599:123;112623:8;:15;112619:1;:19;112599:123;;;112695:12;112708:1;112695:15;;;;;;;;:::i;:::-;;;;;;;112660:13;:19;112674:4;112660:19;;;;;;;;;;;:32;112680:8;112689:1;112680:11;;;;;;;;:::i;:::-;;;;;;;112660:32;;;;;;;;;;;:50;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;112640:3:0;::::1;::::0;::::1;:::i;:::-;;;;112599:123;;108314:22:::0;;;;;;;:::i;111727:88::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111793:14;;::::1;::::0;:6:::1;::::0;:14:::1;::::0;::::1;::::0;::::1;:::i;70975:396::-:0;71142:28;71152:4;71158:2;71162:7;71142:9;:28::i;:::-;-1:-1:-1;;;;;71185:14:0;;;:19;71181:183;;71224:56;71255:4;71261:2;71265:7;71274:5;71224:30;:56::i;:::-;71219:145;;71308:40;;-1:-1:-1;;;71308:40:0;;;;;;;;;;;114610:303;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;114782:13:::1;::::0;;;:7:::1;:13;::::0;;;;;;;:23;;;;;;;;114820:30;;:34:::1;::::0;114853:1:::1;::::0;114820:34:::1;:::i;:::-;114782:83;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;114749:13;;;:7:::1;:13:::0;;;;;;:23;;;;;;;;:30;;-1:-1:-1;;;;;114782:83:0;;::::1;::::0;114773:5;;114749:30;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;;::::1;:116:::0;;-1:-1:-1;;;;;;114749:116:0::1;-1:-1:-1::0;;;;;114749:116:0;;;::::1;::::0;;;::::1;::::0;;;114876:13;;;:7:::1;:13:::0;;;;;;:23;;;;;;;:29;;;::::1;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;114876:29:0;;;;;-1:-1:-1;;;;;;114876:29:0::1;::::0;;;;;-1:-1:-1;;;114610:303:0:o;115886:2180::-;115987:13;116023:16;116031:7;116023;:16::i;:::-;116018:86;;116063:29;;-1:-1:-1;;;116063:29:0;;;;;;;;;;;116018:86;116120:6;:13;;;;;:::i;:::-;;;116137:1;116120:18;116116:116;;116186:12;116200:18;:7;:16;:18::i;:::-;116169:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;116155:65;;115886:2180;;;:::o;116116:116::-;116244:12;116259:16;116267:7;116259;:16::i;:::-;116244:31;;116286:15;116304:19;116315:7;116304:10;:19::i;:::-;116286:37;-1:-1:-1;116334:11:0;116366:7;;;;116408:13;116413:7;116408:4;:13::i;:::-;116388:33;;116434:17;116511:9;116554:18;:7;:16;:18::i;:::-;116623:11;116679:7;116725:27;116733:4;116725:25;:27::i;:::-;116805:7;116855:27;116863:4;116855:25;:27::i;:::-;116454:439;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;116454:439:0;;;;;;;;;117198:16;;;;:10;116454:439;117198:16;;;;;;116454:439;;-1:-1:-1;116911:333:0;;116454:439;;117013:3;;117107:8;;117198:16;;116911:333;;:::i;:::-;;;;-1:-1:-1;;116911:333:0;;;;;;;;;117371:19;;;;:13;116911:333;117371:19;;;;;;:28;;;;;;;;116911:333;;-1:-1:-1;117264:165:0;;116911:333;;117264:165;;:::i;:::-;;;;;;;;;;;;;117257:172;;117447:9;117442:369;117466:17;;117462:1;:21;117442:369;;;117609:20;;;;:14;:20;;;;;;;;:37;;;;;;;;117710:13;;;:7;:13;;;;;:30;;;;;;;;117547:4;;117699:10;;117747:4;117752:5;117643:1;117756;117752:5;:::i;:::-;117747:11;;;;;;;:::i;:::-;117710:50;;117747:11;;;;117710:50;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;117710:50:0;117699:62;;;;;;;;;;;;;;;117512:287;;;;;;;;:::i;:::-;;;;;;;;;;;;;117505:294;;117485:3;;;;;:::i;:::-;;;;117442:369;;;;117845:4;117828:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;117821:35;;118005:19;118019:4;118005:13;:19::i;:::-;117912:131;;;;;;;;:::i;:::-;;;;;;;;;;;;;117867:191;;;;;;;115886:2180;;;:::o;115645:153::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;115755:20:::1;::::0;;;:14:::1;:20;::::0;;;;;:35;;-1:-1:-1;;115755:35:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;115645:153::o;113841:374::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;114055:152:::1;::::0;-1:-1:-1;;;114055:152:0;;107915:42:::1;::::0;114055:23:::1;::::0;:152:::1;::::0;114093:4;;114112:5;;114132:3;;114150:4;;114169:6;;114190;;114055:152:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114032:20;:175:::0;-1:-1:-1;;;;;;113841:374:0:o;108120:26::-;;;;;;;:::i;111529:92::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111595:10:::1;:18:::0;111529:92::o;119335:442::-;119390:7;119415:16;119423:7;119415;:16::i;:::-;119410:86;;119455:29;;-1:-1:-1;;;119455:29:0;;;;;;;;;;;119410:86;119532:1;119516:6;:13;;;;;:::i;:::-;;;:17;119508:54;;;;-1:-1:-1;;;119508:54:0;;32095:2:1;119508:54:0;;;32077:21:1;32134:2;32114:18;;;32107:30;32173:26;32153:18;;;32146:54;32217:18;;119508:54:0;31893:348:1;119508:54:0;119621:133;119667:17;;119687:1;119667:21;;;;:::i;:::-;119656:33;;:7;:33;:::i;:::-;119713:17;;:21;;119733:1;119713:21;:::i;:::-;119621:6;:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:133;;;;;:::i;:::-;119595:174;;;:::i;114921:151::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;115041:13:::1;::::0;;;:7:::1;:13;::::0;;;;;;;:23;;;;;;;;115034:30:::1;::::0;::::1;:::i;91076:201::-:0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;91165:22:0;::::1;91157:73;;;::::0;-1:-1:-1;;;91157:73:0;;32750:2:1;91157:73:0::1;::::0;::::1;32732:21:1::0;32789:2;32769:18;;;32762:30;32828:34;32808:18;;;32801:62;-1:-1:-1;;;32879:18:1;;;32872:36;32925:19;;91157:73:0::1;32548:402:1::0;91157:73:0::1;91241:28;91260:8;91241:18;:28::i;110555:404::-:0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;110684:6:::1;110659:21;:31;;110637:117;;;::::0;-1:-1:-1;;;110637:117:0;;33157:2:1;110637:117:0::1;::::0;::::1;33139:21:1::0;33196:2;33176:18;;;33169:30;33235:34;33215:18;;;33208:62;-1:-1:-1;;;33286:18:1;;;33279:34;33330:19;;110637:117:0::1;32955:400:1::0;110637:117:0::1;110771:6;110781:1;110771:11:::0;110767:74:::1;;-1:-1:-1::0;110808:21:0::1;110767:74;-1:-1:-1::0;;;;;110855:16:0;::::1;110851:70;;90240:6:::0;;-1:-1:-1;;;;;90240:6:0;110888:21:::1;;110851:70;110931:20;-1:-1:-1::0;;;;;110931:12:0;::::1;110944:6:::0;110931:12:::1;:20::i;111431:90::-:0;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111496:9:::1;:17:::0;111431:90::o;111823:111::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;111898:20:::1;:28:::0;111823:111::o;115080:204::-;90240:6;;-1:-1:-1;;;;;90240:6:0;86367:10;90387:23;90379:68;;;;-1:-1:-1;;;90379:68:0;;;;;;;:::i;:::-;115194:15:::1;115212:20;115226:5;;115212:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;115212:13:0::1;::::0;-1:-1:-1;;;115212:20:0:i:1;:::-;115243:19;::::0;;;:13:::1;:19;::::0;;;;;;:33;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;-1:-1:-1;;;;;;115243:33:0::1;-1:-1:-1::0;;;;;115243:33:0;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;;;115080:204:0:o;62006:665::-;62136:4;-1:-1:-1;;;;;;;;;62441:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;62518:25:0;;;62441:102;:179;;;-1:-1:-1;;;;;;;;62595:25:0;-1:-1:-1;;;62595:25:0;;62006:665::o;46133:215::-;46235:4;-1:-1:-1;;;;;;46259:41:0;;-1:-1:-1;;;46259:41:0;;:81;;-1:-1:-1;;;;;;;;;;44130:40:0;;;46304:36;44021:157;71626:273;71683:4;71773:13;;71763:7;:23;71720:152;;;;-1:-1:-1;;71824:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;71824:43:0;:48;;71626:273::o;64448:1161::-;64542:7;64582;64684:13;;64677:4;:20;64673:869;;;64722:14;64739:23;;;:17;:23;;;;;;;-1:-1:-1;;;64828:23:0;;:28;;64824:699;;65347:113;65354:6;65364:1;65354:11;65347:113;;-1:-1:-1;;;65425:6:0;65407:25;;;;:17;:25;;;;;;65347:113;;;65493:6;64448:1161;-1:-1:-1;;;64448:1161:0:o;64824:699::-;64699:843;64673:869;65570:31;;-1:-1:-1;;;65570:31:0;;;;;;;;;;;77144:2667;77259:27;77289;77308:7;77289:18;:27::i;:::-;77259:57;;77374:4;-1:-1:-1;;;;;77333:45:0;77349:19;-1:-1:-1;;;;;77333:45:0;;77329:99;;77400:28;;-1:-1:-1;;;77400:28:0;;;;;;;;;;;77329:99;77441:23;77467:24;;;:15;:24;;;;;;-1:-1:-1;;;;;77467:24:0;;;;77441:23;77530:27;;86367:10;77530:27;;:87;;-1:-1:-1;77574:43:0;77591:4;86367:10;70197:214;:::i;77574:43::-;77530:142;;;-1:-1:-1;;;;;;77634:38:0;;86367:10;77634:38;77530:142;77504:169;;77691:17;77686:66;;77717:35;;-1:-1:-1;;;77717:35:0;;;;;;;;;;;77686:66;77785:2;77792:1;77767:26;77763:62;;77802:23;;-1:-1:-1;;;77802:23:0;;;;;;;;;;;77763:62;77969:15;77951:39;77947:103;;78014:24;;;;:15;:24;;;;;78007:31;;-1:-1:-1;;;;;;78007:31:0;;;77947:103;-1:-1:-1;;;;;78417:24:0;;;;;;;:18;:24;;;;;;;;78415:26;;-1:-1:-1;;78415:26:0;;;78486:22;;;;;;;;78484:24;;-1:-1:-1;78484:24:0;;;78779:26;;;:17;:26;;;;;-1:-1:-1;;;78867:15:0;58684:3;78867:41;78825:84;;:128;;78779:174;;;79073:46;;:51;;79069:626;;79177:1;79167:11;;79145:19;79300:30;;;:17;:30;;;;;;:35;;79296:384;;79438:13;;79423:11;:28;79419:242;;79585:30;;;;:17;:30;;;;;:52;;;79419:242;79126:569;79069:626;79742:7;79738:2;-1:-1:-1;;;;;79723:27:0;79732:4;-1:-1:-1;;;;;79723:27:0;;;;;;;;;;;79761:42;112737:334;123005:359;123153:4;123190:166;123227:6;;123190:166;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;123190:166:0;123252:20;123301:39;;-1:-1:-1;;33537:2:1;33533:15;;;33529:53;123301:39:0;;;33517:66:1;33599:12;;;33592:28;;;123252:20:0;;-1:-1:-1;33636:12:1;;;-1:-1:-1;123301:39:0;;;;;;;;;;;;123291:50;;;;;;123190:18;:166::i;:::-;123170:186;;123005:359;;;;;;;:::o;71983:104::-;72052:27;72062:2;72066:8;72052:27;;;;;;;;;;;;:9;:27::i;27865:475::-;27918:15;28021:17;28041:99;28119:5;28074:59;;;;;;;;:::i;:::-;;;;;;;;;;;;;28041:24;:99::i;:::-;28021:119;;28239:4;28233:11;28228:2;28222:4;28218:13;28215:1;28208:37;28197:48;-1:-1:-1;;;;;;28292:21:0;;28288:46;;28322:12;;-1:-1:-1;;;28322:12:0;;;;;;;;;;;28288:46;27935:405;27865:475;;;:::o;121449:922::-;121575:19;121597:20;;;:14;:20;;;;;;121545:12;;121597:20;;;;;121632;;:25;;121628:92;;-1:-1:-1;;;;121628:92:0;121750:13;;;121760:2;121750:13;;;;;;;;;121730:17;;121750:13;;;;;;;;;;-1:-1:-1;121750:13:0;121730:33;;121791:4;121784:12;;121774:4;121779:1;121774:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121774:22:0;;;;;;;;;121824:4;121817:12;;121807:4;121812:1;121807:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121807:22:0;;;;;;;;;121857:4;121850:12;;121840:4;121845:1;121840:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121840:22:0;;;;;;;;;121890:4;121883:12;;121873:4;121878:1;121873:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121873:22:0;;;;;;;;;121923:4;121916:12;;121906:4;121911:1;121906:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121906:22:0;;;;;;;;;121956:4;121949:12;;121939:4;121944:1;121939:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121939:22:0;;;;;;;;;121989:4;121982:12;;121972:4;121977:1;121972:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;121972:22:0;;;;;;;;;122022:4;122015:12;;122005:4;122010:1;122005:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;122005:22:0;;;;;;;;;122055:4;122048:12;;122038:4;122043:1;122038:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;122038:22:0;;;;;;;;;122075:9;:14;;122088:1;122075:14;122071:124;;122123:4;122116:12;;122106:4;122111:1;122106:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;122106:22:0;;;;;;;;;122071:124;;;122178:4;122171:12;;122161:4;122166:1;122161:7;;;;;;;;:::i;:::-;;;;:22;-1:-1:-1;;;;;122161:22:0;;;;;;;;;122071:124;122223:4;122216:12;;122205:4;122210:2;122205:8;;;;;;;;:::i;:::-;;;;:23;-1:-1:-1;;;;;122205:23:0;;;;;;;;;122257:9;122250:17;;122239:4;122244:2;122239:8;;;;;;;;:::i;:::-;;;;:28;-1:-1:-1;;;;;122239:28:0;;;;;;;;-1:-1:-1;122289:12:0;122302:1;122289:15;;;122278:4;122283:2;122278:8;;;;;;;;:::i;:::-;;;;:26;-1:-1:-1;;;;;122278:26:0;;;;;;;;-1:-1:-1;122326:12:0;122339:1;122326:15;;;122315:4;122320:2;122315:8;;;;;;;;:::i;:::-;;;;:26;-1:-1:-1;;;;;122315:26:0;;;;;;;;-1:-1:-1;122359:4:0;121449:922;-1:-1:-1;;;;121449:922:0:o;28602:136::-;28657:12;28685:47;28701:8;28711:1;-1:-1:-1;;28685:15:0;:47::i;122379:533::-;122481:12;;;122491:1;122481:12;;;;;;;;;122438;;122463:15;;122481:12;;;;;;;;;;;-1:-1:-1;122481:12:0;122463:30;;122519:4;122512:12;;122504:2;122507:1;122504:5;;;;;;;;:::i;:::-;;;;:20;-1:-1:-1;;;;;122504:20:0;;;;;;;;;122550:4;122543:12;;122535:2;122538:1;122535:5;;;;;;;;:::i;:::-;;;;:20;-1:-1:-1;;;;;122535:20:0;;;;;;;;;122581:4;122574:12;;122566:2;122569:1;122566:5;;;;;;;;:::i;:::-;;;;:20;-1:-1:-1;;;;;122566:20:0;;;;;;;;;122612:4;122605:12;;122597:2;122600:1;122597:5;;;;;;;;:::i;:::-;;;;:20;-1:-1:-1;;;;;122597:20:0;;;;;;;;;122628;122668:4;:11;122651:29;;;;;;34207:19:1;;34251:2;34242:12;;34078:182;122651:29:0;;;;;;;;;;;;;122628:52;;122699:7;122724:1;122707:7;:14;:18;;;;:::i;:::-;122699:27;;;;;;;;:::i;:::-;;;;;;;;;122691:2;122694:1;122691:5;;;;;;;;:::i;:::-;;;;:35;-1:-1:-1;;;;;122691:35:0;;;;;;;;;122745:7;122770:1;122753:7;:14;:18;;;;:::i;:::-;122745:27;;;;;;;;:::i;:::-;;;;;;;;;122737:2;122740:1;122737:5;;;;;;;;:::i;:::-;;;;:35;-1:-1:-1;;;;;122737:35:0;;;;;;;;;122791:7;122816:1;122799:7;:14;:18;;;;:::i;:::-;122791:27;;;;;;;;:::i;:::-;;;;;;;;;122783:2;122786:1;122783:5;;;;;;;;:::i;:::-;;;;:35;-1:-1:-1;;;;;122783:35:0;;;;;;;;;122837:7;122862:1;122845:7;:14;:18;;;;:::i;:::-;122837:27;;;;;;;;:::i;:::-;;;;;;;;;122829:2;122832:1;122829:5;;;;;;;;:::i;:::-;;;;:35;-1:-1:-1;;;;;122829:35:0;;;;;;;;;122895:2;122899:4;122882:22;;;;;;;;;:::i;:::-;;;;;;;;;;;;;122875:29;;;;122379:533;;;:::o;337:1790::-;435:11;;395:13;;421:11;461:8;;;457:23;;-1:-1:-1;;471:9:0;;;;;;;;;-1:-1:-1;471:9:0;;;337:1790;-1:-1:-1;337:1790:0:o;457:23::-;532:18;570:1;559:7;:3;565:1;559:7;:::i;:::-;558:13;;;;:::i;:::-;553:19;;:1;:19;:::i;:::-;532:40;-1:-1:-1;630:19:0;662:15;532:40;675:2;662:15;:::i;:::-;-1:-1:-1;;;;;652:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;652:26:0;;630:48;;691:18;712:5;;;;;;;;;;;;;;;;;691:26;;781:1;774:5;770:13;826:2;818:6;814:15;877:1;845:960;900:3;897:1;894:10;845:960;;;955:1;998:12;;;;;992:19;1093:4;1081:2;1077:14;;;;;1059:40;;1053:47;1245:2;1241:14;;;1237:25;;1223:40;;1217:47;1435:1;1431:13;;;1427:24;;1413:39;;1407:46;1616:16;;;;1602:31;;1596:38;1129:1;1125:11;;;1266:4;1213:58;;;1161:129;1315:11;;1403:57;;;1351:128;;;;1504:11;;1592:49;;1540:120;1689:3;1685:13;1718:22;;1788:1;1773:17;;;;948:9;845:960;;;849:44;1837:1;1832:3;1828:11;1858:1;1853:84;;;;1956:1;1951:82;;;;1821:212;;1853:84;-1:-1:-1;;;;;1886:17:0;;1879:43;1853:84;;1951:82;-1:-1:-1;;;;;1984:17:0;;1977:41;1821:212;-1:-1:-1;;;2049:26:0;;;2056:6;337:1790;-1:-1:-1;;;;337:1790:0:o;91437:191::-;91530:6;;;-1:-1:-1;;;;;91547:17:0;;;-1:-1:-1;;;;;;91547:17:0;;;;;;;91580:40;;91530:6;;;91547:17;91530:6;;91580:40;;91511:16;;91580:40;91500:128;91437:191;:::o;47495:332::-;124200:3;-1:-1:-1;;;;;47598:33:0;;;;47590:88;;;;-1:-1:-1;;;47590:88:0;;34467:2:1;47590:88:0;;;34449:21:1;34506:2;34486:18;;;34479:30;34545:34;34525:18;;;34518:62;-1:-1:-1;;;34596:18:1;;;34589:40;34646:19;;47590:88:0;34265:406:1;47590:88:0;-1:-1:-1;;;;;47697:22:0;;47689:60;;;;-1:-1:-1;;;47689:60:0;;34878:2:1;47689:60:0;;;34860:21:1;34917:2;34897:18;;;34890:30;34956:27;34936:18;;;34929:55;35001:18;;47689:60:0;34676:349:1;47689:60:0;47784:35;;;;;;;;;-1:-1:-1;;;;;47784:35:0;;;;;;-1:-1:-1;;;;;47784:35:0;;;;;;;;;;-1:-1:-1;;;47762:57:0;;;;:19;:57;47495:332::o;83634:831::-;83831:171;;-1:-1:-1;;;83831:171:0;;83797:4;;-1:-1:-1;;;;;83831:45:0;;;;;:171;;86367:10;;83933:4;;83956:7;;83982:5;;83831:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83831:171:0;;;;;;;;-1:-1:-1;;83831:171:0;;;;;;;;;;;;:::i;:::-;;;83814:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84216:6;:13;84233:1;84216:18;84212:235;;84262:40;;-1:-1:-1;;;84262:40:0;;;;;;;;;;;84212:235;84405:6;84399:13;84390:6;84386:2;84382:15;84375:38;83814:644;-1:-1:-1;;;;;;84075:81:0;-1:-1:-1;;;84075:81:0;;-1:-1:-1;84051:105:0;;40812:723;40868:13;41089:5;41098:1;41089:10;41085:53;;-1:-1:-1;;41116:10:0;;;;;;;;;;;;-1:-1:-1;;;41116:10:0;;;;;40812:723::o;41085:53::-;41163:5;41148:12;41204:78;41211:9;;41204:78;;41237:8;;;;:::i;:::-;;-1:-1:-1;41260:10:0;;-1:-1:-1;41268:2:0;41260:10;;:::i;:::-;;;41204:78;;;41292:19;41324:6;-1:-1:-1;;;;;41314:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41314:17:0;;41292:39;;41342:154;41349:10;;41342:154;;41376:11;41386:1;41376:11;;:::i;:::-;;-1:-1:-1;41445:10:0;41453:2;41445:5;:10;:::i;:::-;41432:24;;:2;:24;:::i;:::-;41419:39;;41402:6;41409;41402:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;41402:56:0;;;;;;;;-1:-1:-1;41473:11:0;41482:2;41473:11;;:::i;:::-;;;41342:154;;41645:340;41704:13;41734:5;41743:1;41734:10;41730:56;;-1:-1:-1;;41761:13:0;;;;;;;;;;;;-1:-1:-1;;;41761:13:0;;;;;41645:340::o;41730:56::-;41811:5;41796:12;41856:78;41863:9;;41856:78;;41889:8;;;;:::i;:::-;;;;41921:1;41912:10;;;;;41856:78;;;41951:26;41963:5;41970:6;41951:11;:26::i;14489:2871::-;14642:12;14696:7;14680:12;14696:7;14690:2;14680:12;:::i;:::-;:23;;14672:50;;;;-1:-1:-1;;;14672:50:0;;36097:2:1;14672:50:0;;;36079:21:1;36136:2;36116:18;;;36109:30;-1:-1:-1;;;36155:18:1;;;36148:44;36209:18;;14672:50:0;35895:338:1;14672:50:0;14758:16;14767:7;14758:6;:16;:::i;:::-;14741:6;:13;:33;;14733:63;;;;-1:-1:-1;;;14733:63:0;;36440:2:1;14733:63:0;;;36422:21:1;36479:2;36459:18;;;36452:30;-1:-1:-1;;;36498:18:1;;;36491:47;36555:18;;14733:63:0;36238:341:1;14733:63:0;14809:22;14875:15;;14904:2005;;;;17053:4;17047:11;17034:24;;17242:1;17231:9;17224:20;17292:4;17281:9;17277:20;17271:4;17264:34;14868:2445;;14904:2005;15089:4;15083:11;15070:24;;15758:2;15749:7;15745:16;16146:9;16139:17;16133:4;16129:28;16117:9;16106;16102:25;16098:60;16195:7;16191:2;16187:16;16452:6;16438:9;16431:17;16425:4;16421:28;16409:9;16401:6;16397:22;16393:57;16389:70;16223:434;16486:3;16482:2;16479:11;16223:434;;;16628:9;;16617:21;;16528:4;16520:13;;;;16561;16223:434;;;-1:-1:-1;;16677:26:0;;;16889:2;16872:11;-1:-1:-1;;16868:25:0;16862:4;16855:39;-1:-1:-1;14868:2445:0;-1:-1:-1;17343:9:0;14489:2871;-1:-1:-1;;;;14489:2871:0:o;34577:317::-;34692:6;34667:21;:31;;34659:73;;;;-1:-1:-1;;;34659:73:0;;36786:2:1;34659:73:0;;;36768:21:1;36825:2;36805:18;;;36798:30;36864:31;36844:18;;;36837:59;36913:18;;34659:73:0;36584:353:1;34659:73:0;34746:12;34764:9;-1:-1:-1;;;;;34764:14:0;34786:6;34764:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34745:52;;;34816:7;34808:78;;;;-1:-1:-1;;;34808:78:0;;37354:2:1;34808:78:0;;;37336:21:1;37393:2;37373:18;;;37366:30;37432:34;37412:18;;;37405:62;37503:28;37483:18;;;37476:56;37549:19;;34808:78:0;37152:422:1;30770:190:0;30895:4;30948;30919:25;30932:5;30939:4;30919:12;:25::i;:::-;:33;;30770:190;-1:-1:-1;;;;30770:190:0:o;72460:2471::-;72583:20;72606:13;72652:2;72659:1;72634:26;72630:58;;72669:19;;-1:-1:-1;;;72669:19:0;;;;;;;;;;;72630:58;72703:8;72715:1;72703:13;72699:44;;72725:18;;-1:-1:-1;;;72725:18:0;;;;;;;;;;;72699:44;-1:-1:-1;;;;;73292:22:0;;;;;;:18;:22;;;;58167:2;73292:22;;;:104;;73364:31;73335:61;;73292:104;;;73639:31;;;:17;:31;;;;;73732:15;58684:3;73732:41;73690:84;;-1:-1:-1;73810:13:0;;58943:3;73795:56;73690:162;73639:213;;:31;;73933:23;;;;73977:14;:19;73973:826;;74017:504;74048:38;;74073:12;;-1:-1:-1;;;;;74048:38:0;;;74065:1;;74048:38;;74065:1;;74048:38;74140:212;74209:1;74242:2;74275:14;;;;;;74320:5;74140:30;:212::i;:::-;74109:365;;74410:40;;-1:-1:-1;;;74410:40:0;;;;;;;;;;;74109:365;74516:3;74501:12;:18;74017:504;;74602:12;74585:13;;:29;74581:43;;74616:8;;;74581:43;73973:826;;;74665:119;74696:40;;74721:14;;;;;-1:-1:-1;;;;;74696:40:0;;;74713:1;;74696:40;;74713:1;;74696:40;74779:3;74764:12;:18;74665:119;;73973:826;-1:-1:-1;74813:13:0;:28;;;74863:60;;74896:2;74900:12;74914:8;74863:60;:::i;24922:718::-;24990:12;25560:5;:12;25622:5;25512:122;;;;;;;;;:::i;26376:971::-;26460:18;25926;;26487:13;26529:10;;;26525:32;;-1:-1:-1;;26548:9:0;;;;;;;;;-1:-1:-1;26548:9:0;;26541:16;;26525:32;26579:5;26570:6;:14;26566:36;;;-1:-1:-1;;26593:9:0;;;;;;;;;-1:-1:-1;26593:9:0;;26586:16;;26566:36;26620:6;26613:4;:13;26609:65;;;26635:39;;-1:-1:-1;;;26635:39:0;;;;;38464:25:1;;;38505:18;;;38498:34;;;38548:18;;;38541:34;;;38437:18;;26635:39:0;38262:319:1;26609:65:0;26721:13;;;26761:14;;;26703:15;26801:17;;;:37;;26831:7;26801:37;;;26821:7;26801:37;27012:4;27006:11;;27102:26;;;-1:-1:-1;;27098:42:0;27087:54;;27074:68;;;27187:19;;;27006:11;-1:-1:-1;26786:52:0;-1:-1:-1;26786:52:0;27313:6;27116:4;27295:16;;27288:5;27276:50;26858:477;;;26480:867;26376:971;;;;;:::o;42113:451::-;42188:13;42214:19;42246:10;42250:6;42246:1;:10;:::i;:::-;:14;;42259:1;42246:14;:::i;:::-;-1:-1:-1;;;;;42236:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42236:25:0;;42214:47;;-1:-1:-1;;;42272:6:0;42279:1;42272:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;42272:15:0;;;;;;;;;-1:-1:-1;;;42298:6:0;42305:1;42298:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;42298:15:0;;;;;;;;-1:-1:-1;42329:9:0;42341:10;42345:6;42341:1;:10;:::i;:::-;:14;;42354:1;42341:14;:::i;:::-;42329:26;;42324:135;42361:1;42357;:5;42324:135;;;-1:-1:-1;;;42409:5:0;42417:3;42409:11;42396:25;;;;;;;:::i;:::-;;;;42384:6;42391:1;42384:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;42384:37:0;;;;;;;;-1:-1:-1;42446:1:0;42436:11;;;;;42364:3;;;:::i;:::-;;;42324:135;;;-1:-1:-1;42477:10:0;;42469:55;;;;-1:-1:-1;;;42469:55:0;;38929:2:1;42469:55:0;;;38911:21:1;;;38948:18;;;38941:30;39007:34;38987:18;;;38980:62;39059:18;;42469:55:0;38727:356:1;31321:675:0;31404:7;31447:4;31404:7;31462:497;31486:5;:12;31482:1;:16;31462:497;;;31520:20;31543:5;31549:1;31543:8;;;;;;;;:::i;:::-;;;;;;;31520:31;;31586:12;31570;:28;31566:382;;32072:13;32122:15;;;32158:4;32151:15;;;32205:4;32189:21;;31698:57;;31566:382;;;32072:13;32122:15;;;32158:4;32151:15;;;32205:4;32189:21;;31875:57;;31566:382;-1:-1:-1;31500:3:0;;;;:::i;:::-;;;;31462:497;;;-1:-1:-1;31976:12:0;31321:675;-1:-1:-1;;;31321:675:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:131::-;-1:-1:-1;;;;;1811:31:1;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:315;1940:6;1948;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;2056:9;2043:23;2075:31;2100:5;2075:31;:::i;:::-;2125:5;2177:2;2162:18;;;;2149:32;;-1:-1:-1;;;1872:315:1:o;2825:156::-;2891:20;;2951:4;2940:16;;2930:27;;2920:55;;2971:1;2968;2961:12;2920:55;2825:156;;;:::o;2986:625::-;3079:6;3087;3095;3103;3111;3119;3172:3;3160:9;3151:7;3147:23;3143:33;3140:53;;;3189:1;3186;3179:12;3140:53;3228:9;3215:23;3278:6;3271:5;3267:18;3260:5;3257:29;3247:57;;3300:1;3297;3290:12;3247:57;3323:5;-1:-1:-1;3347:36:1;3379:2;3364:18;;3347:36;:::i;:::-;3337:46;;3402:36;3434:2;3423:9;3419:18;3402:36;:::i;:::-;3392:46;;3457:36;3489:2;3478:9;3474:18;3457:36;:::i;:::-;3447:46;;3512:37;3544:3;3533:9;3529:19;3512:37;:::i;:::-;3502:47;;3568:37;3600:3;3589:9;3585:19;3568:37;:::i;:::-;3558:47;;2986:625;;;;;;;;:::o;3616:456::-;3693:6;3701;3709;3762:2;3750:9;3741:7;3737:23;3733:32;3730:52;;;3778:1;3775;3768:12;3730:52;3817:9;3804:23;3836:31;3861:5;3836:31;:::i;:::-;3886:5;-1:-1:-1;3943:2:1;3928:18;;3915:32;3956:33;3915:32;3956:33;:::i;:::-;3616:456;;4008:7;;-1:-1:-1;;;4062:2:1;4047:18;;;;4034:32;;3616:456::o;4077:751::-;4181:6;4189;4197;4205;4258:2;4246:9;4237:7;4233:23;4229:32;4226:52;;;4274:1;4271;4264:12;4226:52;4310:9;4297:23;4287:33;;4367:2;4356:9;4352:18;4339:32;4329:42;;4422:2;4411:9;4407:18;4394:32;-1:-1:-1;;;;;4486:2:1;4478:6;4475:14;4472:34;;;4502:1;4499;4492:12;4472:34;4540:6;4529:9;4525:22;4515:32;;4585:7;4578:4;4574:2;4570:13;4566:27;4556:55;;4607:1;4604;4597:12;4556:55;4647:2;4634:16;4673:2;4665:6;4662:14;4659:34;;;4689:1;4686;4679:12;4659:34;4742:7;4737:2;4727:6;4724:1;4720:14;4716:2;4712:23;4708:32;4705:45;4702:65;;;4763:1;4760;4753:12;4702:65;4077:751;;;;-1:-1:-1;;4794:2:1;4786:11;;-1:-1:-1;;;4077:751:1:o;4833:248::-;4901:6;4909;4962:2;4950:9;4941:7;4937:23;4933:32;4930:52;;;4978:1;4975;4968:12;4930:52;-1:-1:-1;;5001:23:1;;;5071:2;5056:18;;;5043:32;;-1:-1:-1;4833:248:1:o;5365:127::-;5426:10;5421:3;5417:20;5414:1;5407:31;5457:4;5454:1;5447:15;5481:4;5478:1;5471:15;5497:275;5568:2;5562:9;5633:2;5614:13;;-1:-1:-1;;5610:27:1;5598:40;;-1:-1:-1;;;;;5653:34:1;;5689:22;;;5650:62;5647:88;;;5715:18;;:::i;:::-;5751:2;5744:22;5497:275;;-1:-1:-1;5497:275:1:o;5777:531::-;5820:5;5873:3;5866:4;5858:6;5854:17;5850:27;5840:55;;5891:1;5888;5881:12;5840:55;5927:6;5914:20;-1:-1:-1;;;;;5949:2:1;5946:26;5943:52;;;5975:18;;:::i;:::-;6019:55;6062:2;6043:13;;-1:-1:-1;;6039:27:1;6068:4;6035:38;6019:55;:::i;:::-;6099:2;6090:7;6083:19;6145:3;6138:4;6133:2;6125:6;6121:15;6117:26;6114:35;6111:55;;;6162:1;6159;6152:12;6111:55;6227:2;6220:4;6212:6;6208:17;6201:4;6192:7;6188:18;6175:55;6275:1;6250:16;;;6268:4;6246:27;6239:38;;;;6254:7;5777:531;-1:-1:-1;;;5777:531:1:o;6313:322::-;6382:6;6435:2;6423:9;6414:7;6410:23;6406:32;6403:52;;;6451:1;6448;6441:12;6403:52;6491:9;6478:23;-1:-1:-1;;;;;6516:6:1;6513:30;6510:50;;;6556:1;6553;6546:12;6510:50;6579;6621:7;6612:6;6601:9;6597:22;6579:50;:::i;6640:204::-;6721:4;-1:-1:-1;;;;;6746:6:1;6743:30;6740:56;;;6776:18;;:::i;:::-;-1:-1:-1;6821:1:1;6817:14;6833:4;6813:25;;6640:204::o;6849:909::-;6902:5;6955:3;6948:4;6940:6;6936:17;6932:27;6922:55;;6973:1;6970;6963:12;6922:55;7009:6;6996:20;7035:4;7059:81;7075:64;7136:2;7075:64;:::i;:::-;7059:81;:::i;:::-;7174:15;;;7260:1;7256:10;;;;7244:23;;7240:32;;;7205:12;;;;7284:15;;;7281:35;;;7312:1;7309;7302:12;7281:35;7348:2;7340:6;7336:15;7360:369;7376:6;7371:3;7368:15;7360:369;;;7462:3;7449:17;-1:-1:-1;;;;;7485:11:1;7482:35;7479:125;;;7558:1;7587:2;7583;7576:14;7479:125;7629:57;7682:3;7677:2;7663:11;7655:6;7651:24;7647:33;7629:57;:::i;:::-;7617:70;;-1:-1:-1;7707:12:1;;;;7393;;7360:369;;;-1:-1:-1;7747:5:1;6849:909;-1:-1:-1;;;;;;6849:909:1:o;7763:1291::-;7955:6;7963;7971;8024:2;8012:9;8003:7;7999:23;7995:32;7992:52;;;8040:1;8037;8030:12;7992:52;8076:9;8063:23;8053:33;;8105:2;8158;8147:9;8143:18;8130:32;-1:-1:-1;;;;;8222:2:1;8214:6;8211:14;8208:34;;;8238:1;8235;8228:12;8208:34;8276:6;8265:9;8261:22;8251:32;;8321:7;8314:4;8310:2;8306:13;8302:27;8292:55;;8343:1;8340;8333:12;8292:55;8379:2;8366:16;8402:81;8418:64;8479:2;8418:64;:::i;8402:81::-;8517:15;;;8599:1;8595:10;;;;8587:19;;8583:28;;;8548:12;;;;8623:19;;;8620:39;;;8655:1;8652;8645:12;8620:39;8679:11;;;;8699:142;8715:6;8710:3;8707:15;8699:142;;;8781:17;;8769:30;;8732:12;;;;8819;;;;8699:142;;;8860:5;-1:-1:-1;;;8918:2:1;8903:18;;8890:32;;-1:-1:-1;8934:16:1;;;8931:36;;;8963:1;8960;8953:12;8931:36;;;8986:62;9040:7;9029:8;9018:9;9014:24;8986:62;:::i;:::-;8976:72;;;7763:1291;;;;;:::o;9059:1197::-;9214:6;9222;9275:2;9263:9;9254:7;9250:23;9246:32;9243:52;;;9291:1;9288;9281:12;9243:52;9331:9;9318:23;-1:-1:-1;;;;;9401:2:1;9393:6;9390:14;9387:34;;;9417:1;9414;9407:12;9387:34;9455:6;9444:9;9440:22;9430:32;;9500:7;9493:4;9489:2;9485:13;9481:27;9471:55;;9522:1;9519;9512:12;9471:55;9558:2;9545:16;9580:4;9604:81;9620:64;9681:2;9620:64;:::i;9604:81::-;9719:15;;;9801:1;9797:10;;;;9789:19;;9785:28;;;9750:12;;;;9825:19;;;9822:39;;;9857:1;9854;9847:12;9822:39;9881:11;;;;9901:142;9917:6;9912:3;9909:15;9901:142;;;9983:17;;9971:30;;9934:12;;;;10021;;;;9901:142;;;10062:5;-1:-1:-1;;10105:18:1;;10092:32;;-1:-1:-1;;10136:16:1;;;10133:36;;;10165:1;10162;10155:12;10133:36;;10188:62;10242:7;10231:8;10220:9;10216:24;10188:62;:::i;:::-;10178:72;;;9059:1197;;;;;:::o;10261:347::-;10312:8;10322:6;10376:3;10369:4;10361:6;10357:17;10353:27;10343:55;;10394:1;10391;10384:12;10343:55;-1:-1:-1;10417:20:1;;-1:-1:-1;;;;;10449:30:1;;10446:50;;;10492:1;10489;10482:12;10446:50;10529:4;10521:6;10517:17;10505:29;;10581:3;10574:4;10565:6;10557;10553:19;10549:30;10546:39;10543:59;;;10598:1;10595;10588:12;10613:910;10777:6;10785;10793;10801;10809;10817;10870:3;10858:9;10849:7;10845:23;10841:33;10838:53;;;10887:1;10884;10877:12;10838:53;10923:9;10910:23;10900:33;;10980:2;10969:9;10965:18;10952:32;10942:42;;11035:2;11024:9;11020:18;11007:32;-1:-1:-1;;;;;11099:2:1;11091:6;11088:14;11085:34;;;11115:1;11112;11105:12;11085:34;11154:58;11204:7;11195:6;11184:9;11180:22;11154:58;:::i;:::-;11231:8;;-1:-1:-1;11128:84:1;-1:-1:-1;11319:2:1;11304:18;;11291:32;;-1:-1:-1;11335:16:1;;;11332:36;;;11364:1;11361;11354:12;11332:36;;11403:60;11455:7;11444:8;11433:9;11429:24;11403:60;:::i;:::-;10613:910;;;;-1:-1:-1;10613:910:1;;-1:-1:-1;10613:910:1;;11482:8;;10613:910;-1:-1:-1;;;10613:910:1:o;12035:247::-;12094:6;12147:2;12135:9;12126:7;12122:23;12118:32;12115:52;;;12163:1;12160;12153:12;12115:52;12202:9;12189:23;12221:31;12246:5;12221:31;:::i;12287:338::-;12429:2;12414:18;;12462:1;12451:13;;12441:144;;12507:10;12502:3;12498:20;12495:1;12488:31;12542:4;12539:1;12532:15;12570:4;12567:1;12560:15;12441:144;12594:25;;;12287:338;:::o;12630:292::-;12688:6;12741:2;12729:9;12720:7;12716:23;12712:32;12709:52;;;12757:1;12754;12747:12;12709:52;12796:9;12783:23;-1:-1:-1;;;;;12839:5:1;12835:38;12828:5;12825:49;12815:77;;12888:1;12885;12878:12;12927:416;12992:6;13000;13053:2;13041:9;13032:7;13028:23;13024:32;13021:52;;;13069:1;13066;13059:12;13021:52;13108:9;13095:23;13127:31;13152:5;13127:31;:::i;:::-;13177:5;-1:-1:-1;13234:2:1;13219:18;;13206:32;13276:15;;13269:23;13257:36;;13247:64;;13307:1;13304;13297:12;13247:64;13330:7;13320:17;;;12927:416;;;;;:::o;14942:666::-;15037:6;15045;15053;15061;15114:3;15102:9;15093:7;15089:23;15085:33;15082:53;;;15131:1;15128;15121:12;15082:53;15170:9;15157:23;15189:31;15214:5;15189:31;:::i;:::-;15239:5;-1:-1:-1;15296:2:1;15281:18;;15268:32;15309:33;15268:32;15309:33;:::i;:::-;15361:7;-1:-1:-1;15415:2:1;15400:18;;15387:32;;-1:-1:-1;15470:2:1;15455:18;;15442:32;-1:-1:-1;;;;;15486:30:1;;15483:50;;;15529:1;15526;15519:12;15483:50;15552;15594:7;15585:6;15574:9;15570:22;15552:50;:::i;:::-;15542:60;;;14942:666;;;;;;;:::o;15613:371::-;15745:6;15753;15761;15814:2;15802:9;15793:7;15789:23;15785:32;15782:52;;;15830:1;15827;15820:12;15782:52;-1:-1:-1;;15853:23:1;;;15923:2;15908:18;;15895:32;;-1:-1:-1;15974:2:1;15959:18;;;15946:32;;15613:371;-1:-1:-1;15613:371:1:o;15989:376::-;16083:6;16091;16144:2;16132:9;16123:7;16119:23;16115:32;16112:52;;;16160:1;16157;16150:12;16112:52;16183:23;;;-1:-1:-1;16256:2:1;16241:18;;16228:32;-1:-1:-1;;;;;;16289:27:1;;16279:38;;16269:66;;16331:1;16328;16321:12;16552:388;16620:6;16628;16681:2;16669:9;16660:7;16656:23;16652:32;16649:52;;;16697:1;16694;16687:12;16649:52;16736:9;16723:23;16755:31;16780:5;16755:31;:::i;:::-;16805:5;-1:-1:-1;16862:2:1;16847:18;;16834:32;16875:33;16834:32;16875:33;:::i;17766:504::-;17872:6;17880;17888;17941:2;17929:9;17920:7;17916:23;17912:32;17909:52;;;17957:1;17954;17947:12;17909:52;17993:9;17980:23;17970:33;;18054:2;18043:9;18039:18;18026:32;-1:-1:-1;;;;;18073:6:1;18070:30;18067:50;;;18113:1;18110;18103:12;18067:50;18152:58;18202:7;18193:6;18182:9;18178:22;18152:58;:::i;:::-;17766:504;;18229:8;;-1:-1:-1;18126:84:1;;-1:-1:-1;;;;17766:504:1:o;18275:380::-;18354:1;18350:12;;;;18397;;;18418:61;;18472:4;18464:6;18460:17;18450:27;;18418:61;18525:2;18517:6;18514:14;18494:18;18491:38;18488:161;;18571:10;18566:3;18562:20;18559:1;18552:31;18606:4;18603:1;18596:15;18634:4;18631:1;18624:15;18660:356;18862:2;18844:21;;;18881:18;;;18874:30;18940:34;18935:2;18920:18;;18913:62;19007:2;18992:18;;18660:356::o;19021:581::-;19316:6;19304:19;;;;19286:38;;19372:4;19360:17;;;19355:2;19340:18;;19333:45;19414:17;;;19409:2;19394:18;;19387:45;19468:17;;;19463:2;19448:18;;19441:45;19523:17;;19517:3;19502:19;;19495:46;19578:17;19572:3;19557:19;;19550:46;19273:3;19258:19;;19021:581::o;19607:184::-;19677:6;19730:2;19718:9;19709:7;19705:23;19701:32;19698:52;;;19746:1;19743;19736:12;19698:52;-1:-1:-1;19769:16:1;;19607:184;-1:-1:-1;19607:184:1:o;19796:402::-;19998:2;19980:21;;;20037:2;20017:18;;;20010:30;20076:34;20071:2;20056:18;;20049:62;-1:-1:-1;;;20142:2:1;20127:18;;20120:36;20188:3;20173:19;;19796:402::o;20203:127::-;20264:10;20259:3;20255:20;20252:1;20245:31;20295:4;20292:1;20285:15;20319:4;20316:1;20309:15;20335:168;20375:7;20441:1;20437;20433:6;20429:14;20426:1;20423:21;20418:1;20411:9;20404:17;20400:45;20397:71;;;20448:18;;:::i;:::-;-1:-1:-1;20488:9:1;;20335:168::o;20864:128::-;20904:3;20935:1;20931:6;20928:1;20925:13;20922:39;;;20941:18;;:::i;:::-;-1:-1:-1;20977:9:1;;20864:128::o;20997:400::-;21199:2;21181:21;;;21238:2;21218:18;;;21211:30;21277:34;21272:2;21257:18;;21250:62;-1:-1:-1;;;21343:2:1;21328:18;;21321:34;21387:3;21372:19;;20997:400::o;22166:127::-;22227:10;22222:3;22218:20;22215:1;22208:31;22258:4;22255:1;22248:15;22282:4;22279:1;22272:15;22298:120;22338:1;22364;22354:35;;22369:18;;:::i;:::-;-1:-1:-1;22403:9:1;;22298:120::o;22423:127::-;22484:10;22479:3;22475:20;22472:1;22465:31;22515:4;22512:1;22505:15;22539:4;22536:1;22529:15;22555:135;22594:3;22615:17;;;22612:43;;22635:18;;:::i;:::-;-1:-1:-1;22682:1:1;22671:13;;22555:135::o;22695:125::-;22735:4;22763:1;22760;22757:8;22754:34;;;22768:18;;:::i;:::-;-1:-1:-1;22805:9:1;;22695:125::o;22825:127::-;22886:10;22881:3;22877:20;22874:1;22867:31;22917:4;22914:1;22907:15;22941:4;22938:1;22931:15;22957:466;23132:3;23170:6;23164:13;23186:53;23232:6;23227:3;23220:4;23212:6;23208:17;23186:53;:::i;:::-;23302:13;;23261:16;;;;23324:57;23302:13;23261:16;23358:4;23346:17;;23324:57;:::i;:::-;23397:20;;22957:466;-1:-1:-1;;;;22957:466:1:o;23969:973::-;24054:12;;24019:3;;24109:1;24129:18;;;;24182;;;;24209:61;;24263:4;24255:6;24251:17;24241:27;;24209:61;24289:2;24337;24329:6;24326:14;24306:18;24303:38;24300:161;;24383:10;24378:3;24374:20;24371:1;24364:31;24418:4;24415:1;24408:15;24446:4;24443:1;24436:15;24300:161;24477:18;24504:104;;;;24622:1;24617:319;;;;24470:466;;24504:104;-1:-1:-1;;24537:24:1;;24525:37;;24582:16;;;;-1:-1:-1;24504:104:1;;24617:319;23916:1;23909:14;;;23953:4;23940:18;;24711:1;24725:165;24739:6;24736:1;24733:13;24725:165;;;24817:14;;24804:11;;;24797:35;24860:16;;;;24754:10;;24725:165;;;24729:3;;24919:6;24914:3;24910:16;24903:23;;24470:466;;;;;;;23969:973;;;;:::o;24947:376::-;25123:3;25151:38;25185:3;25177:6;25151:38;:::i;:::-;25218:6;25212:13;25234:52;25279:6;25275:2;25268:4;25260:6;25256:17;25234:52;:::i;25328:2186::-;-1:-1:-1;;;26460:43:1;;26442:3;26522:46;26565:1;26556:11;;26548:6;26522:46;:::i;:::-;-1:-1:-1;;;26584:2:1;26577:16;26622:6;26616:13;26638:60;26691:6;26687:1;26683:2;26679:10;26672:4;26664:6;26660:17;26638:60;:::i;:::-;-1:-1:-1;;;26756:1:1;26717:15;;;;26748:10;;;26741:70;26830:46;26872:2;26864:11;;26856:6;26830:46;:::i;:::-;-1:-1:-1;;;26885:50:1;;26820:56;-1:-1:-1;26954:46:1;26996:2;26988:11;;26980:6;26954:46;:::i;:::-;26944:56;;-1:-1:-1;;;27016:2:1;27009:21;27061:6;27055:13;27077:62;27130:8;27126:1;27122:2;27118:10;27111:4;27103:6;27099:17;27077:62;:::i;:::-;-1:-1:-1;;;27199:1:1;27158:17;;;;27191:10;;;27184:73;27276:46;27318:2;27310:11;;27302:6;27276:46;:::i;:::-;27266:56;;-1:-1:-1;;;27338:2:1;27331:25;27387:6;27381:13;27403:63;27457:8;27452:2;27448;27444:11;27437:4;27429:6;27425:17;27403:63;:::i;:::-;27486:17;27505:2;27482:26;;25328:2186;-1:-1:-1;;;;;;;;;25328:2186:1:o;27519:1656::-;28190:3;28228:6;28222:13;28244:53;28290:6;28285:3;28278:4;28270:6;28266:17;28244:53;:::i;:::-;28328:6;28323:3;28319:16;28306:29;;28358:66;28351:5;28344:81;-1:-1:-1;;;28452:4:1;28445:5;28441:16;28434:31;28496:6;28490:13;28512:66;28569:8;28564:2;28557:5;28553:14;28546:4;28538:6;28534:17;28512:66;:::i;:::-;28646;28641:2;28597:20;;;;28633:11;;;28626:87;28742:66;28737:2;28729:11;;28722:87;28828:46;28870:2;28862:11;;28854:6;28828:46;:::i;:::-;28894:66;28883:78;;-1:-1:-1;;;28985:4:1;28977:13;;28970:73;28818:56;-1:-1:-1;29062:46:1;29104:2;29096:11;;29088:6;29062:46;:::i;:::-;-1:-1:-1;;;29117:26:1;;29167:1;29159:10;;27519:1656;-1:-1:-1;;;;;;;27519:1656:1:o;29180:809::-;29556:3;29594:6;29588:13;29610:53;29656:6;29651:3;29644:4;29636:6;29632:17;29610:53;:::i;:::-;29724:66;29685:16;;;29710:81;;;-1:-1:-1;;;29818:4:1;29807:16;;29800:54;29873:49;29918:2;29907:14;;29899:6;29873:49;:::i;:::-;-1:-1:-1;;;29931:26:1;;29981:1;29973:10;;29180:809;-1:-1:-1;;;;;29180:809:1:o;29994:998::-;30516:3;30554:6;30548:13;30570:53;30616:6;30611:3;30604:4;30596:6;30592:17;30570:53;:::i;:::-;-1:-1:-1;;;30645:16:1;;;30670:63;;;30752:49;30797:2;30786:14;;30778:6;30752:49;:::i;:::-;-1:-1:-1;;;30810:50:1;;30742:59;-1:-1:-1;30879:46:1;30921:2;30913:11;;30905:6;30879:46;:::i;:::-;-1:-1:-1;;;30934:26:1;;30984:1;30976:10;;29994:998;-1:-1:-1;;;;;;29994:998:1:o;30997:438::-;31227:3;31265:6;31259:13;31281:53;31327:6;31322:3;31315:4;31307:6;31303:17;31281:53;:::i;:::-;-1:-1:-1;;;31356:16:1;;31381:19;;;-1:-1:-1;31427:1:1;31416:13;;30997:438;-1:-1:-1;30997:438:1:o;31440:448::-;31702:31;31697:3;31690:44;31672:3;31763:6;31757:13;31779:62;31834:6;31829:2;31824:3;31820:12;31813:4;31805:6;31801:17;31779:62;:::i;:::-;31861:16;;;;31879:2;31857:25;;31440:448;-1:-1:-1;;31440:448:1:o;32246:297::-;32364:12;;32411:4;32400:16;;;32394:23;;32364:12;32429:16;;32426:111;;;-1:-1:-1;;32503:4:1;32499:17;;;;32496:1;32492:25;32488:38;32477:50;;32246:297;-1:-1:-1;32246:297:1:o;33659:414::-;33919:1;33914:3;33907:14;33889:3;33950:6;33944:13;33966:61;34020:6;34016:1;34011:3;34007:11;34000:4;33992:6;33988:17;33966:61;:::i;:::-;34047:16;;;;34065:1;34043:24;;33659:414;-1:-1:-1;;33659:414:1:o;35030:489::-;-1:-1:-1;;;;;35299:15:1;;;35281:34;;35351:15;;35346:2;35331:18;;35324:43;35398:2;35383:18;;35376:34;;;35446:3;35441:2;35426:18;;35419:31;;;35224:4;;35467:46;;35493:19;;35485:6;35467:46;:::i;35524:249::-;35593:6;35646:2;35634:9;35625:7;35621:23;35617:32;35614:52;;;35662:1;35659;35652:12;35614:52;35694:9;35688:16;35713:30;35737:5;35713:30;:::i;35778:112::-;35810:1;35836;35826:35;;35841:18;;:::i;:::-;-1:-1:-1;35875:9:1;;35778:112::o;37579:678::-;-1:-1:-1;;;37954:16:1;;38025:3;38003:16;;;-1:-1:-1;;;;;;37999:43:1;37995:1;37986:11;;37979:64;-1:-1:-1;;;38068:1:1;38059:11;;38052:51;38126:13;;-1:-1:-1;;38148:62:1;38126:13;38198:2;38189:12;;38182:4;38170:17;;38148:62;:::i;:::-;38230:16;;;;38248:2;38226:25;;37579:678;-1:-1:-1;;;37579:678:1:o;38586:136::-;38625:3;38653:5;38643:39;;38662:18;;:::i;:::-;-1:-1:-1;;;38698:18:1;;38586:136::o

Swarm Source

ipfs://48f242caf7b01229c96339e2a2d210e23f58499c5d8dab7cdb45c5295f7937ef
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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