ETH Price: $2,974.53 (-1.12%)
Gas: 2 Gwei

Token

STARTLAND (STL)
 

Overview

Max Total Supply

8,174 STL

Holders

1,038

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 STL
0xed87631022d31dc2f1827fbf03057f153dbb91dc
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:
STARTLAND

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 62 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-11-22
*/

/**
 *Submitted for verification at Etherscan.io on 2023-02-25
 */

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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)
            }
        }
    }
}
pragma solidity ^0.8.0;

/**
  @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);
    }
}

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

/**
 *Submitted for verification at Etherscan.io on 2023-02-17
 */

// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(
        Set storage set,
        bytes32 value
    ) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(
        Set storage set,
        uint256 index
    ) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(
        Bytes32Set storage set,
        bytes32 value
    ) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(
        Bytes32Set storage set,
        bytes32 value
    ) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(
        Bytes32Set storage set,
        bytes32 value
    ) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(
        Bytes32Set storage set,
        uint256 index
    ) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(
        Bytes32Set storage set
    ) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(
        AddressSet storage set,
        address value
    ) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(
        AddressSet storage set,
        address value
    ) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(
        AddressSet storage set,
        address value
    ) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(
        AddressSet storage set,
        uint256 index
    ) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(
        AddressSet storage set
    ) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(
        UintSet storage set,
        uint256 value
    ) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(
        UintSet storage set,
        uint256 value
    ) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(
        UintSet storage set,
        uint256 index
    ) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(
        UintSet storage set
    ) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: @openzeppelin/contracts/utils/StorageSlot.sol

// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(
        bytes32 slot
    ) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(
        bytes32 slot
    ) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(
        bytes32 slot
    ) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(
        bytes32 slot
    ) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }
}

// File: @openzeppelin/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
            functionCallWithValue(
                target,
                data,
                0,
                "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"
        );
        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return
            verifyCallResultFromTarget(
                target,
                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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return
            verifyCallResultFromTarget(
                target,
                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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return
            verifyCallResultFromTarget(
                target,
                success,
                returndata,
                errorMessage
            );
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(
        bytes memory returndata,
        string memory errorMessage
    ) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(
        uint256 a,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return
                result +
                (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return
                result +
                (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return
                result +
                (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return
                result +
                (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

// File: solidity-bits/contracts/Popcount.sol

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        

- npm: https://www.npmjs.com/package/solidity-bits
- github: https://github.com/estarriolvetch/solidity-bits

 */

pragma solidity ^0.8.0;

library Popcount {
    uint256 private constant m1 =
        0x5555555555555555555555555555555555555555555555555555555555555555;
    uint256 private constant m2 =
        0x3333333333333333333333333333333333333333333333333333333333333333;
    uint256 private constant m4 =
        0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;
    uint256 private constant h01 =
        0x0101010101010101010101010101010101010101010101010101010101010101;

    function popcount256A(uint256 x) internal pure returns (uint256 count) {
        unchecked {
            for (count = 0; x != 0; count++) x &= x - 1;
        }
    }

    function popcount256B(uint256 x) internal pure returns (uint256) {
        if (x == type(uint256).max) {
            return 256;
        }
        unchecked {
            x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
            x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
            x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
            x = (x * h01) >> 248; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
        }
        return x;
    }
}
// File: solidity-bits/contracts/BitScan.sol

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        

- npm: https://www.npmjs.com/package/solidity-bits
- github: https://github.com/estarriolvetch/solidity-bits

 */

pragma solidity ^0.8.0;

library BitScan {
    uint256 private constant DEBRUIJN_256 =
        0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff;
    bytes private constant LOOKUP_TABLE_256 =
        hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8";

    /**
        @dev Isolate the least significant set bit.
     */
    function isolateLS1B256(uint256 bb) internal pure returns (uint256) {
        require(bb > 0);
        unchecked {
            return bb & (0 - bb);
        }
    }

    /**
        @dev Isolate the most significant set bit.
     */
    function isolateMS1B256(uint256 bb) internal pure returns (uint256) {
        require(bb > 0);
        unchecked {
            bb |= bb >> 128;
            bb |= bb >> 64;
            bb |= bb >> 32;
            bb |= bb >> 16;
            bb |= bb >> 8;
            bb |= bb >> 4;
            bb |= bb >> 2;
            bb |= bb >> 1;

            return (bb >> 1) + 1;
        }
    }

    /**
        @dev Find the index of the lest significant set bit. (trailing zero count)
     */
    function bitScanForward256(uint256 bb) internal pure returns (uint8) {
        unchecked {
            return
                uint8(
                    LOOKUP_TABLE_256[(isolateLS1B256(bb) * DEBRUIJN_256) >> 248]
                );
        }
    }

    /**
        @dev Find the index of the most significant set bit.
     */
    function bitScanReverse256(uint256 bb) internal pure returns (uint8) {
        unchecked {
            return
                255 -
                uint8(
                    LOOKUP_TABLE_256[
                        ((isolateMS1B256(bb) * DEBRUIJN_256) >> 248)
                    ]
                );
        }
    }

    function log2(uint256 bb) internal pure returns (uint8) {
        unchecked {
            return
                uint8(
                    LOOKUP_TABLE_256[(isolateMS1B256(bb) * DEBRUIJN_256) >> 248]
                );
        }
    }
}

// File: solidity-bits/contracts/BitMaps.sol

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        

- npm: https://www.npmjs.com/package/solidity-bits
- github: https://github.com/estarriolvetch/solidity-bits

 */
pragma solidity ^0.8.0;

/**
 * @dev This Library is a modified version of Openzeppelin's BitMaps library with extra features.
 *
 * 1. Functions of finding the index of the closest set bit from a given index are added.
 *    The indexing of each bucket is modifed to count from the MSB to the LSB instead of from the LSB to the MSB.
 *    The modification of indexing makes finding the closest previous set bit more efficient in gas usage.
 * 2. Setting and unsetting the bitmap consecutively.
 * 3. Accounting number of set bits within a given range.
 *
 */

/**
 * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
 * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
 */

library BitMaps {
    using BitScan for uint256;
    uint256 private constant MASK_INDEX_ZERO = (1 << 255);
    uint256 private constant MASK_FULL = type(uint256).max;

    struct BitMap {
        mapping(uint256 => uint256) _data;
    }

    /**
     * @dev Returns whether the bit at `index` is set.
     */
    function get(
        BitMap storage bitmap,
        uint256 index
    ) internal view returns (bool) {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        return bitmap._data[bucket] & mask != 0;
    }

    /**
     * @dev Sets the bit at `index` to the boolean `value`.
     */
    function setTo(BitMap storage bitmap, uint256 index, bool value) internal {
        if (value) {
            set(bitmap, index);
        } else {
            unset(bitmap, index);
        }
    }

    /**
     * @dev Sets the bit at `index`.
     */
    function set(BitMap storage bitmap, uint256 index) internal {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        bitmap._data[bucket] |= mask;
    }

    /**
     * @dev Unsets the bit at `index`.
     */
    function unset(BitMap storage bitmap, uint256 index) internal {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        bitmap._data[bucket] &= ~mask;
    }

    /**
     * @dev Consecutively sets `amount` of bits starting from the bit at `startIndex`.
     */
    function setBatch(
        BitMap storage bitmap,
        uint256 startIndex,
        uint256 amount
    ) internal {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if (bucketStartIndex + amount < 256) {
                bitmap._data[bucket] |=
                    (MASK_FULL << (256 - amount)) >>
                    bucketStartIndex;
            } else {
                bitmap._data[bucket] |= MASK_FULL >> bucketStartIndex;
                amount -= (256 - bucketStartIndex);
                bucket++;

                while (amount > 256) {
                    bitmap._data[bucket] = MASK_FULL;
                    amount -= 256;
                    bucket++;
                }

                bitmap._data[bucket] |= MASK_FULL << (256 - amount);
            }
        }
    }

    /**
     * @dev Consecutively unsets `amount` of bits starting from the bit at `startIndex`.
     */
    function unsetBatch(
        BitMap storage bitmap,
        uint256 startIndex,
        uint256 amount
    ) internal {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if (bucketStartIndex + amount < 256) {
                bitmap._data[bucket] &= ~((MASK_FULL << (256 - amount)) >>
                    bucketStartIndex);
            } else {
                bitmap._data[bucket] &= ~(MASK_FULL >> bucketStartIndex);
                amount -= (256 - bucketStartIndex);
                bucket++;

                while (amount > 256) {
                    bitmap._data[bucket] = 0;
                    amount -= 256;
                    bucket++;
                }

                bitmap._data[bucket] &= ~(MASK_FULL << (256 - amount));
            }
        }
    }

    /**
     * @dev Returns number of set bits within a range.
     */
    function popcountA(
        BitMap storage bitmap,
        uint256 startIndex,
        uint256 amount
    ) internal view returns (uint256 count) {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if (bucketStartIndex + amount < 256) {
                count += Popcount.popcount256A(
                    bitmap._data[bucket] &
                        ((MASK_FULL << (256 - amount)) >> bucketStartIndex)
                );
            } else {
                count += Popcount.popcount256A(
                    bitmap._data[bucket] & (MASK_FULL >> bucketStartIndex)
                );
                amount -= (256 - bucketStartIndex);
                bucket++;

                while (amount > 256) {
                    count += Popcount.popcount256A(bitmap._data[bucket]);
                    amount -= 256;
                    bucket++;
                }
                count += Popcount.popcount256A(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount))
                );
            }
        }
    }

    /**
     * @dev Returns number of set bits within a range.
     */
    function popcountB(
        BitMap storage bitmap,
        uint256 startIndex,
        uint256 amount
    ) internal view returns (uint256 count) {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if (bucketStartIndex + amount < 256) {
                count += Popcount.popcount256B(
                    bitmap._data[bucket] &
                        ((MASK_FULL << (256 - amount)) >> bucketStartIndex)
                );
            } else {
                count += Popcount.popcount256B(
                    bitmap._data[bucket] & (MASK_FULL >> bucketStartIndex)
                );
                amount -= (256 - bucketStartIndex);
                bucket++;

                while (amount > 256) {
                    count += Popcount.popcount256B(bitmap._data[bucket]);
                    amount -= 256;
                    bucket++;
                }
                count += Popcount.popcount256B(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount))
                );
            }
        }
    }

    /**
     * @dev Find the closest index of the set bit before `index`.
     */
    function scanForward(
        BitMap storage bitmap,
        uint256 index
    ) internal view returns (uint256 setBitIndex) {
        uint256 bucket = index >> 8;

        // index within the bucket
        uint256 bucketIndex = (index & 0xff);

        // load a bitboard from the bitmap.
        uint256 bb = bitmap._data[bucket];

        // offset the bitboard to scan from `bucketIndex`.
        bb = bb >> (0xff ^ bucketIndex); // bb >> (255 - bucketIndex)

        if (bb > 0) {
            unchecked {
                setBitIndex =
                    (bucket << 8) |
                    (bucketIndex - bb.bitScanForward256());
            }
        } else {
            while (true) {
                require(
                    bucket > 0,
                    "BitMaps: The set bit before the index doesn't exist."
                );
                unchecked {
                    bucket--;
                }
                // No offset. Always scan from the least significiant bit now.
                bb = bitmap._data[bucket];

                if (bb > 0) {
                    unchecked {
                        setBitIndex =
                            (bucket << 8) |
                            (255 - bb.bitScanForward256());
                        break;
                    }
                }
            }
        }
    }

    function getBucket(
        BitMap storage bitmap,
        uint256 bucket
    ) internal view returns (uint256) {
        return bitmap._data[bucket];
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol

// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol

// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * 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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

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

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

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/interfaces/IERC2981.sol

// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

/**
 * @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);
}

// File: @openzeppelin/contracts/token/common/ERC2981.sol

// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

/**
 * @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:
     *
     * - `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];
    }
}

// File: @openzeppelin/contracts/utils/Context.sol

// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: erc721psi/contracts/ERC721Psi.sol

/**
  ______ _____   _____ ______ ___  __ _  _  _ 
 |  ____|  __ \ / ____|____  |__ \/_ | || || |
 | |__  | |__) | |        / /   ) || | \| |/ |
 |  __| |  _  /| |       / /   / / | |\_   _/ 
 | |____| | \ \| |____  / /   / /_ | |  | |   
 |______|_|  \_\\_____|/_/   |____||_|  |_|   

 - github: https://github.com/estarriolvetch/ERC721Psi
 - npm: https://www.npmjs.com/package/erc721psi
                                          
 */

pragma solidity ^0.8.0;

contract ERC721Psi is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;
    using BitMaps for BitMaps.BitMap;

    BitMaps.BitMap internal _batchHead;

    string private _name;
    string private _symbol;

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

    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

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

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal pure virtual returns (uint256) {
        // It will become modifiable in the future versions
        return 0;
    }

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

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        return _currentIndex - _startTokenId();
    }

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

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

        uint count;
        for (uint i = _startTokenId(); i < _nextTokenId(); ++i) {
            if (_exists(i)) {
                if (owner == ownerOf(i)) {
                    ++count;
                }
            }
        }
        return count;
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(
        uint256 tokenId
    ) public view virtual override returns (address) {
        (address owner, ) = _ownerAndBatchHeadOf(tokenId);
        return owner;
    }

    function _ownerAndBatchHeadOf(
        uint256 tokenId
    ) internal view virtual returns (address owner, uint256 tokenIdBatchHead) {
        require(
            _exists(tokenId),
            "ERC721Psi: owner query for nonexistent token"
        );
        tokenIdBatchHead = _getBatchHead(tokenId);
        owner = _owners[tokenIdBatchHead];
    }

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return tokenId < _nextTokenId() && _startTokenId() <= tokenId;
    }

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

    /**
     * @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) internal virtual {
        _safeMint(to, quantity, "");
    }

    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        uint256 nextTokenId = _nextTokenId();
        _mint(to, quantity);
        require(
            _checkOnERC721Received(
                address(0),
                to,
                nextTokenId,
                quantity,
                _data
            ),
            "ERC721Psi: transfer to non ERC721Receiver implementer"
        );
    }

    function _mint(address to, uint256 quantity) internal virtual {
        uint256 nextTokenId = _nextTokenId();

        require(quantity > 0, "ERC721Psi: quantity must be greater 0");
        require(to != address(0), "ERC721Psi: mint to the zero address");

        _beforeTokenTransfers(address(0), to, nextTokenId, quantity);
        _currentIndex += quantity;
        _owners[nextTokenId] = to;
        _batchHead.set(nextTokenId);
        _afterTokenTransfers(address(0), to, nextTokenId, quantity);

        // Emit events
        for (
            uint256 tokenId = nextTokenId;
            tokenId < nextTokenId + quantity;
            tokenId++
        ) {
            emit Transfer(address(0), to, tokenId);
        }
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf(
            tokenId
        );

        require(owner == from, "ERC721Psi: transfer of token that is not own");
        require(to != address(0), "ERC721Psi: transfer to the zero address");

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        uint256 subsequentTokenId = tokenId + 1;

        if (
            !_batchHead.get(subsequentTokenId) &&
            subsequentTokenId < _nextTokenId()
        ) {
            _owners[subsequentTokenId] = from;
            _batchHead.set(subsequentTokenId);
        }

        _owners[tokenId] = to;
        if (tokenId != tokenIdBatchHead) {
            _batchHead.set(tokenId);
        }

        emit Transfer(from, to, tokenId);

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

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

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

    function _getBatchHead(
        uint256 tokenId
    ) internal view returns (uint256 tokenIdBatchHead) {
        tokenIdBatchHead = _batchHead.scanForward(tokenId);
    }

    function totalSupply() public view virtual returns (uint256) {
        return _totalMinted();
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * This function is compatiable with ERC721AQueryable.
     */
    function tokensOfOwner(
        address owner
    ) external view virtual returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            for (
                uint256 i = _startTokenId();
                tokenIdsIdx != tokenIdsLength;
                ++i
            ) {
                if (_exists(i)) {
                    if (ownerOf(i) == owner) {
                        tokenIds[tokenIdsIdx++] = i;
                    }
                }
            }
            return tokenIds;
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     *
     * 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`.
     */
    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.
     *
     * 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` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}
// File: erc721psi/contracts/extension/ERC721PsiBurnable.sol

/**
  ______ _____   _____ ______ ___  __ _  _  _ 
 |  ____|  __ \ / ____|____  |__ \/_ | || || |
 | |__  | |__) | |        / /   ) || | \| |/ |
 |  __| |  _  /| |       / /   / / | |\_   _/ 
 | |____| | \ \| |____  / /   / /_ | |  | |   
 |______|_|  \_\\_____|/_/   |____||_|  |_|   
                                              
                                            
 */
pragma solidity ^0.8.0;

abstract contract ERC721PsiBurnable is ERC721Psi {
    using BitMaps for BitMaps.BitMap;
    BitMaps.BitMap internal _burnedToken;

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

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

        _afterTokenTransfers(from, address(0), tokenId, 1);
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(
        uint256 tokenId
    ) internal view virtual override returns (bool) {
        if (_burnedToken.get(tokenId)) {
            return false;
        }
        return super._exists(tokenId);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalMinted() - _burned();
    }

    /**
     * @dev Returns number of token burned.
     */
    function _burned() internal view returns (uint256 burned) {
        uint256 startBucket = _startTokenId() >> 8;
        uint256 lastBucket = (_nextTokenId() >> 8) + 1;

        for (uint256 i = startBucket; i < lastBucket; i++) {
            uint256 bucket = _burnedToken.getBucket(i);
            burned += _popcount(bucket);
        }
    }

    /**
     * @dev Returns number of set bits.
     */
    function _popcount(uint256 x) private pure returns (uint256 count) {
        unchecked {
            for (count = 0; x != 0; count++) x &= x - 1;
        }
    }
}
// File: @openzeppelin/contracts/access/Ownable.sol

// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}

// File: EXO/NEW/EXO.sol

pragma solidity >=0.6.0;

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

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

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

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

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

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

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

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

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

            // run over the input, 3 bytes at a time
            for {

            } lt(dataPtr, endPtr) {

            } {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

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

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

        return result;
    }

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

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

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

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

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

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

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

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

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

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

            // run over the input, 4 characters at a time
            for {

            } lt(dataPtr, endPtr) {

            } {
                // read 4 characters
                dataPtr := add(dataPtr, 4)
                let input := mload(dataPtr)

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

        return result;
    }
}

pragma solidity ^0.8.7;

abstract contract MerkleProof {
    mapping(uint256 => bytes32) internal _alMerkleRoot;

    uint256 public phaseId;

    function _setAlMerkleRootWithId(
        uint256 _phaseId,
        bytes32 merkleRoot_
    ) internal virtual {
        _alMerkleRoot[_phaseId] = merkleRoot_;
    }

    function _setAlMerkleRoot(bytes32 merkleRoot_) internal virtual {
        _alMerkleRoot[phaseId] = merkleRoot_;
    }

    function isAllowlisted(
        address address_,
        uint256 _alId,
        bytes32[] memory proof_
    ) public view returns (bool) {
        bytes32 _leaf = keccak256(abi.encodePacked(address_));
        for (uint256 i = 0; i < proof_.length; i++) {
            _leaf = _leaf < proof_[i]
                ? keccak256(abi.encodePacked(_leaf, proof_[i]))
                : keccak256(abi.encodePacked(proof_[i], _leaf));
        }
        return _leaf == _alMerkleRoot[_alId];
    }
}

pragma solidity ^0.8.9;

abstract contract Operable is Context {
    mapping(address => bool) _operators;
    modifier onlyOperator() {
        _checkOperatorRole(_msgSender());
        _;
    }

    function isOperator(address _operator) public view returns (bool) {
        return _operators[_operator];
    }

    function _grantOperatorRole(address _candidate) internal {
        require(
            !_operators[_candidate],
            string(
                abi.encodePacked(
                    "account ",
                    Strings.toHexString(uint160(_msgSender()), 20),
                    " is already has an operator role"
                )
            )
        );
        _operators[_candidate] = true;
    }

    function _revokeOperatorRole(address _candidate) internal {
        _checkOperatorRole(_candidate);
        delete _operators[_candidate];
    }

    function _checkOperatorRole(address _operator) internal view {
        require(
            _operators[_operator],
            string(
                abi.encodePacked(
                    "account ",
                    Strings.toHexString(uint160(_msgSender()), 20),
                    " is not an operator"
                )
            )
        );
    }
}

pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(
        address registrant,
        address operator
    ) external view returns (bool);

    function register(address registrant) external;

    function registerAndSubscribe(
        address registrant,
        address subscription
    ) external;

    function registerAndCopyEntries(
        address registrant,
        address registrantToCopy
    ) external;

    function unregister(address addr) external;

    function updateOperator(
        address registrant,
        address operator,
        bool filtered
    ) external;

    function updateOperators(
        address registrant,
        address[] calldata operators,
        bool filtered
    ) external;

    function updateCodeHash(
        address registrant,
        bytes32 codehash,
        bool filtered
    ) external;

    function updateCodeHashes(
        address registrant,
        bytes32[] calldata codeHashes,
        bool filtered
    ) external;

    function subscribe(
        address registrant,
        address registrantToSubscribe
    ) external;

    function unsubscribe(address registrant, bool copyExistingEntries) external;

    function subscriptionOf(address addr) external returns (address registrant);

    function subscribers(
        address registrant
    ) external returns (address[] memory);

    function subscriberAt(
        address registrant,
        uint256 index
    ) external returns (address);

    function copyEntriesOf(
        address registrant,
        address registrantToCopy
    ) external;

    function isOperatorFiltered(
        address registrant,
        address operator
    ) external returns (bool);

    function isCodeHashOfFiltered(
        address registrant,
        address operatorWithCode
    ) external returns (bool);

    function isCodeHashFiltered(
        address registrant,
        bytes32 codeHash
    ) external returns (bool);

    function filteredOperators(
        address addr
    ) external returns (address[] memory);

    function filteredCodeHashes(
        address addr
    ) external returns (bytes32[] memory);

    function filteredOperatorAt(
        address registrant,
        uint256 index
    ) external returns (address);

    function filteredCodeHashAt(
        address registrant,
        uint256 index
    ) external returns (bytes32);

    function isRegistered(address addr) external returns (bool);

    function codeHashOf(address addr) external returns (bytes32);
}

pragma solidity ^0.8.13;

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);
    bool public operatorFilteringEnabled = true;

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(
                    address(this),
                    subscriptionOrRegistrantToCopy
                );
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(
                        address(this),
                        subscriptionOrRegistrantToCopy
                    );
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (
            address(OPERATOR_FILTER_REGISTRY).code.length > 0 &&
            operatorFilteringEnabled
        ) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !OPERATOR_FILTER_REGISTRY.isOperatorAllowed(
                    address(this),
                    msg.sender
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (
            address(OPERATOR_FILTER_REGISTRY).code.length > 0 &&
            operatorFilteringEnabled
        ) {
            if (
                !OPERATOR_FILTER_REGISTRY.isOperatorAllowed(
                    address(this),
                    operator
                )
            ) {
                revert OperatorNotAllowed(operator);
            }
        }
        _;
    }
}

pragma solidity ^0.8.13;

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION =
        address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

pragma solidity >=0.7.0 <0.9.0;

interface IContractAllowListProxy {
    function isAllowed(
        address _transferer,
        uint256 _level
    ) external view returns (bool);
}

pragma solidity >=0.8.0;

/// @title IERC721RestrictApprove
/// @dev Approve抑制機能付きコントラクトのインターフェース
/// @author Lavulite

interface IERC721RestrictApprove {
    /**
     * @dev CALレベルが変更された場合のイベント
     */
    event CalLevelChanged(address indexed operator, uint256 indexed level);

    /**
     * @dev LocalContractAllowListnに追加された場合のイベント
     */
    event LocalCalAdded(address indexed operator, address indexed transferer);

    /**
     * @dev LocalContractAllowListnに削除された場合のイベント
     */
    event LocalCalRemoved(address indexed operator, address indexed transferer);

    /**
     * @dev CALを利用する場合のCALのレベルを設定する。レベルが高いほど、許可されるコントラクトの範囲が狭い。
     */
    function setCALLevel(uint256 level) external;

    /**
     * @dev CALのアドレスをセットする。
     */
    function setCAL(address calAddress) external;

    /**
     * @dev CALのリストに無い独自の許可アドレスを追加する場合、こちらにアドレスを記載する。
     */
    function addLocalContractAllowList(address transferer) external;

    /**
     * @dev CALのリストにある独自の許可アドレスを削除する場合、こちらにアドレスを記載する。
     */
    function removeLocalContractAllowList(address transferer) external;

    /**
     * @dev CALのリストにある独自の許可アドレスの一覧を取得する。
     */
    function getLocalContractAllowList()
        external
        view
        returns (address[] memory);
}

pragma solidity >=0.8.0;

/// @title AntiScam機能付きERC721A
/// @dev Readmeを見てください。

abstract contract ERC721RestrictApprove is
    ERC721PsiBurnable,
    IERC721RestrictApprove
{
    using EnumerableSet for EnumerableSet.AddressSet;

    IContractAllowListProxy public CAL;
    EnumerableSet.AddressSet localAllowedAddresses;

    modifier onlyHolder(uint256 tokenId) {
        require(
            msg.sender == ownerOf(tokenId),
            "RestrictApprove: operation is only holder."
        );
        _;
    }

    /*//////////////////////////////////////////////////////////////
    変数
    //////////////////////////////////////////////////////////////*/
    bool public enableRestrict = true;

    // token lock
    mapping(uint256 => uint256) public tokenCALLevel;

    // wallet lock
    mapping(address => uint256) public walletCALLevel;

    // contract lock
    uint256 public CALLevel = 1;

    /*///////////////////////////////////////////////////////////////
    Approve抑制機能ロジック
    //////////////////////////////////////////////////////////////*/
    function _addLocalContractAllowList(address transferer) internal virtual {
        localAllowedAddresses.add(transferer);
        emit LocalCalAdded(msg.sender, transferer);
    }

    function _removeLocalContractAllowList(
        address transferer
    ) internal virtual {
        localAllowedAddresses.remove(transferer);
        emit LocalCalRemoved(msg.sender, transferer);
    }

    function _getLocalContractAllowList()
        internal
        view
        virtual
        returns (address[] memory)
    {
        return localAllowedAddresses.values();
    }

    function _isLocalAllowed(
        address transferer
    ) internal view virtual returns (bool) {
        return localAllowedAddresses.contains(transferer);
    }

    function _isAllowed(
        address transferer
    ) internal view virtual returns (bool) {
        return _isAllowed(msg.sender, transferer);
    }

    function _isAllowed(
        uint256 tokenId,
        address transferer
    ) internal view virtual returns (bool) {
        uint256 level = _getCALLevel(msg.sender, tokenId);
        return _isAllowed(transferer, level);
    }

    function _isAllowed(
        address holder,
        address transferer
    ) internal view virtual returns (bool) {
        uint256 level = _getCALLevel(holder);
        return _isAllowed(transferer, level);
    }

    function _isAllowed(
        address transferer,
        uint256 level
    ) internal view virtual returns (bool) {
        if (!enableRestrict) {
            return true;
        }

        return _isLocalAllowed(transferer) || CAL.isAllowed(transferer, level);
    }

    function _getCALLevel(
        address holder,
        uint256 tokenId
    ) internal view virtual returns (uint256) {
        if (tokenCALLevel[tokenId] > 0) {
            return tokenCALLevel[tokenId];
        }

        return _getCALLevel(holder);
    }

    function _getCALLevel(
        address holder
    ) internal view virtual returns (uint256) {
        if (walletCALLevel[holder] > 0) {
            return walletCALLevel[holder];
        }

        return CALLevel;
    }

    function _setCAL(address _cal) internal virtual {
        CAL = IContractAllowListProxy(_cal);
    }

    function _deleteTokenCALLevel(uint256 tokenId) internal virtual {
        delete tokenCALLevel[tokenId];
    }

    function setTokenCALLevel(
        uint256 tokenId,
        uint256 level
    ) external virtual onlyHolder(tokenId) {
        tokenCALLevel[tokenId] = level;
    }

    function setWalletCALLevel(uint256 level) external virtual {
        walletCALLevel[msg.sender] = level;
    }

    /*///////////////////////////////////////////////////////////////
                              OVERRIDES
    //////////////////////////////////////////////////////////////*/

    function isApprovedForAll(
        address owner,
        address operator
    ) public view virtual override returns (bool) {
        if (_isAllowed(owner, operator) == false) {
            return false;
        }
        return super.isApprovedForAll(owner, operator);
    }

    function setApprovalForAll(
        address operator,
        bool approved
    ) public virtual override {
        require(
            _isAllowed(operator) || approved == false,
            "RestrictApprove: Can not approve locked token"
        );
        super.setApprovalForAll(operator, approved);
    }

    function _beforeApprove(address to, uint256 tokenId) internal virtual {
        if (to != address(0)) {
            require(
                _isAllowed(tokenId, to),
                "RestrictApprove: The contract is not allowed."
            );
        }
    }

    function approve(address to, uint256 tokenId) public virtual override {
        _beforeApprove(to, tokenId);
        super.approve(to, tokenId);
    }

    function _afterTokenTransfers(
        address from,
        address /*to*/,
        uint256 startTokenId,
        uint256 /*quantity*/
    ) internal virtual override {
        // 転送やバーンにおいては、常にstartTokenIdは TokenIDそのものとなります。
        if (from != address(0)) {
            // CALレベルをデフォルトに戻す。
            _deleteTokenCALLevel(startTokenId);
        }
    }

    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override returns (bool) {
        return
            interfaceId == type(IERC721RestrictApprove).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

interface IControll {
    // TOKEN IDごとのステータスを取得
    function getLock(uint256 tokenId) external view returns (uint256);
}

pragma solidity ^0.8.7;

/*
┏━━┳━━┳━━┳━┳━━┳┓┏━━┳━┳┳━━┓
┃━━╋┓┏┫┏┓┃╋┣┓┏┫┃┃┏┓┃┃┃┣┓┓┃
┣━━┃┃┃┃┣┫┃┓┫┃┃┃┗┫┣┫┃┃┃┣┻┛┃
┗━━┛┗┛┗┛┗┻┻┛┗┛┗━┻┛┗┻┻━┻━━┛
-STARTLAND-
*/
contract STARTLAND is
    Ownable,
    ERC721RestrictApprove,
    ReentrancyGuard,
    MerkleProof,
    ERC2981,
    DefaultOperatorFilterer,
    Operable
{
    //Project Settings
    mapping(uint256 => mapping(uint256 => uint256)) public alMintPrice;
    mapping(uint256 => uint256) public psMintPrice;
    uint256 public maxSupply = 47350;
    uint256 public mintable = 17360;
    mapping(uint256 => uint256) public parcelUnits;
    mapping(uint256 => uint256) public pcMinted;
    uint256 public revealed;
    uint256 public nowPhasePs;
    uint256 public maxReveal;

    address internal _withdrawWallet;

    //URI
    string internal hiddenURI;
    string internal _baseTokenURI;
    string public _baseExtension = ".json";

    //flags
    mapping(uint256 => bool) public isAlSaleEnabled;
    bool public isPublicSaleEnabled;
    bool internal lockBurn = true;
    IControll ctlContract;
    address public ctlAddress;

    //mint records.
    mapping(uint256 => uint256) public phaseIds;
    mapping(uint256 => uint256) public maxMintsPerAL;
    mapping(uint256 => mapping(uint256 => uint256)) public maxMintsPerPc;
    mapping(uint256 => uint256) public maxMintsPerPS;
    mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))
        internal _alMinted;
    mapping(uint256 => mapping(uint256 => mapping(address => uint256)))
        internal _psMinted;
    mapping(int256 => mapping(int256 => uint256)) internal coordinate;
    mapping(uint256 => mapping(uint256 => mapping(address => uint256)))
        internal _privilege;
    mapping(uint256 => uint256) internal tokenHex;
    mapping(uint256 => uint256) internal tokenSize;
    address[] private pointer;
    using BytesLib for bytes;
    using BitMaps for BitMaps.BitMap;
    uint256 public nowPid;

    constructor() ERC721Psi("STARTLAND", "STL") {
        _grantOperatorRole(msg.sender);
        _withdrawWallet = 0xB4250F715995683c6EA5BC7c5e2CDF9b1601ba3f;
        _grantOperatorRole(_withdrawWallet);
        _setDefaultRoyalty(_withdrawWallet, 300);
        //CAL initialization
        setCALLevel(1);
        _setCAL(0xF2A78c73ffBAB6ECc3548Acc54B546ace279312E); //Ethereum mainnet proxy
        // _addLocalContractAllowList(0x1E0049783F008A0085193E00003D00cd54003c71); //OpenSea
        // _addLocalContractAllowList(0x4feE7B061C97C9c496b01DbcE9CDb10c02f0a0Be); //Rarible
        // _addLocalContractAllowList(0x000000000000Ad05Ccc4F10045630fb830B95127);//BLUR
        maxMintsPerPc[0][4] = 3; //1x1//Free
        maxMintsPerPc[1][3] = 1; //3x3//Free
        maxMintsPerPc[2][2] = 1; //5x5//Free

        maxMintsPerPc[3][0] = 1; //20x20//al
        maxMintsPerPc[3][1] = 1; //10x10//al
        maxMintsPerPc[3][2] = 1; //5x5//al
        maxMintsPerPc[3][3] = 1; //3x3//al
        maxMintsPerPc[3][4] = 5; //1x1//al

        maxMintsPerPc[4][0] = 10; //20x20//fcfs
        maxMintsPerPc[4][1] = 10; //10x10//fcfs
        maxMintsPerPc[4][2] = 10; //5x5//fcfs
        maxMintsPerPc[4][3] = 10; //3x3//fcfs
        maxMintsPerPc[4][4] = 10; //1x1//fcfs
        hiddenURI = "https://startlands.io/STL/hidden/";
        _baseTokenURI = "https://startlands.io/STL/";
        parcelUnits[0] = 17;
        parcelUnits[1] = 65;
        parcelUnits[2] = 1500;
        parcelUnits[3] = 278;
        parcelUnits[4] = 15500;
        // alMintPrice[0][4] = 0.0 ether; //1x1//Free
        // alMintPrice[1][3] = 0.0 ether; //3x3//Free
        // alMintPrice[2][2] = 0.0 ether; //5x5//Free
        alMintPrice[3][0] = 1 ether; //20x20
        alMintPrice[3][1] = 0.5 ether; //10x10
        alMintPrice[3][2] = 0.25 ether; //5x5
        alMintPrice[3][3] = 0.15 ether; //3x3
        alMintPrice[3][4] = 0.039 ether; //1x1
        alMintPrice[4][0] = 1 ether; //20x20
        alMintPrice[4][1] = 0.5 ether; //10x10
        alMintPrice[4][2] = 0.25 ether; //5x5
        alMintPrice[4][3] = 0.15 ether; //3x3
        alMintPrice[4][4] = 0.039 ether; //1x1
        ctlContract = IControll(0xB4250F715995683c6EA5BC7c5e2CDF9b1601ba3f);
        pcMinted[4] = 3380;
    }

    function setCtlContract(address _contractAddress) public onlyOperator {
        ctlAddress = _contractAddress;
        ctlContract = IControll(ctlAddress);
    }

    //start from 1.adjust.
    function _startTokenId() internal pure virtual override returns (uint256) {
        return 1;
    }

    //set Default Royalty._feeNumerator 500 = 5% Royalty
    function setDefaultRoyalty(
        address _receiver,
        uint96 _feeNumerator
    ) external virtual onlyOperator {
        _setDefaultRoyalty(_receiver, _feeNumerator);
    }

    //for ERC2981
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        virtual
        override(ERC721RestrictApprove, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    //for ERC2981 Opensea
    function contractURI() external view virtual returns (string memory) {
        return _formatContractURI();
    }

    //make contractURI
    function _formatContractURI() internal view returns (string memory) {
        (address receiver, uint256 royaltyFraction) = royaltyInfo(
            0,
            _feeDenominator()
        ); //tokenid=0
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"seller_fee_basis_points":',
                                Strings.toString(royaltyFraction),
                                ', "fee_recipient":"',
                                Strings.toHexString(
                                    uint256(uint160(receiver)),
                                    20
                                ),
                                '"}'
                            )
                        )
                    )
                )
            );
    }

    //set maxSupply.only owner.
    function setMaxSupply(uint256 _maxSupply) external virtual onlyOperator {
        maxSupply = _maxSupply;
    }

    //set mintable.only owner.
    function setMintable(uint256 _mintable) external virtual onlyOperator {
        mintable = _mintable;
    }

    //set mintable.only owner.
    function setParcelUnits(
        uint256 _pcId,
        uint256 _units
    ) external virtual onlyOperator {
        parcelUnits[_pcId] = _units;
    }

    // GET phaseId.
    function getPhaseIds(
        uint256 _alId
    ) external view virtual returns (uint256) {
        return phaseIds[_alId];
    }

    // SET phaseId.
    function setPhaseId(
        uint256 _alId,
        uint256 _phaseId
    ) external virtual onlyOperator {
        phaseIds[_alId] = _phaseId;
    }

    // SET phaseId.
    function setPhaseIdWithReset(
        uint256 _alId,
        uint256 _phaseId
    ) external virtual onlyOperator {
        phaseIds[_alId] = _phaseId;
    }

    function setNowPhasePs(uint256 _nowPhasePs) external virtual onlyOperator {
        nowPhasePs = _nowPhasePs;
    }

    // SET PRICES.
    //AL.Price
    function setAlPrice(
        uint256 _alId,
        uint256 _pcId,
        uint256 newPrice
    ) external virtual onlyOperator {
        alMintPrice[_alId][_pcId] = newPrice;
    }

    //PS.Price
    function setPsPrice(
        uint256 newPrice,
        uint256 _pcId
    ) external virtual onlyOperator {
        psMintPrice[_pcId] = newPrice;
    }

    //set reveal.only owner.
    function setReveal(uint256 newRevealNum) external virtual onlyOperator {
        revealed = newRevealNum;
    }

    //return _isRevealed()
    function _isRevealed(
        uint256 _tokenId
    ) internal view virtual returns (bool) {
        return _tokenId <= revealed;
    }

    // GET MINTED COUNT.
    function alIdMinted(
        uint256 _alId,
        address _address,
        uint256 _pcId
    ) external view virtual returns (uint256) {
        return _alMinted[_alId][phaseIds[_alId]][_pcId][_address];
    }

    function psMinted(
        address _address,
        uint256 _pcId
    ) external view virtual returns (uint256) {
        return _psMinted[nowPhasePs][_pcId][_address];
    }

    // SET MAX MINTS.
    //set.AL.mxmints
    function setPcMaxMints(
        uint256 _alId,
        uint256 _pcId,
        uint256 _max
    ) external virtual onlyOperator {
        maxMintsPerPc[_alId][_pcId] = _max;
    }

    //PS.mxmints
    function setPsMaxMints(
        uint256 _pcId,
        uint256 _max
    ) external virtual onlyOperator {
        maxMintsPerPS[_pcId] = _max;
    }

    // SET SALES ENABLE.

    //AL.SaleEnable
    function setAllowlistSaleEnable(
        uint256 _alId,
        bool bool_
    ) external virtual onlyOperator {
        isAlSaleEnabled[_alId] = bool_;
    }

    //PS.SaleEnable
    function setPublicSaleEnable(bool bool_) external virtual onlyOperator {
        isPublicSaleEnabled = bool_;
    }

    function setMerkleRootAlWithId(
        uint256 _phaseId,
        bytes32 merkleRoot_
    ) external virtual onlyOperator {
        _setAlMerkleRootWithId(_phaseId, merkleRoot_);
    }

    //set HiddenBaseURI.only owner.
    function setHiddenURI(string memory uri_) external virtual onlyOperator {
        hiddenURI = uri_;
    }

    //return _currentIndex
    function getCurrentIndex() external view virtual returns (uint256) {
        return _nextTokenId() - 1;
    }

    /** @dev set BaseURI at after reveal. only owner. */
    function setBaseURI(string memory uri_) external virtual onlyOperator {
        _baseTokenURI = uri_;
    }

    function setBaseExtension(
        string memory _newBaseExtension
    ) external onlyOperator {
        _baseExtension = _newBaseExtension;
    }

    /** @dev BaseURI.internal. */
    function _currentBaseURI() internal view returns (string memory) {
        return _baseTokenURI;
    }

    // SET MAX Rev.
    function setmaxReveal(uint256 _max) external virtual onlyOwner {
        maxReveal = _max;
    }

    function assignPrivileges(
        uint256 _alId,
        uint256 _pcId,
        address[] memory _address,
        uint256[] memory _priv
    ) external virtual onlyOperator {
        for (uint256 i = 0; i < _address.length; i++) {
            _privilege[_alId][_pcId][_address[i]] = _priv[i];
        }
    }

    function getMaxMint(
        uint256 _alId,
        uint256 _pcId,
        address _address
    ) public view virtual returns (uint256) {
        uint256 priv = maxMintsPerPc[_alId][_pcId];
        if (_privilege[_alId][_pcId][_address] > 0) {
            priv = _privilege[_alId][_pcId][_address];
        }
        return priv;
    }

    function tokenURI(
        uint256 _tokenId
    ) public view virtual override returns (string memory) {
        require(_exists(_tokenId), "URI query for nonexistent token");
        if (_isRevealed(_tokenId)) {
            return
                string(
                    abi.encodePacked(
                        _currentBaseURI(),
                        Strings.toString(getTokenHex(_tokenId)),
                        _baseExtension
                    )
                );
        }
        return
            string(
                abi.encodePacked(
                    hiddenURI,
                    Strings.toString(getTokenSize(_tokenId)),
                    _baseExtension
                )
            );
    }

    /** @dev owner mint.transfer to _address.only owner. */
    function ownerMintSafe(
        uint256 _pcId,
        uint256 _amount,
        address _address,
        uint256 _pmFlag
    ) external virtual onlyOperator {
        require((_amount + totalSupply()) <= (maxSupply), "No more NFTs");
        require(
            (_amount + pcMinted[_pcId]) <= (parcelUnits[_pcId]),
            "No more parcels"
        );
        if(_pmFlag > 0){
            _processMintedTokens(_pcId, _amount);
        }
        _safeMint(_address, _amount);
    }

    //AL mint.
    function allowlistMint(
        uint256 _alId,
        uint256 _pcId,
        uint256 _amount,
        address _receiver,
        bytes32[] memory proof_
    ) external payable virtual nonReentrant {
        require(isAlSaleEnabled[_alId], "allowlistMint is Paused");
        require(
            isAllowlisted(_receiver, _alId, proof_),
            "You are not whitelisted!"
        );
        require(
            getMaxMint(_alId, _pcId, _receiver) >= _amount,
            "allowlistMint: Over max mints per wallet"
        );
        require(
            getMaxMint(_alId, _pcId, _receiver) >=
                _alMinted[_alId][phaseIds[_alId]][_pcId][_receiver] + _amount,
            "You have no whitelistMint left"
        );
        require(
            msg.value == alMintPrice[_alId][_pcId] * _amount,
            "ETH value is not correct"
        );
        require((_amount + totalSupply()) <= (mintable), "No more NFTs");
        require(
            (_amount + pcMinted[_pcId]) <= (parcelUnits[_pcId]),
            "No more parcels"
        );
        _alMinted[_alId][phaseIds[_alId]][_pcId][_receiver] += _amount;
        _processMintedTokens(_pcId, _amount);
        _safeMint(_receiver, _amount);
    }

    //Public mint.
    function publicMint(
        uint256 _pcId,
        uint256 _amount,
        address _receiver
    ) external payable virtual nonReentrant {
        require(isPublicSaleEnabled, "publicMint is Paused");
        require(
            maxMintsPerPS[_pcId] >= _amount,
            "publicMint: Over max mints per wallet"
        );
        require(
            maxMintsPerPS[_pcId] >=
                _psMinted[nowPhasePs][_pcId][_receiver] + _amount,
            "You have no publicMint left"
        );
        require(
            msg.value == psMintPrice[_pcId] * _amount,
            "ETH value is not correct"
        );
        require((_amount + totalSupply()) <= (mintable), "No more NFTs");
        require(
            (_amount + pcMinted[_pcId]) <= (parcelUnits[_pcId]),
            "No more parcels"
        );
        _psMinted[nowPhasePs][_pcId][_receiver] += _amount;
        _processMintedTokens(_pcId, _amount);
        _safeMint(_receiver, _amount);
    }

    function _processMintedTokens(uint256 _pcId, uint256 _amount) internal {
        uint256 startTokenId = totalSupply() + 1;
        for (uint256 i = 0; i < _amount; i++) {
            uint256 tokenId = startTokenId + i;
            uint256 iterator = pcMinted[_pcId] + i;
            uint256 encodedHex = getCoordinateHex(iterator, _pcId);
            tokenHex[tokenId] = encodedHex;
            createEstate(encodedHex, _pcId, tokenId);
        }
        pcMinted[_pcId] += _amount;
    }
    function _processTokensAfter(uint256 _tokenId,uint256 _pcId, uint256 _amount) external onlyOperator {
        for (uint256 i = 0; i < _amount; i++) {
            uint256 tokenId = _tokenId + i;
            uint256 encodedHex;
            if(tokenId > 290 && tokenId <= 3670){
                uint256 iterator = tokenId - 291;
                encodedHex = getCoordinateHex(iterator, _pcId);
            }else{
                uint256 iterator = pcMinted[_pcId] + i;
                encodedHex = getCoordinateHex(iterator, _pcId);
            }
            tokenHex[tokenId] = encodedHex;
            createEstate(tokenHex[tokenId], _pcId, tokenId);
        }
        pcMinted[_pcId] += _amount;
    }

    /** @dev receive. */
    function receiveToDeb() external payable virtual nonReentrant {
        require(msg.value > 0, "ETH value is not correct");
    }

    /** @dev widraw ETH from this contract.only operator. */
    function withdraw() external payable virtual onlyOperator nonReentrant {
        uint256 _ethBalance = address(this).balance;
        bool os;
        if (_withdrawWallet != address(0)) {
            //if _withdrawWallet has.
            (os, ) = payable(_withdrawWallet).call{value: (_ethBalance)}("");
        } else {
            (os, ) = payable(owner()).call{value: (_ethBalance)}("");
        }
        require(os, "Failed to withdraw Ether");
    }

    //burn
    function burn(uint256 tokenId) external virtual {
        require(ownerOf(tokenId) == msg.sender, "isnt owner token");
        require(lockBurn == false, "not allow");
        _burn(tokenId);
    }

    //LB.SaleEnable
    function setLockBurn(bool bool_) external virtual onlyOperator {
        lockBurn = bool_;
    }

    //return wallet owned tokenids.
    function walletOfOwner(
        address _address
    ) external view virtual returns (uint256[] memory) {
        uint256 ownerTokenCount = balanceOf(_address);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        //search from all tonkenid. so spend high gas values.attention.
        uint256 tokenindex = 0;
        for (uint256 i = _startTokenId(); i <= (_nextTokenId() - 1); i++) {
            if (_address == this.tryOwnerOf(i)) tokenIds[tokenindex++] = i;
        }
        return tokenIds;
    }

    //try catch vaersion ownerOf. support burned tokenid.
    function tryOwnerOf(
        uint256 tokenId
    ) external view virtual returns (address) {
        try this.ownerOf(tokenId) returns (address _address) {
            return (_address);
        } catch {
            return (address(0)); //return 0x0 if error.
        }
    }

    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal override {
        if (from != address(0)) {
            for (uint256 i = 0; i < quantity; i++) {
                uint256 currentTokenId = startTokenId + i;
                require(
                    ctlContract.getLock(currentTokenId) < 1,
                    "Cannot transfer, token is locked"
                );
            }
        }
        super._beforeTokenTransfers(from, to, startTokenId, quantity);
    }

    //OPENSEA.OPERATORFilterer.START
    /**
     * @notice Set the state of the OpenSea operator filter
     * @param value Flag indicating if the operator filter should be applied to transfers and approvals
     */
    function setOperatorFilteringEnabled(bool value) external onlyOperator {
        operatorFilteringEnabled = value;
    }

    function setApprovalForAll(
        address operator,
        bool approved
    ) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(
        address operator,
        uint256 tokenId
    ) public override onlyAllowedOperatorApproval(operator) {
        require(
            ctlContract.getLock(tokenId) < 1,
            "Cannot approve, transferring not allowed"
        );
        super.approve(operator, tokenId);
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    //OPENSEA.OPERATORFilterer.END

    /*///////////////////////////////////////////////////////////////
                    OVERRIDES ERC721RestrictApprove
    //////////////////////////////////////////////////////////////*/
    function addLocalContractAllowList(
        address transferer
    ) external override onlyOperator {
        _addLocalContractAllowList(transferer);
    }

    function removeLocalContractAllowList(
        address transferer
    ) external override onlyOperator {
        _removeLocalContractAllowList(transferer);
    }

    function getLocalContractAllowList()
        external
        view
        override
        returns (address[] memory)
    {
        return _getLocalContractAllowList();
    }

    function setCALLevel(uint256 level) public override onlyOperator {
        CALLevel = level;
    }

    function setCAL(address calAddress) external override onlyOperator {
        _setCAL(calAddress);
    }

    /**
        @dev Operable.Role.ADD
     */
    function grantOperatorRole(address _candidate) external onlyOwner {
        _grantOperatorRole(_candidate);
    }

    /**
        @dev Operable.Role.REMOVE
     */
    function revokeOperatorRole(address _candidate) external onlyOwner {
        _revokeOperatorRole(_candidate);
    }

    /*
    Land Implements.
    */
    function setBytes(bytes calldata _bytes) external onlyOperator {
        pointer.push(SSTORE2.write(_bytes));
        nowPid = pointer.length - 1;
    }

    function setBytesWithId(
        bytes calldata _bytes,
        uint256 _pid
    ) external onlyOperator {
        pointer[_pid] = SSTORE2.write(_bytes);
        nowPid = pointer.length - 1;
    }

    function decodeHexToCoordinates(
        uint256 encodedHex
    ) public pure returns (int256, int256) {
        uint256 offset_x = (encodedHex >> 16) & 0xFFFF;
        uint256 offset_y = encodedHex & 0xFFFF;
        int256 x = int256(offset_x) - 170; // Adjust x offset
        int256 y = int256(offset_y) - 175; // Adjust y offset
        return (x, y);
    }
    function getTokenSize(uint256 _tokenId) public view returns (uint256) {
        if(tokenSize[_tokenId]>0){
            return tokenSize[_tokenId];
        }else{
            return 1;
        }
    }
    function getTokenHex(uint256 _tokenId) public view returns (uint256) {
        if(_tokenId > 290 && _tokenId <= 3670){
                uint256 iterator = _tokenId - 291;
                return getCoordinateHex(iterator, 4);
        }else{
            return tokenHex[_tokenId];
        }
    }

    function getTokenCoordinate(
        uint256 _tokenId
    ) external view onlyOperator returns (int256, int256) {
        return decodeHexToCoordinates(getTokenHex(_tokenId));
    }

    function getCoordinateHex(
        uint256 _iterator,
        uint256 _type
    ) internal view returns (uint256) {
        uint256 pid = _type;
        uint256 start = _iterator * 4;
        if (_type > 3) {
            pid = (_iterator / 4480) + 4;
            start = (_iterator - ((pid - 4) * 4480)) * 4;
        }
        bytes memory data = SSTORE2.read(pointer[pid], start, start + 4);

        uint256 encodedHex;
        assembly {
            encodedHex := mload(add(data, 32))
        }

        encodedHex = encodedHex >> (256 - 32);
        return encodedHex;
    }

    function getCoordinates(
        uint256 _iterator,
        uint256 _type
    ) internal view returns (int256, int256) {
        uint256 encodedHex = getCoordinateHex(_iterator, _type);
        return decodeHexToCoordinates(encodedHex);
    }

    // createEstate
    function createEstate(
        uint256 _hex,
        uint256 _type,
        uint256 _tokenId
    ) internal virtual {
        (int256 x, int256 y) = decodeHexToCoordinates(_hex);
        uint256 minusX;
        uint256 minusY;
        uint256 lands;

        // 各タイプに応じてパラメータを設定
        if (_type == 0) {
            minusX = 10;
            minusY = 9;
            lands = 20;
        } else if (_type == 1) {
            minusX = 4;
            minusY = 5;
            lands = 10;
        } else if (_type == 2) {
            minusX = 2;
            minusY = 2;
            lands = 5;
        } else if (_type == 3) {
            minusX = 1;
            minusY = 1;
            lands = 3;
        } else {
            coordinate[x][y] = _tokenId;
            // tokenSize[_tokenId] = 1;
            return;
        }
        tokenSize[_tokenId] = lands;

        int256 startX = x - int256(minusX);
        int256 endX = startX + int256(lands) - 1;
        int256 startY = y - int256(minusY);
        int256 endY = startY + int256(lands) - 1;

        // 右の辺だけを更新
        for (int256 j = startY; j <= endY; j++) {
            coordinate[endX][j] = _tokenId;
        }
    }

    function getLand(int256 x, int256 y) public view returns (uint256) {
        int256 originalX = x;
        for (int256 i = 0; i < 20; i++) {
            if (coordinate[x][y] != 0) {
                return coordinate[x][y];
            }
            x++;
            if (x > originalX + 20) {
                break;
            }
        }
        return 0;
    }

    function getLandOwner(int256 x, int256 y) external view returns (address) {
        uint256 _tokenId = getLand(x,y);
        if(_tokenId > 0){
            return ownerOf(_tokenId);
        }
        return address(0);
    }

    function getOwnerLand(
        address _address
    ) external view returns (int256[][] memory) {
        uint256 ownerTokenCount = balanceOf(_address);
        int256[][] memory coords = new int256[][](ownerTokenCount);

        uint256 tokenIndex = 0;
        for (uint256 i = _startTokenId(); i <= (_nextTokenId() - 1); i++) {
            if (_address == this.tryOwnerOf(i)) {
                (int256 x, int256 y) = decodeHexToCoordinates(getTokenHex(i));
                coords[tokenIndex] = new int256[](2);
                coords[tokenIndex][0] = x;
                coords[tokenIndex][1] = y;
                tokenIndex++;
            }
        }
        return coords;
    }
}
//CODE.BY.FRICKLIK

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":"operator","type":"address"},{"indexed":true,"internalType":"uint256","name":"level","type":"uint256"}],"name":"CalLevelChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"transferer","type":"address"}],"name":"LocalCalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"transferer","type":"address"}],"name":"LocalCalRemoved","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":[],"name":"CAL","outputs":[{"internalType":"contract IContractAllowListProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"_processTokensAfter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferer","type":"address"}],"name":"addLocalContractAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_pcId","type":"uint256"}],"name":"alIdMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"alMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"allowlistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_priv","type":"uint256[]"}],"name":"assignPrivileges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ctlAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"encodedHex","type":"uint256"}],"name":"decodeHexToCoordinates","outputs":[{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"enableRestrict","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"x","type":"int256"},{"internalType":"int256","name":"y","type":"int256"}],"name":"getLand","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"x","type":"int256"},{"internalType":"int256","name":"y","type":"int256"}],"name":"getLandOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLocalContractAllowList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"address","name":"_address","type":"address"}],"name":"getMaxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getOwnerLand","outputs":[{"internalType":"int256[][]","name":"","type":"int256[][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"}],"name":"getPhaseIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTokenCoordinate","outputs":[{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTokenHex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTokenSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_candidate","type":"address"}],"name":"grantOperatorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isAlSaleEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"isAllowlisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSaleEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxMintsPerAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxMintsPerPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxMintsPerPc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxReveal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nowPhasePs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nowPid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_pmFlag","type":"uint256"}],"name":"ownerMintSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"parcelUnits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pcMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phaseId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"phaseIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"psMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_pcId","type":"uint256"}],"name":"psMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"receiveToDeb","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"transferer","type":"address"}],"name":"removeLocalContractAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_candidate","type":"address"}],"name":"revokeOperatorRole","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setAlPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"bool","name":"bool_","type":"bool"}],"name":"setAllowlistSaleEnable","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":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_bytes","type":"bytes"}],"name":"setBytes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_bytes","type":"bytes"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"setBytesWithId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"calAddress","type":"address"}],"name":"setCAL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setCtlContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint96","name":"_feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setHiddenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"bool_","type":"bool"}],"name":"setLockBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_phaseId","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"setMerkleRootAlWithId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintable","type":"uint256"}],"name":"setMintable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nowPhasePs","type":"uint256"}],"name":"setNowPhasePs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_units","type":"uint256"}],"name":"setParcelUnits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setPcMaxMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_phaseId","type":"uint256"}],"name":"setPhaseId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alId","type":"uint256"},{"internalType":"uint256","name":"_phaseId","type":"uint256"}],"name":"setPhaseIdWithReset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pcId","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setPsMaxMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"},{"internalType":"uint256","name":"_pcId","type":"uint256"}],"name":"setPsPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"bool_","type":"bool"}],"name":"setPublicSaleEnable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRevealNum","type":"uint256"}],"name":"setReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setTokenCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setWalletCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setmaxReveal","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":"","type":"uint256"}],"name":"tokenCALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"uint256","name":"tokenId","type":"uint256"}],"name":"tryOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletCALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

600c8054600160ff199182168117909255600f82905560158054909116909117905561b8f66019556143d0601a5560c06040526005608090815264173539b7b760d91b60a05260239062000054908262000cb3565b506025805461ff00191661010017905534801562000070575f80fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600981526020016814d51054951310539160ba1b8152506040518060400160405280600381526020016214d51360ea1b815250620000e0620000da620007e760201b60201c565b620007eb565b6002620000ee838262000cb3565b506003620000fd828262000cb3565b506001600555505060016010556daaeb6d7670e522a718067333cd4e3b15620002455780156200019857604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b5f604051808303815f87803b1580156200017b575f80fd5b505af11580156200018e573d5f803e3d5ffd5b5050505062000245565b6001600160a01b03821615620001e95760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000163565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e486906024015f604051808303815f87803b1580156200022d575f80fd5b505af115801562000240573d5f803e3d5ffd5b505050505b50620002539050336200083a565b602080546001600160a01b03191673b4250f715995683c6ea5bc7c5e2cdf9b1601ba3f90811790915562000287906200083a565b602054620002a1906001600160a01b031661012c620008dc565b620002ad6001620009dd565b600980546001600160a01b03191673f2a78c73ffbab6ecc3548acc54b546ace279312e17905560037ff47fb4829b7e5204b64fa073e6650be535a636d451196573ab335380e55d18fc5560017fb5377912d16b1e486f0522e3c6466ee3300bff7ac467c63ecf38fe292414dea68190557f1fced590a37c503f7995284bc25ce0c18548f919df1e22d718b477212662be3c8190557f9ca80c1c75c5dc8b620a4b667020a6bc67065693a3787def70d2b49f68d9e7b58190557f69a0f76a76f82690b80861e6eaa6c5efde005b51c15857e9ee13261f66b547698190557fe80b15bfca1f0ac3d2d00a398c9145d06031a47d67fdb965244ed628316baaec8190557fc0eb925ddd257462cd18d86f1641000560a2a2f0a6600c8e2521b653420501cb5560057f986a66ea97cefefac8ffc61ca48a74912b3c250fc0b5038d75dc76455e53d22055600a7fab2dcbcb17a016732ef96d0b235ee1680423fb69b38cdf80dea1db4645b0f09e8190557f82941dfe3c875815adeef8f91b534f24c22d75f4d02d4791999544b47bfd55088190557f8b763ca6a0377d3638abd56c3a8de2acf50a1b1d974e668c0614a1e899b4a5d58190557fab7faf522ec145dfa67d8edd09d8e45a9b5a58f73477bcbb9cfb35389b3c70f981905560045f527fc0697d2f1fce52aa225d0458a7b27ad1956d52964cfd4c2be7f9306a6f1400ef60209081527ff25e5780730cba6006da78fa60737e4b45b23ce760013200bb1b5e90a21f034b9190915560408051606081019091526021808252909162006ed890830139602190620004fd908262000cb3565b5060408051808201909152601a81527f68747470733a2f2f73746172746c616e64732e696f2f53544c2f000000000000602082015260229062000541908262000cb3565b5060117f584f46c60af19681376031579adb04a2416e54ee5505351c2a8435e3766026ea5560417f9fafca4c9c0d5c2cbf85f49fd8ab8212430ce78c2a0cb75b51e0f9c4f9ace003556105dc7f1dd2f4b94a51cfb409e6e317a497f7cfd9013960a1c723f830c49c05a25f08a5556101167f804a3d0621e73505f5f0c57c922f3e57d6b48e175551184eb12f80d7b4a9c78355613c8c7fa952f8c0f40734b22d2328e0f7ff57eeffee78885b9cf2147ff941cc37e1c86e55670de0b6b3a76400007f71a639537cbf0c3eebd7f340a0e0c7adfac7798c9b8c2005c505347732bd2c988190556706f05b59d3b200007f2f0bd8bd14e1c1ec609324f83dd54fef6b2e972a389e51fac8ebaed38fb152d18190556703782dace9d900007f051c8eaf4c3de6d6cc6fc2ad1e77c449a768f1db89718a62394fecc5da7c5db3819055670214e8348c4f00007fadd8845f419e4157f2f3850fd9957a4b6cd5fa87be27370a1866bb816f2c1d96819055668a8e4b1a3d80007f994d2671de73a11992ab01589c8193f6f6ddb1808789f3ffae08791b1e4364318190557f1b9000d6d924ea5d820e567ecfe347f4a621f7450e51daf22f6ba52323a19c7d949094557fe111609d2df7971c39a0f940c0c2b98e3e7134d65890ee81416cacca5d7d7c39929092557fecaa15d4564c3153d6f37373ed5a034189b78d092d69f14fe496577f663fab33557fd634453058c00e9bb26303faf198ad9af079a083966e36e53c89bd88c5306b0c5560045f527ffa9ea797ae9193a6de7d03301fd0a2956781ee199efa6d28b4d65db274be0feb556025805462010000600160b01b03191675b4250f715995683c6ea5bc7c5e2cdf9b1601ba3f0000179055601c602052610d347fadacb2ae086d090ae1cbb87d66774fa6d708dd14d5bdc5b6c1e455aa2020dfb75562000ef7565b3390565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381165f9081526016602052604090205460ff16156200086d335b6001600160a01b03166014620009ed565b6040516020016200087f919062000da3565b60405160208183030381529060405290620008b85760405162461bcd60e51b8152600401620008af919062000dfb565b60405180910390fd5b506001600160a01b03165f908152601660205260409020805460ff19166001179055565b6127106001600160601b03821611156200094c5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401620008af565b6001600160a01b038216620009a45760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620008af565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601355565b620009e83362000ba9565b600f55565b60605f620009fd83600262000e43565b62000a0a90600262000e5d565b6001600160401b0381111562000a245762000a2462000c15565b6040519080825280601f01601f19166020018201604052801562000a4f576020820181803683370190505b509050600360fc1b815f8151811062000a6c5762000a6c62000e73565b60200101906001600160f81b03191690815f1a905350600f60fb1b8160018151811062000a9d5762000a9d62000e73565b60200101906001600160f81b03191690815f1a9053505f62000ac184600262000e43565b62000ace90600162000e5d565b90505b600181111562000b4f576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062000b065762000b0662000e73565b1a60f81b82828151811062000b1f5762000b1f62000e73565b60200101906001600160f81b03191690815f1a90535060049490941c9362000b478162000e87565b905062000ad1565b50831562000ba05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620008af565b90505b92915050565b6001600160a01b0381165f9081526016602052604090205460ff1662000bcf336200085c565b60405160200162000be1919062000e9f565b6040516020818303038152906040529062000c115760405162461bcd60e51b8152600401620008af919062000dfb565b5050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000c3e57607f821691505b60208210810362000c5d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000cae57805f5260205f20601f840160051c8101602085101562000c8a5750805b601f840160051c820191505b8181101562000cab575f815560010162000c96565b50505b505050565b81516001600160401b0381111562000ccf5762000ccf62000c15565b62000ce78162000ce0845462000c29565b8462000c63565b602080601f83116001811462000d1d575f841562000d055750858301515b5f19600386901b1c1916600185901b17855562000d77565b5f85815260208120601f198616915b8281101562000d4d5788860151825594840194600190910190840162000d2c565b508582101562000d6b57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f5b8381101562000d9b57818101518382015260200162000d81565b50505f910152565b67030b1b1b7bab73a160c51b81525f825162000dc781600885016020870162000d7f565b7f20697320616c72656164792068617320616e206f70657261746f7220726f6c656008939091019283015250602801919050565b602081525f825180602084015262000e1b81604085016020870162000d7f565b601f01601f19169190910160400192915050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141762000ba35762000ba362000e2f565b8082018082111562000ba35762000ba362000e2f565b634e487b7160e01b5f52603260045260245ffd5b5f8162000e985762000e9862000e2f565b505f190190565b67030b1b1b7bab73a160c51b81525f825162000ec381600885016020870162000d7f565b7f206973206e6f7420616e206f70657261746f72000000000000000000000000006008939091019283015250601b01919050565b615fd38062000f055f395ff3fe6080604052600436106104e7575f3560e01c8063715018a611610289578063b6cbcf3311610158578063da359dc8116100c5578063da359dc81461102d578063da3ef23f1461104c578063df58a1b51461106b578063e0617ce314611080578063e8a3d485146110ab578063e985e9c5146110bf578063ed441adc146110de578063f093888914611109578063f2fde38b14611137578063f95d844214611156578063fb796e6c1461118c578063fe335dee14610a92578063ff768212146111a5575f80fd5b8063b6cbcf3314610e98578063b7c0b8e814610ec3578063b88d4fde14610ee2578063bb06f36614610f01578063bbaac02f14610f20578063bc6d75a414610f3f578063c3cef93914610f5e578063c50c818614610f7d578063c82bf41814610f9c578063c87b56dd14610fbb578063ca5c7a3414610fda578063d2de022f14610ff9578063d5abeb0114611018575f80fd5b806395d89b41116101f657806395d89b4114610ce357806396b0617614610cf7578063979c4a9c14610d165780639da9778c14610d355780639e23c3e714610d3d578063a22cb46514610d5c578063a355fd2914610d7b578063a35c23ad14610d9a578063a8da8c1214610dc5578063ab1e8e6314610de4578063abdc331314610e1a578063b219f7d714610e4e578063b31391cb14610e6d575f80fd5b8063715018a614610b6457806372b44d7114610b785780637558be9e14610b9757806377d744d514610bb65780637c3dc17314610bd55780637e26b0d014610bf45780637fc69f5a14610c13578063829aee9714610c28578063830b3a6414610c535780638462151c14610c725780638528eefe14610c915780638da5cb5b14610cb057806391e4bac814610cc4575f80fd5b806330e7ed35116103c5578063438b630011610332578063438b6300146109d45780634bf365df14610a005780634f3db34614610a155780635183022714610a2a57806355f804b314610a3f5780635638697b14610a5e57806358303b1014610a7d5780635b075f3614610a925780636352211e14610ab15780636d70f7ae14610ad05780636f8b44b014610b075780636fa0cf5f14610b2657806370a0823114610b45575f80fd5b806330e7ed351461085a578063396e8f53146108795780633bdfce02146108985780633ccfd60b146108ab5780633df669f7146108b35780633f91fd04146108c85780633fff74bd146108f35780634009920d14610912578063405059601461092b57806341f434341461095657806342842e0e1461097757806342966c6814610996578063435e4ccd146109b5575f80fd5b806318160ddd1161046357806318160ddd146106b65780631a549a7c146106ca5780631a8b8357146106dd5780631ce5ed6c14610708578063214e4a05146107275780632398f8431461074657806323b872dd146107715780632672c9021461079057806327ac0c58146107a45780632a3d9667146107c35780632a55205a146107ef5780632cbf810f1461081c5780632f9ff2ed1461083b575f80fd5b80623f332f146104eb57806301ffc9a714610515578063025e332e1461054457806304634d8d1461056557806306fdde031461058457806307265389146105a5578063081812fc146105be578063095ea7b3146105ea5780630d9005ae146106095780630f4345e21461062b57806310637d8a1461064a5780631562eea414610697575b5f80fd5b3480156104f6575f80fd5b506104ff6111c4565b60405161050c9190614f03565b60405180910390f35b348015610520575f80fd5b5061053461052f366004614f64565b6111d3565b604051901515815260200161050c565b34801561054f575f80fd5b5061056361055e366004614f93565b6111e3565b005b348015610570575f80fd5b5061056361057f366004614fae565b61120d565b34801561058f575f80fd5b50610598611224565b60405161050c919061503d565b3480156105b0575f80fd5b50600c546105349060ff1681565b3480156105c9575f80fd5b506105dd6105d836600461504f565b6112b4565b60405161050c9190615066565b3480156105f5575f80fd5b5061056361060436600461507a565b611342565b348015610614575f80fd5b5061061d6114d8565b60405190815260200161050c565b348015610636575f80fd5b5061056361064536600461504f565b6114ee565b348015610655575f80fd5b5061061d61066436600461507a565b601e545f908152602c6020908152604080832084845282528083206001600160a01b038616845290915290205492915050565b3480156106a2575f80fd5b506105636106b13660046150a4565b6114fc565b3480156106c1575f80fd5b5061061d6115cc565b6105636106d83660046150cd565b6115dd565b3480156106e8575f80fd5b5061061d6106f736600461504f565b60286020525f908152604090205481565b348015610713575f80fd5b506105636107223660046150a4565b611837565b348015610732575f80fd5b506105636107413660046150a4565b61185b565b348015610751575f80fd5b5061061d610760366004614f93565b600e6020525f908152604090205481565b34801561077c575f80fd5b5061056361078b366004615103565b61187f565b34801561079b575f80fd5b50610598611967565b3480156107af575f80fd5b506105636107be366004614f93565b6119f3565b3480156107ce575f80fd5b506107e26107dd366004614f93565b611a04565b60405161050c9190615141565b3480156107fa575f80fd5b5061080e6108093660046151c7565b611be3565b60405161050c9291906151e7565b348015610827575f80fd5b506105636108363660046151c7565b611c8f565b348015610846575f80fd5b50610563610855366004614f93565b611ca8565b348015610865575f80fd5b5061056361087436600461504f565b611cef565b348015610884575f80fd5b506009546105dd906001600160a01b031681565b6105636108a63660046152d2565b611cfd565b610563611fe0565b3480156108be575f80fd5b5061061d60325481565b3480156108d3575f80fd5b5061061d6108e236600461504f565b601b6020525f908152604090205481565b3480156108fe575f80fd5b5061056361090d3660046151c7565b612110565b34801561091d575f80fd5b506025546105349060ff1681565b348015610936575f80fd5b5061061d61094536600461504f565b5f9081526027602052604090205490565b348015610961575f80fd5b506105dd6daaeb6d7670e522a718067333cd4e81565b348015610982575f80fd5b50610563610991366004615103565b61212a565b3480156109a1575f80fd5b506105636109b036600461504f565b612207565b3480156109c0575f80fd5b506105636109cf366004615346565b6122a7565b3480156109df575f80fd5b506109f36109ee366004614f93565b6122ca565b60405161050c9190615361565b348015610a0b575f80fd5b5061061d601a5481565b348015610a20575f80fd5b5061061d600f5481565b348015610a35575f80fd5b5061061d601d5481565b348015610a4a575f80fd5b50610563610a593660046153ec565b6123ef565b348015610a69575f80fd5b50610563610a7836600461546d565b612404565b348015610a88575f80fd5b5061061d60125481565b348015610a9d575f80fd5b50610563610aac3660046151c7565b61249d565b348015610abc575f80fd5b506105dd610acb36600461504f565b6124b7565b348015610adb575f80fd5b50610534610aea366004614f93565b6001600160a01b03165f9081526016602052604090205460ff1690565b348015610b12575f80fd5b50610563610b2136600461504f565b6124ca565b348015610b31575f80fd5b50610563610b403660046151c7565b6124d8565b348015610b50575f80fd5b5061061d610b5f366004614f93565b6124f2565b348015610b6f575f80fd5b506105636125b7565b348015610b83575f80fd5b50610563610b92366004614f93565b6125c8565b348015610ba2575f80fd5b50610563610bb136600461504f565b6125da565b348015610bc1575f80fd5b506026546105dd906001600160a01b031681565b348015610be0575f80fd5b50610563610bef3660046151c7565b6125e7565b348015610bff575f80fd5b5061061d610c0e36600461504f565b612676565b348015610c1e575f80fd5b5061061d601f5481565b348015610c33575f80fd5b5061061d610c4236600461504f565b602a6020525f908152604090205481565b348015610c5e575f80fd5b506105dd610c6d36600461504f565b6126a8565b348015610c7d575f80fd5b506109f3610c8c366004614f93565b61270d565b348015610c9c575f80fd5b50610563610cab3660046154b4565b6127d1565b348015610cbb575f80fd5b506105dd6127f9565b348015610ccf575f80fd5b50610563610cde36600461504f565b612807565b348015610cee575f80fd5b50610598612815565b348015610d02575f80fd5b5061061d610d113660046154d7565b612824565b348015610d21575f80fd5b50610563610d303660046154fb565b612865565b6105636128f1565b348015610d48575f80fd5b506105dd610d573660046151c7565b612922565b348015610d67575f80fd5b50610563610d763660046155ca565b612950565b348015610d86575f80fd5b50610563610d95366004615346565b612a11565b348015610da5575f80fd5b50610563610db436600461504f565b335f908152600e6020526040902055565b348015610dd0575f80fd5b5061061d610ddf36600461504f565b612a2d565b348015610def575f80fd5b5061061d610dfe3660046151c7565b602960209081525f928352604080842090915290825290205481565b348015610e25575f80fd5b50610e39610e3436600461504f565b612a72565b6040805192835260208301919091520161050c565b348015610e59575f80fd5b50610563610e68366004614f93565b612aa9565b348015610e78575f80fd5b5061061d610e8736600461504f565b600d6020525f908152604090205481565b348015610ea3575f80fd5b5061061d610eb236600461504f565b60276020525f908152604090205481565b348015610ece575f80fd5b50610563610edd366004615346565b612aba565b348015610eed575f80fd5b50610563610efc3660046155f6565b612ad6565b348015610f0c575f80fd5b50610563610f1b3660046151c7565b612bba565b348015610f2b575f80fd5b50610563610f3a3660046153ec565b612bd4565b348015610f4a575f80fd5b50610563610f59366004615664565b612be9565b348015610f69575f80fd5b5061061d610f783660046150cd565b612c81565b348015610f88575f80fd5b50610563610f9736600461504f565b612cf7565b348015610fa7575f80fd5b50610e39610fb636600461504f565b612d05565b348015610fc6575f80fd5b50610598610fd536600461504f565b612d25565b348015610fe5575f80fd5b5061061d610ff43660046151c7565b612df2565b348015611004575f80fd5b506105346110133660046156a0565b612e6f565b348015611023575f80fd5b5061061d60195481565b348015611038575f80fd5b506105636110473660046156f4565b612f8f565b348015611057575f80fd5b506105636110663660046153ec565b61301d565b348015611076575f80fd5b5061061d601e5481565b34801561108b575f80fd5b5061061d61109a36600461504f565b60186020525f908152604090205481565b3480156110b6575f80fd5b50610598613032565b3480156110ca575f80fd5b506105346110d9366004615732565b61303c565b3480156110e9575f80fd5b5061061d6110f836600461504f565b601c6020525f908152604090205481565b348015611114575f80fd5b5061053461112336600461504f565b60246020525f908152604090205460ff1681565b348015611142575f80fd5b50610563611151366004614f93565b613083565b348015611161575f80fd5b5061061d6111703660046151c7565b601760209081525f928352604080842090915290825290205481565b348015611197575f80fd5b506015546105349060ff1681565b3480156111b0575f80fd5b506105636111bf366004614f93565b6130f9565b60606111ce61310b565b905090565b5f6111dd82613117565b92915050565b6111ec3361313b565b600980546001600160a01b0319166001600160a01b03831617905550565b50565b6112163361313b565b61122082826131a8565b5050565b6060600280546112339061575e565b80601f016020809104026020016040519081016040528092919081815260200182805461125f9061575e565b80156112aa5780601f10611281576101008083540402835291602001916112aa565b820191905f5260205f20905b81548152906001019060200180831161128d57829003601f168201915b5050505050905090565b5f6112be826132a1565b6113275760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084015b60405180910390fd5b505f908152600660205260409020546001600160a01b031690565b816daaeb6d7670e522a718067333cd4e3b15801590611363575060155460ff165b156113f957604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c61711349061139b9030908590600401615790565b602060405180830381865afa1580156113b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113da91906157aa565b6113f95780604051633b79c77360e21b815260040161131e9190615066565b60255460405163d68f4dd160e01b8152600481018490526001916201000090046001600160a01b03169063d68f4dd190602401602060405180830381865afa158015611447573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146b91906157c5565b106114c95760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420617070726f76652c207472616e7366657272696e67206e6f7460448201526708185b1b1bddd95960c21b606482015260840161131e565b6114d383836132c2565b505050565b5f60016114e460055490565b6111ce91906157f0565b6114f73361313b565b600f55565b6115053361313b565b5f5b818110156115a4575f61151a8286615803565b90505f610122821180156115305750610e568211155b15611556575f611542610123846157f0565b905061154e81876132d6565b91505061157f565b5f858152601c602052604081205461156f908590615803565b905061157b81876132d6565b9150505b5f828152602f6020526040902081905561159a818684613384565b5050600101611507565b505f828152601c6020526040812080548392906115c2908490615803565b9091555050505050565b5f6115d56134b3565b6114e4613508565b6115e5613518565b60255460ff1661162e5760405162461bcd60e51b81526020600482015260146024820152731c1d589b1a58d35a5b9d081a5cc814185d5cd95960621b604482015260640161131e565b5f838152602a60205260409020548211156116995760405162461bcd60e51b815260206004820152602560248201527f7075626c69634d696e743a204f766572206d6178206d696e7473207065722077604482015264185b1b195d60da1b606482015260840161131e565b601e545f908152602c6020908152604080832086845282528083206001600160a01b03851684529091529020546116d1908390615803565b5f848152602a6020526040902054101561172b5760405162461bcd60e51b815260206004820152601b60248201527a165bdd481a185d99481b9bc81c1d589b1a58d35a5b9d081b19599d602a1b604482015260640161131e565b5f83815260186020526040902054611744908390615816565b34146117625760405162461bcd60e51b815260040161131e9061582d565b601a5461176d6115cc565b6117779084615803565b11156117955760405162461bcd60e51b815260040161131e9061585f565b5f838152601b6020908152604080832054601c909252909120546117b99084615803565b11156117d75760405162461bcd60e51b815260040161131e90615885565b601e545f908152602c6020908152604080832086845282528083206001600160a01b038516845290915281208054849290611813908490615803565b9091555061182390508383613571565b61182d818361360c565b6114d36001601055565b6118403361313b565b5f928352601760209081526040808520938552929052912055565b6118643361313b565b5f928352602960209081526040808520938552929052912055565b826daaeb6d7670e522a718067333cd4e3b158015906118a0575060155460ff165b1561195657336001600160a01b038216036118c5576118c0848484613625565b611961565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c6171134906118f89030903390600401615790565b602060405180830381865afa158015611913573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061193791906157aa565b6119565733604051633b79c77360e21b815260040161131e9190615066565b611961848484613625565b50505050565b602380546119749061575e565b80601f01602080910402602001604051908101604052809291908181526020018280546119a09061575e565b80156119eb5780601f106119c2576101008083540402835291602001916119eb565b820191905f5260205f20905b8154815290600101906020018083116119ce57829003601f168201915b505050505081565b6119fb613656565b61120a816136b5565b60605f611a10836124f2565b90505f816001600160401b03811115611a2b57611a2b615200565b604051908082528060200260200182016040528015611a5e57816020015b6060815260200190600190039081611a495790505b5090505f60015b6001611a7060055490565b611a7a91906157f0565b8111611bd9576040516320c2ce9960e21b815260048101829052309063830b3a6490602401602060405180830381865afa158015611aba573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ade91906158ae565b6001600160a01b0316866001600160a01b031603611bc7575f80611b04610e3484612a2d565b6040805160028082526060820190925292945090925081602001602082028036833701905050858581518110611b3c57611b3c6158c9565b602002602001018190525081858581518110611b5a57611b5a6158c9565b60200260200101515f81518110611b7357611b736158c9565b60200260200101818152505080858581518110611b9257611b926158c9565b6020026020010151600181518110611bac57611bac6158c9565b602090810291909101015283611bc1816158dd565b94505050505b80611bd1816158dd565b915050611a65565b5090949350505050565b5f8281526014602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291611c575750604080518082019091526013546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090611c75906001600160601b031687615816565b611c7f91906158f5565b91519350909150505b9250929050565b611c983361313b565b5f90815260186020526040902055565b611cb13361313b565b602680546001600160a01b0319166001600160a01b039290921691821790556025805462010000600160b01b03191662010000909202919091179055565b611cf83361313b565b601e55565b611d05613518565b5f8581526024602052604090205460ff16611d5c5760405162461bcd60e51b8152602060048201526017602482015276185b1b1bdddb1a5cdd135a5b9d081a5cc814185d5cd959604a1b604482015260640161131e565b611d67828683612e6f565b611dae5760405162461bcd60e51b8152602060048201526018602482015277596f7520617265206e6f742077686974656c69737465642160401b604482015260640161131e565b82611dba868685612c81565b1015611e195760405162461bcd60e51b815260206004820152602860248201527f616c6c6f776c6973744d696e743a204f766572206d6178206d696e74732070656044820152671c881dd85b1b195d60c21b606482015260840161131e565b5f858152602b6020908152604080832060278352818420548452825280832087845282528083206001600160a01b0386168452909152902054611e5d908490615803565b611e68868685612c81565b1015611eb65760405162461bcd60e51b815260206004820152601e60248201527f596f752068617665206e6f2077686974656c6973744d696e74206c6566740000604482015260640161131e565b5f858152601760209081526040808320878452909152902054611eda908490615816565b3414611ef85760405162461bcd60e51b815260040161131e9061582d565b601a54611f036115cc565b611f0d9085615803565b1115611f2b5760405162461bcd60e51b815260040161131e9061585f565b5f848152601b6020908152604080832054601c90925290912054611f4f9085615803565b1115611f6d5760405162461bcd60e51b815260040161131e90615885565b5f858152602b6020908152604080832060278352818420548452825280832087845282528083206001600160a01b038616845290915281208054859290611fb5908490615803565b90915550611fc590508484613571565b611fcf828461360c565b611fd96001601055565b5050505050565b611fe93361313b565b611ff1613518565b60205447905f906001600160a01b031615612060576020546040516001600160a01b039091169083905f81818185875af1925050503d805f8114612050576040519150601f19603f3d011682016040523d82523d5f602084013e612055565b606091505b5050809150506120ba565b6120686127f9565b6001600160a01b0316826040515f6040518083038185875af1925050503d805f81146120af576040519150601f19603f3d011682016040523d82523d5f602084013e6120b4565b606091505b50909150505b806121025760405162461bcd60e51b81526020600482015260186024820152772330b4b632b2103a37903bb4ba34323930bb9022ba3432b960411b604482015260640161131e565b505061210e6001601055565b565b6121193361313b565b5f918252602a602052604090912055565b826daaeb6d7670e522a718067333cd4e3b1580159061214b575060155460ff165b156121fc57336001600160a01b0382160361216b576118c084848461373b565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c61711349061219e9030903390600401615790565b602060405180830381865afa1580156121b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dd91906157aa565b6121fc5733604051633b79c77360e21b815260040161131e9190615066565b61196184848461373b565b33612211826124b7565b6001600160a01b03161461225a5760405162461bcd60e51b815260206004820152601060248201526f34b9b73a1037bbb732b9103a37b5b2b760811b604482015260640161131e565b602554610100900460ff161561229e5760405162461bcd60e51b81526020600482015260096024820152686e6f7420616c6c6f7760b81b604482015260640161131e565b61120a81613755565b6122b03361313b565b602580549115156101000261ff0019909216919091179055565b60605f6122d6836124f2565b90505f816001600160401b038111156122f1576122f1615200565b60405190808252806020026020018201604052801561231a578160200160208202803683370190505b5090505f60015b600161232c60055490565b61233691906157f0565b8111611bd9576040516320c2ce9960e21b815260048101829052309063830b3a6490602401602060405180830381865afa158015612376573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061239a91906158ae565b6001600160a01b0316866001600160a01b0316036123dd578083836123be816158dd565b9450815181106123d0576123d06158c9565b6020026020010181815250505b806123e7816158dd565b915050612321565b6123f83361313b565b60226112208282615958565b61240d3361313b565b61244b83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506137aa92505050565b6031828154811061245e5761245e6158c9565b5f91825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055603154612495906001906157f0565b603255505050565b6124a63361313b565b5f9182526027602052604090912055565b5f806124c28361380d565b509392505050565b6124d33361313b565b601955565b6124e13361313b565b5f9182526011602052604090912055565b5f6001600160a01b03821661255f5760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b606482015260840161131e565b5f60015b6005548110156125b057612576816132a1565b156125a857612584816124b7565b6001600160a01b0316846001600160a01b0316036125a8576125a5826158dd565b91505b600101612563565b5092915050565b6125bf613656565b61210e5f6138a2565b6125d13361313b565b61120a816138f1565b6125e2613656565b601f55565b816125f1816124b7565b6001600160a01b0316336001600160a01b0316146126645760405162461bcd60e51b815260206004820152602a60248201527f5265737472696374417070726f76653a206f7065726174696f6e206973206f6e604482015269363c903437b63232b91760b11b606482015260840161131e565b505f918252600d602052604090912055565b5f818152603060205260408120541561269b57505f9081526030602052604090205490565b506001919050565b919050565b6040516331a9108f60e11b8152600481018290525f903090636352211e90602401602060405180830381865afa925050508015612702575060408051601f3d908101601f191682019092526126ff918101906158ae565b60015b6111dd57505f919050565b60605f8061271a846124f2565b90505f816001600160401b0381111561273557612735615200565b60405190808252806020026020018201604052801561275e578160200160208202803683370190505b50905060015b8284146127c857612774816132a1565b156127c057856001600160a01b031661278c826124b7565b6001600160a01b0316036127c057808285806001019650815181106127b3576127b36158c9565b6020026020010181815250505b600101612764565b50949350505050565b6127da3361313b565b5f91825260246020526040909120805460ff1916911515919091179055565b5f546001600160a01b031690565b6128103361313b565b601a55565b6060600380546112339061575e565b5f838152602b6020908152604080832060278352818420548452825280832084845282528083206001600160a01b03861684529091529020545b9392505050565b61286e3361313b565b5f5b8251811015611fd95781818151811061288b5761288b6158c9565b6020026020010151602e5f8781526020019081526020015f205f8681526020019081526020015f205f8584815181106128c6576128c66158c9565b6020908102919091018101516001600160a01b031682528101919091526040015f2055600101612870565b6128f9613518565b5f34116129185760405162461bcd60e51b815260040161131e9061582d565b61210e6001601055565b5f8061292e8484612df2565b905080156129475761293f816124b7565b9150506111dd565b505f9392505050565b816daaeb6d7670e522a718067333cd4e3b15801590612971575060155460ff165b15612a0757604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c6171134906129a99030908590600401615790565b602060405180830381865afa1580156129c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e891906157aa565b612a075780604051633b79c77360e21b815260040161131e9190615066565b6114d38383613935565b612a1a3361313b565b6025805460ff1916911515919091179055565b5f61012282118015612a415750610e568211155b15612a60575f612a53610123846157f0565b905061285e8160046132d6565b505f908152602f602052604090205490565b5f8061ffff601084901c811690841682612a8d60aa84615a13565b90505f612a9b60af84615a13565b919791965090945050505050565b612ab1613656565b61120a816139b3565b612ac33361313b565b6015805460ff1916911515919091179055565b836daaeb6d7670e522a718067333cd4e3b15801590612af7575060155460ff165b15612bae57336001600160a01b03821603612b1d57612b18858585856139dc565b611fd9565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c617113490612b509030903390600401615790565b602060405180830381865afa158015612b6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8f91906157aa565b612bae5733604051633b79c77360e21b815260040161131e9190615066565b611fd9858585856139dc565b612bc33361313b565b5f918252601b602052604090912055565b612bdd3361313b565b60216112208282615958565b612bf23361313b565b601954612bfd6115cc565b612c079085615803565b1115612c255760405162461bcd60e51b815260040161131e9061585f565b5f848152601b6020908152604080832054601c90925290912054612c499085615803565b1115612c675760405162461bcd60e51b815260040161131e90615885565b8015612c7757612c778484613571565b611961828461360c565b5f838152602960209081526040808320858452825280832054868452602e835281842086855283528184206001600160a01b038616855290925282205415612cef57505f848152602e6020908152604080832086845282528083206001600160a01b03861684529091529020545b949350505050565b612d003361313b565b601d55565b5f80612d103361313b565b612d1c610e3484612a2d565b91509150915091565b6060612d30826132a1565b612d7c5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00604482015260640161131e565b612d8882601d54101590565b15612dd057612d95613a0e565b612da6612da184612a2d565b613a1d565b6023604051602001612dba93929190615aa1565b6040516020818303038152906040529050919050565b6021612dde612da184612676565b6023604051602001612dba93929190615add565b5f82815b6014811215612e65575f858152602d6020908152604080832087845290915290205415612e3e575050505f828152602d602090815260408083208484529091529020546111dd565b84612e4881615af8565b9550612e579050826014615b0f565b8513612e6557600101612df6565b505f949350505050565b6040516001600160601b0319606085901b1660208201525f9081906034016040516020818303038152906040528051906020012090505f5b8351811015612f7657838181518110612ec257612ec26158c9565b60200260200101518210612f2057838181518110612ee257612ee26158c9565b602002602001015182604051602001612f05929190918252602082015260400190565b60405160208183030381529060405280519060200120612f6c565b81848281518110612f3357612f336158c9565b6020026020010151604051602001612f55929190918252602082015260400190565b604051602081830303815290604052805190602001205b9150600101612ea7565b505f848152601160205260409020541490509392505050565b612f983361313b565b6031612fd883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506137aa92505050565b8154600180820184555f93845260209093200180546001600160a01b0319166001600160a01b039290921691909117905560315461301691906157f0565b6032555050565b6130263361313b565b60236112208282615958565b60606111ce613aac565b5f6130478383613b2b565b15155f0361305657505f6111dd565b6001600160a01b038084165f9081526007602090815260408083209386168352929052205460ff1661285e565b61308b613656565b6001600160a01b0381166130f05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161131e565b61120a816138a2565b6131023361313b565b61120a81613b42565b60606111ce600a613b86565b5f6001600160e01b0319821663152a902d60e11b14806111dd57506111dd82613b92565b6001600160a01b0381165f9081526016602052604090205460ff1661316b335b6001600160a01b03166014613bb6565b60405160200161317b9190615b36565b604051602081830303815290604052906112205760405162461bcd60e51b815260040161131e919061503d565b6127106001600160601b03821611156132165760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840161131e565b6001600160a01b0382166132685760405162461bcd60e51b815260206004820152601960248201527822a921991c9c189d1034b73b30b634b2103932b1b2b4bb32b960391b604482015260640161131e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601355565b5f6132ad600883613d4b565b156132b957505f919050565b6111dd82613d71565b6132cc8282613d8c565b6112208282613e07565b5f81816132e4856004615816565b90506003841115613337576132fb611180866158f5565b613306906004615803565b91506133136004836157f0565b61331f90611180615816565b61332990866157f0565b613334906004615816565b90505b5f6133736031848154811061334e5761334e6158c9565b5f918252602090912001546001600160a01b03168361336e816004615803565b613f16565b6020015160e01c9695505050505050565b5f8061338f85612a72565b915091505f805f865f036133ad5750600a9150600990506014613413565b866001036133c557506004915060059050600a613413565b866002036133dc5750600291508190506005613413565b866003036133f35750600191508190506003613413565b5050505f918252602d602090815260408084209284529190529020555050565b5f86815260306020526040812082905561342d8487615a13565b90505f600161343c8484615b0f565b6134469190615a13565b90505f6134538588615a13565b90505f60016134628684615b0f565b61346c9190615a13565b9050815b8181136134a4575f848152602d6020908152604080832084845290915290208b90558061349c81615af8565b915050613470565b50505050505050505050505050565b6005545f90819081906134ca9060081c6001615803565b9050815b81811015613502575f818152600860205260409020546134ed81613f37565b6134f79086615803565b9450506001016134ce565b50505090565b5f60016005546111ce91906157f0565b60026010540361356a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161131e565b6002601055565b5f61357a6115cc565b613585906001615803565b90505f5b828110156135ee575f61359c8284615803565b5f868152601c6020526040812054919250906135b9908490615803565b90505f6135c682886132d6565b5f848152602f6020526040902081905590506135e3818885613384565b505050600101613589565b505f838152601c6020526040812080548492906115c2908490615803565b611220828260405180602001604052805f815250613f4f565b61362f3382613f8e565b61364b5760405162461bcd60e51b815260040161131e90615b82565b6114d3838383614051565b3361365f6127f9565b6001600160a01b03161461210e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161131e565b6001600160a01b0381165f9081526016602052604090205460ff16156136da3361315b565b6040516020016136ea9190615bd6565b604051602081830303815290604052906137175760405162461bcd60e51b815260040161131e919061503d565b506001600160a01b03165f908152601660205260409020805460ff19166001179055565b6114d383838360405180602001604052805f815250612ad6565b5f61375f826124b7565b905061376e815f84600161422b565b613779600883614321565b60405182905f906001600160a01b038416905f80516020615e7e833981519152908390a4611220815f84600161434c565b5f806137d4836040516020016137c09190615c2c565b60405160208183030381529060405261436e565b90508051602082015ff091506001600160a01b0382166138075760405163046a55db60e11b815260040160405180910390fd5b50919050565b5f80613818836132a1565b6138795760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161131e565b61388283614384565b5f818152600460205260409020546001600160a01b031694909350915050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6138fc600a82614390565b506040516001600160a01b0382169033907f3b01c97343869ca2757fcc37cdb8f71683b0a7aed858e3755f4529a1db857292905f90a350565b61393e826143a4565b80613947575080155b6139a95760405162461bcd60e51b815260206004820152602d60248201527f5265737472696374417070726f76653a2043616e206e6f7420617070726f766560448201526c103637b1b5b2b2103a37b5b2b760991b606482015260840161131e565b61122082826143af565b6139bc8161313b565b6001600160a01b03165f908152601660205260409020805460ff19169055565b6139e63383613f8e565b613a025760405162461bcd60e51b815260040161131e90615b82565b61196184848484614472565b6060602280546112339061575e565b60605f613a298361448b565b60010190505f816001600160401b03811115613a4757613a47615200565b6040519080825280601f01601f191660200182016040528015613a71576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613a7b57509392505050565b60605f80613abc81612710611be3565b91509150613b05613acc82613a1d565b613ae0846001600160a01b03166014613bb6565b604051602001613af1929190615c50565b604051602081830303815290604052614560565b604051602001613b159190615cd4565b6040516020818303038152906040529250505090565b5f80613b36846146be565b9050612cef83826146fe565b613b4d600a82614792565b506040516001600160a01b0382169033907fbd0af1fe0a2c1c7bb340c17a284a291138979c8eeb797e176dbd1c415199af3c905f90a350565b60605f61285e836147a6565b5f6001600160e01b03198216630101c11560e71b14806111dd57506111dd826147ff565b60605f613bc4836002615816565b613bcf906002615803565b6001600160401b03811115613be657613be6615200565b6040519080825280601f01601f191660200182016040528015613c10576020820181803683370190505b509050600360fc1b815f81518110613c2a57613c2a6158c9565b60200101906001600160f81b03191690815f1a905350600f60fb1b81600181518110613c5857613c586158c9565b60200101906001600160f81b03191690815f1a9053505f613c7a846002615816565b613c85906001615803565b90505b6001811115613cfc576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613cb957613cb96158c9565b1a60f81b828281518110613ccf57613ccf6158c9565b60200101906001600160f81b03191690815f1a90535060049490941c93613cf581615d18565b9050613c88565b50831561285e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161131e565b600881901c5f90815260208390526040902054600160ff1b60ff83161c16151592915050565b5f613d7b60055490565b821080156111dd5750506001111590565b6001600160a01b0382161561122057613da5818361484e565b6112205760405162461bcd60e51b815260206004820152602d60248201527f5265737472696374417070726f76653a2054686520636f6e747261637420697360448201526c103737ba1030b63637bbb2b21760991b606482015260840161131e565b5f613e11826124b7565b9050806001600160a01b0316836001600160a01b031603613e805760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b606482015260840161131e565b336001600160a01b0382161480613e9c5750613e9c813361303c565b613f0c5760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b606482015260840161131e565b6114d3838361485a565b6060612cef84613f27856001615803565b613f32856001615803565b6148c7565b5f5b81156126a3575f19820190911690600101613f39565b5f613f5960055490565b9050613f658484614978565b613f725f85838686614ae1565b6119615760405162461bcd60e51b815260040161131e90615d2d565b5f613f98826132a1565b613ffc5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161131e565b5f614006836124b7565b9050806001600160a01b0316846001600160a01b031614806140415750836001600160a01b0316614036846112b4565b6001600160a01b0316145b80612cef5750612cef818561303c565b5f8061405c8361380d565b91509150846001600160a01b0316826001600160a01b0316146140d65760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b606482015260840161131e565b6001600160a01b03841661413c5760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b606482015260840161131e565b614149858585600161422b565b6141535f8461485a565b5f61415f846001615803565b905061416c600182613d4b565b15801561417a575060055481105b156141b0575f81815260046020526040902080546001600160a01b0319166001600160a01b0388161790556141b0600182614321565b5f84815260046020526040902080546001600160a01b0319166001600160a01b0387161790558184146141e8576141e8600185614321565b83856001600160a01b0316876001600160a01b03165f80516020615e7e83398151915260405160405180910390a4614223868686600161434c565b505050505050565b6001600160a01b038416156118c0575f5b8181101561431b575f61424f8285615803565b60255460405163d68f4dd160e01b815260048101839052919250600191620100009091046001600160a01b03169063d68f4dd190602401602060405180830381865afa1580156142a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142c591906157c5565b106143125760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207472616e736665722c20746f6b656e206973206c6f636b6564604482015260640161131e565b5060010161423c565b50611961565b600881901c5f90815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b6001600160a01b03841615611961575f828152600d6020526040812055611961565b6060815182604051602001612dba929190615d82565b5f6111dd600183614c0a565b5f61285e836001600160a01b038416614cfe565b5f6111dd3383613b2b565b336001600160a01b038316036144075760405162461bcd60e51b815260206004820152601c60248201527f4552433732315073693a20617070726f766520746f2063616c6c657200000000604482015260640161131e565b335f8181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61447d848484614051565b613f72848484600185614ae1565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106144c95772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b83106144f3576904ee2d6d415b85acef8160201b830492506020015b662386f26fc10000831061451157662386f26fc10000830492506010015b6305f5e1008310614529576305f5e100830492506008015b612710831061453d57612710830492506004015b6064831061454f576064830492506002015b600a83106111dd5760010192915050565b606081515f0361457d57505060408051602081019091525f815290565b5f604051806060016040528060408152602001615e3e6040913990505f6003845160026145aa9190615803565b6145b491906158f5565b6145bf906004615816565b90505f6145cd826020615803565b6001600160401b038111156145e4576145e4615200565b6040519080825280601f01601f19166020018201604052801561460e576020820181803683370190505b509050818152600183018586518101602084015b8183101561467a576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101614622565b60038951066001811461469457600281146146a5576146b0565b613d3d60f01b6001198301526146b0565b603d60f81b5f198301525b509398975050505050505050565b6001600160a01b0381165f908152600e6020526040812054156146f657506001600160a01b03165f908152600e602052604090205490565b5050600f5490565b600c545f9060ff16614712575060016111dd565b61471b83614de1565b8061285e5750600954604051630f8350ed60e41b81526001600160a01b039091169063f8350ed09061475390869086906004016151e7565b602060405180830381865afa15801561476e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061285e91906157aa565b5f61285e836001600160a01b038416614e09565b6060815f018054806020026020016040519081016040528092919081815260200182805480156147f357602002820191905f5260205f20905b8154815260200190600101908083116147df575b50505050509050919050565b5f6001600160e01b031982166380ac58cd60e01b148061482f57506001600160e01b03198216635b5e139f60e01b145b806111dd57506301ffc9a760e01b6001600160e01b03198316146111dd565b5f80613b363385614e55565b5f81815260066020526040902080546001600160a01b0319166001600160a01b038416908117909155819061488e826124b7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6060833b5f8190036148e857505060408051602081019091525f815261285e565b8084111561490557505060408051602081019091525f815261285e565b838310156149375760405163162544fd60e11b815260048101829052602481018590526044810184905260640161131e565b8383038482035f82821061494b578261494d565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b5f61498260055490565b90505f82116149e15760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b606482015260840161131e565b6001600160a01b038316614a435760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b606482015260840161131e565b614a4f5f84838561422b565b8160055f828254614a609190615803565b90915550505f81815260046020526040902080546001600160a01b0319166001600160a01b038516179055614a96600182614321565b614aa25f84838561434c565b805b614aae8383615803565b8110156119615760405181906001600160a01b038616905f905f80516020615e7e833981519152908290a4600101614aa4565b5f6001600160a01b0385163b15614bfd57506001835b614b018486615803565b811015614bf757604051630a85bd0160e11b81526001600160a01b0387169063150b7a0290614b3a9033908b9086908990600401615dd2565b6020604051808303815f875af1925050508015614b74575060408051601f3d908101601f19168201909252614b7191810190615e0e565b60015b614bcf573d808015614ba1576040519150601f19603f3d011682016040523d82523d5f602084013e614ba6565b606091505b5080515f03614bc75760405162461bcd60e51b815260040161131e90615d2d565b805181602001fd5b828015614bec57506001600160e01b03198116630a85bd0160e11b145b925050600101614af7565b50614c01565b5060015b95945050505050565b600881901c5f8181526020849052604081205490919060ff808516919082181c8015614c4b57614c3981614e85565b60ff168203600884901b179350614cf5565b5f8311614cb75760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b606482015260840161131e565b505f199091015f818152602086905260409020549091908015614cf057614cdd81614e85565b60ff0360ff16600884901b179350614cf5565b614c4b565b50505092915050565b5f8181526001830160205260408120548015614dd8575f614d206001836157f0565b85549091505f90614d33906001906157f0565b9050818114614d92575f865f018281548110614d5157614d516158c9565b905f5260205f200154905080875f018481548110614d7157614d716158c9565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080614da357614da3615e29565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f9055600193505050506111dd565b5f9150506111dd565b5f6111dd600a836001600160a01b0381165f908152600183016020526040812054151561285e565b5f818152600183016020526040812054614e4e57508154600181810184555f8481526020808220909301849055845484825282860190935260409020919091556111dd565b505f6111dd565b5f818152600d602052604081205415614e7c57505f818152600d60205260409020546111dd565b61285e836146be565b5f6040518061012001604052806101008152602001615e9e610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff614ecd85614eee565b02901c81518110614ee057614ee06158c9565b016020015160f81c92915050565b5f808211614efa575f80fd5b505f8190031690565b602080825282518282018190525f9190848201906040850190845b81811015614f435783516001600160a01b031683529284019291840191600101614f1e565b50909695505050505050565b6001600160e01b03198116811461120a575f80fd5b5f60208284031215614f74575f80fd5b813561285e81614f4f565b6001600160a01b038116811461120a575f80fd5b5f60208284031215614fa3575f80fd5b813561285e81614f7f565b5f8060408385031215614fbf575f80fd5b8235614fca81614f7f565b915060208301356001600160601b0381168114614fe5575f80fd5b809150509250929050565b5f5b8381101561500a578181015183820152602001614ff2565b50505f910152565b5f8151808452615029816020860160208601614ff0565b601f01601f19169290920160200192915050565b602081525f61285e6020830184615012565b5f6020828403121561505f575f80fd5b5035919050565b6001600160a01b0391909116815260200190565b5f806040838503121561508b575f80fd5b823561509681614f7f565b946020939093013593505050565b5f805f606084860312156150b6575f80fd5b505081359360208301359350604090920135919050565b5f805f606084860312156150df575f80fd5b833592506020840135915060408401356150f881614f7f565b809150509250925092565b5f805f60608486031215615115575f80fd5b833561512081614f7f565b9250602084013561513081614f7f565b929592945050506040919091013590565b5f602080830181845280855180835260408601915060408160051b87010192508387015f5b828110156151ba57878503603f190184528151805180875290870190878701905f5b818110156151a457835183529289019291890191600101615188565b5090965050509285019290850190600101615166565b5092979650505050505050565b5f80604083850312156151d8575f80fd5b50508035926020909101359150565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561523c5761523c615200565b604052919050565b5f6001600160401b0382111561525c5761525c615200565b5060051b60200190565b5f82601f830112615275575f80fd5b8135602061528a61528583615244565b615214565b8083825260208201915060208460051b8701019350868411156152ab575f80fd5b602086015b848110156152c757803583529183019183016152b0565b509695505050505050565b5f805f805f60a086880312156152e6575f80fd5b853594506020860135935060408601359250606086013561530681614f7f565b915060808601356001600160401b03811115615320575f80fd5b61532c88828901615266565b9150509295509295909350565b801515811461120a575f80fd5b5f60208284031215615356575f80fd5b813561285e81615339565b602080825282518282018190525f9190848201906040850190845b81811015614f435783518352928401929184019160010161537c565b5f6001600160401b038311156153b0576153b0615200565b6153c3601f8401601f1916602001615214565b90508281528383830111156153d6575f80fd5b828260208301375f602084830101529392505050565b5f602082840312156153fc575f80fd5b81356001600160401b03811115615411575f80fd5b8201601f81018413615421575f80fd5b612cef84823560208401615398565b5f8083601f840112615440575f80fd5b5081356001600160401b03811115615456575f80fd5b602083019150836020828501011115611c88575f80fd5b5f805f6040848603121561547f575f80fd5b83356001600160401b03811115615494575f80fd5b6154a086828701615430565b909790965060209590950135949350505050565b5f80604083850312156154c5575f80fd5b823591506020830135614fe581615339565b5f805f606084860312156154e9575f80fd5b83359250602084013561513081614f7f565b5f805f806080858703121561550e575f80fd5b84359350602080860135935060408601356001600160401b0380821115615533575f80fd5b818801915088601f830112615546575f80fd5b813561555461528582615244565b81815260059190911b8301840190848101908b831115615572575f80fd5b938501935b8285101561559957843561558a81614f7f565b82529385019390850190615577565b9650505060608801359250808311156155b0575f80fd5b50506155be87828801615266565b91505092959194509250565b5f80604083850312156155db575f80fd5b82356155e681614f7f565b91506020830135614fe581615339565b5f805f8060808587031215615609575f80fd5b843561561481614f7f565b9350602085013561562481614f7f565b92506040850135915060608501356001600160401b03811115615645575f80fd5b8501601f81018713615655575f80fd5b6155be87823560208401615398565b5f805f8060808587031215615677575f80fd5b8435935060208501359250604085013561569081614f7f565b9396929550929360600135925050565b5f805f606084860312156156b2575f80fd5b83356156bd81614f7f565b92506020840135915060408401356001600160401b038111156156de575f80fd5b6156ea86828701615266565b9150509250925092565b5f8060208385031215615705575f80fd5b82356001600160401b0381111561571a575f80fd5b61572685828601615430565b90969095509350505050565b5f8060408385031215615743575f80fd5b823561574e81614f7f565b91506020830135614fe581614f7f565b600181811c9082168061577257607f821691505b60208210810361380757634e487b7160e01b5f52602260045260245ffd5b6001600160a01b0392831681529116602082015260400190565b5f602082840312156157ba575f80fd5b815161285e81615339565b5f602082840312156157d5575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156111dd576111dd6157dc565b808201808211156111dd576111dd6157dc565b80820281158282048414176111dd576111dd6157dc565b602080825260189082015277115512081d985b1d59481a5cc81b9bdd0818dbdc9c9958dd60421b604082015260600190565b6020808252600c908201526b4e6f206d6f7265204e46547360a01b604082015260600190565b6020808252600f908201526e4e6f206d6f72652070617263656c7360881b604082015260600190565b5f602082840312156158be575f80fd5b815161285e81614f7f565b634e487b7160e01b5f52603260045260245ffd5b5f600182016158ee576158ee6157dc565b5060010190565b5f8261590f57634e487b7160e01b5f52601260045260245ffd5b500490565b601f8211156114d357805f5260205f20601f840160051c810160208510156159395750805b601f840160051c820191505b81811015611fd9575f8155600101615945565b81516001600160401b0381111561597157615971615200565b6159858161597f845461575e565b84615914565b602080601f8311600181146159b8575f84156159a15750858301515b5f19600386901b1c1916600185901b178555614223565b5f85815260208120601f198616915b828110156159e6578886015182559484019460019091019084016159c7565b5085821015615a0357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b8181035f8312801583831316838312821617156125b0576125b06157dc565b5f8154615a3e8161575e565b60018281168015615a565760018114615a6b57615a97565b60ff1984168752821515830287019450615a97565b855f526020805f205f5b85811015615a8e5781548a820152908401908201615a75565b50505082870194505b5050505092915050565b5f8451615ab2818460208901614ff0565b845190830190615ac6818360208901614ff0565b615ad281830186615a32565b979650505050505050565b5f615ae88286615a32565b8451615ac6818360208901614ff0565b5f6001600160ff1b0182016158ee576158ee6157dc565b8082018281125f831280158216821582161715615b2e57615b2e6157dc565b505092915050565b67030b1b1b7bab73a160c51b81525f8251615b58816008850160208701614ff0565b721034b9903737ba1030b71037b832b930ba37b960691b6008939091019283015250601b01919050565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b67030b1b1b7bab73a160c51b81525f8251615bf8816008850160208701614ff0565b7f20697320616c72656164792068617320616e206f70657261746f7220726f6c656008939091019283015250602801919050565b5f81525f8251615c43816001850160208701614ff0565b9190910160010192915050565b7a3d9139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60291b815282515f90615c8681601b850160208801614ff0565b721610113332b2afb932b1b4b834b2b73a111d1160691b601b918401918201528351615cb981602e840160208801614ff0565b61227d60f01b602e9290910191820152603001949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081525f8251615d0b81601d850160208701614ff0565b91909101601d0192915050565b5f81615d2657615d266157dc565b505f190190565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b600582015281515f90615dc481600e850160208701614ff0565b91909101600e019392505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90615e0490830184615012565b9695505050505050565b5f60208284031215615e1e575f80fd5b815161285e81614f4f565b634e487b7160e01b5f52603160045260245ffdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a2646970667358221220d61ca505ea5e5c4944f79381bfdcb3b559f3e7df765702e9c73c9564b1c9adae64736f6c6343000817003368747470733a2f2f73746172746c616e64732e696f2f53544c2f68696464656e2f

Deployed Bytecode

0x6080604052600436106104e7575f3560e01c8063715018a611610289578063b6cbcf3311610158578063da359dc8116100c5578063da359dc81461102d578063da3ef23f1461104c578063df58a1b51461106b578063e0617ce314611080578063e8a3d485146110ab578063e985e9c5146110bf578063ed441adc146110de578063f093888914611109578063f2fde38b14611137578063f95d844214611156578063fb796e6c1461118c578063fe335dee14610a92578063ff768212146111a5575f80fd5b8063b6cbcf3314610e98578063b7c0b8e814610ec3578063b88d4fde14610ee2578063bb06f36614610f01578063bbaac02f14610f20578063bc6d75a414610f3f578063c3cef93914610f5e578063c50c818614610f7d578063c82bf41814610f9c578063c87b56dd14610fbb578063ca5c7a3414610fda578063d2de022f14610ff9578063d5abeb0114611018575f80fd5b806395d89b41116101f657806395d89b4114610ce357806396b0617614610cf7578063979c4a9c14610d165780639da9778c14610d355780639e23c3e714610d3d578063a22cb46514610d5c578063a355fd2914610d7b578063a35c23ad14610d9a578063a8da8c1214610dc5578063ab1e8e6314610de4578063abdc331314610e1a578063b219f7d714610e4e578063b31391cb14610e6d575f80fd5b8063715018a614610b6457806372b44d7114610b785780637558be9e14610b9757806377d744d514610bb65780637c3dc17314610bd55780637e26b0d014610bf45780637fc69f5a14610c13578063829aee9714610c28578063830b3a6414610c535780638462151c14610c725780638528eefe14610c915780638da5cb5b14610cb057806391e4bac814610cc4575f80fd5b806330e7ed35116103c5578063438b630011610332578063438b6300146109d45780634bf365df14610a005780634f3db34614610a155780635183022714610a2a57806355f804b314610a3f5780635638697b14610a5e57806358303b1014610a7d5780635b075f3614610a925780636352211e14610ab15780636d70f7ae14610ad05780636f8b44b014610b075780636fa0cf5f14610b2657806370a0823114610b45575f80fd5b806330e7ed351461085a578063396e8f53146108795780633bdfce02146108985780633ccfd60b146108ab5780633df669f7146108b35780633f91fd04146108c85780633fff74bd146108f35780634009920d14610912578063405059601461092b57806341f434341461095657806342842e0e1461097757806342966c6814610996578063435e4ccd146109b5575f80fd5b806318160ddd1161046357806318160ddd146106b65780631a549a7c146106ca5780631a8b8357146106dd5780631ce5ed6c14610708578063214e4a05146107275780632398f8431461074657806323b872dd146107715780632672c9021461079057806327ac0c58146107a45780632a3d9667146107c35780632a55205a146107ef5780632cbf810f1461081c5780632f9ff2ed1461083b575f80fd5b80623f332f146104eb57806301ffc9a714610515578063025e332e1461054457806304634d8d1461056557806306fdde031461058457806307265389146105a5578063081812fc146105be578063095ea7b3146105ea5780630d9005ae146106095780630f4345e21461062b57806310637d8a1461064a5780631562eea414610697575b5f80fd5b3480156104f6575f80fd5b506104ff6111c4565b60405161050c9190614f03565b60405180910390f35b348015610520575f80fd5b5061053461052f366004614f64565b6111d3565b604051901515815260200161050c565b34801561054f575f80fd5b5061056361055e366004614f93565b6111e3565b005b348015610570575f80fd5b5061056361057f366004614fae565b61120d565b34801561058f575f80fd5b50610598611224565b60405161050c919061503d565b3480156105b0575f80fd5b50600c546105349060ff1681565b3480156105c9575f80fd5b506105dd6105d836600461504f565b6112b4565b60405161050c9190615066565b3480156105f5575f80fd5b5061056361060436600461507a565b611342565b348015610614575f80fd5b5061061d6114d8565b60405190815260200161050c565b348015610636575f80fd5b5061056361064536600461504f565b6114ee565b348015610655575f80fd5b5061061d61066436600461507a565b601e545f908152602c6020908152604080832084845282528083206001600160a01b038616845290915290205492915050565b3480156106a2575f80fd5b506105636106b13660046150a4565b6114fc565b3480156106c1575f80fd5b5061061d6115cc565b6105636106d83660046150cd565b6115dd565b3480156106e8575f80fd5b5061061d6106f736600461504f565b60286020525f908152604090205481565b348015610713575f80fd5b506105636107223660046150a4565b611837565b348015610732575f80fd5b506105636107413660046150a4565b61185b565b348015610751575f80fd5b5061061d610760366004614f93565b600e6020525f908152604090205481565b34801561077c575f80fd5b5061056361078b366004615103565b61187f565b34801561079b575f80fd5b50610598611967565b3480156107af575f80fd5b506105636107be366004614f93565b6119f3565b3480156107ce575f80fd5b506107e26107dd366004614f93565b611a04565b60405161050c9190615141565b3480156107fa575f80fd5b5061080e6108093660046151c7565b611be3565b60405161050c9291906151e7565b348015610827575f80fd5b506105636108363660046151c7565b611c8f565b348015610846575f80fd5b50610563610855366004614f93565b611ca8565b348015610865575f80fd5b5061056361087436600461504f565b611cef565b348015610884575f80fd5b506009546105dd906001600160a01b031681565b6105636108a63660046152d2565b611cfd565b610563611fe0565b3480156108be575f80fd5b5061061d60325481565b3480156108d3575f80fd5b5061061d6108e236600461504f565b601b6020525f908152604090205481565b3480156108fe575f80fd5b5061056361090d3660046151c7565b612110565b34801561091d575f80fd5b506025546105349060ff1681565b348015610936575f80fd5b5061061d61094536600461504f565b5f9081526027602052604090205490565b348015610961575f80fd5b506105dd6daaeb6d7670e522a718067333cd4e81565b348015610982575f80fd5b50610563610991366004615103565b61212a565b3480156109a1575f80fd5b506105636109b036600461504f565b612207565b3480156109c0575f80fd5b506105636109cf366004615346565b6122a7565b3480156109df575f80fd5b506109f36109ee366004614f93565b6122ca565b60405161050c9190615361565b348015610a0b575f80fd5b5061061d601a5481565b348015610a20575f80fd5b5061061d600f5481565b348015610a35575f80fd5b5061061d601d5481565b348015610a4a575f80fd5b50610563610a593660046153ec565b6123ef565b348015610a69575f80fd5b50610563610a7836600461546d565b612404565b348015610a88575f80fd5b5061061d60125481565b348015610a9d575f80fd5b50610563610aac3660046151c7565b61249d565b348015610abc575f80fd5b506105dd610acb36600461504f565b6124b7565b348015610adb575f80fd5b50610534610aea366004614f93565b6001600160a01b03165f9081526016602052604090205460ff1690565b348015610b12575f80fd5b50610563610b2136600461504f565b6124ca565b348015610b31575f80fd5b50610563610b403660046151c7565b6124d8565b348015610b50575f80fd5b5061061d610b5f366004614f93565b6124f2565b348015610b6f575f80fd5b506105636125b7565b348015610b83575f80fd5b50610563610b92366004614f93565b6125c8565b348015610ba2575f80fd5b50610563610bb136600461504f565b6125da565b348015610bc1575f80fd5b506026546105dd906001600160a01b031681565b348015610be0575f80fd5b50610563610bef3660046151c7565b6125e7565b348015610bff575f80fd5b5061061d610c0e36600461504f565b612676565b348015610c1e575f80fd5b5061061d601f5481565b348015610c33575f80fd5b5061061d610c4236600461504f565b602a6020525f908152604090205481565b348015610c5e575f80fd5b506105dd610c6d36600461504f565b6126a8565b348015610c7d575f80fd5b506109f3610c8c366004614f93565b61270d565b348015610c9c575f80fd5b50610563610cab3660046154b4565b6127d1565b348015610cbb575f80fd5b506105dd6127f9565b348015610ccf575f80fd5b50610563610cde36600461504f565b612807565b348015610cee575f80fd5b50610598612815565b348015610d02575f80fd5b5061061d610d113660046154d7565b612824565b348015610d21575f80fd5b50610563610d303660046154fb565b612865565b6105636128f1565b348015610d48575f80fd5b506105dd610d573660046151c7565b612922565b348015610d67575f80fd5b50610563610d763660046155ca565b612950565b348015610d86575f80fd5b50610563610d95366004615346565b612a11565b348015610da5575f80fd5b50610563610db436600461504f565b335f908152600e6020526040902055565b348015610dd0575f80fd5b5061061d610ddf36600461504f565b612a2d565b348015610def575f80fd5b5061061d610dfe3660046151c7565b602960209081525f928352604080842090915290825290205481565b348015610e25575f80fd5b50610e39610e3436600461504f565b612a72565b6040805192835260208301919091520161050c565b348015610e59575f80fd5b50610563610e68366004614f93565b612aa9565b348015610e78575f80fd5b5061061d610e8736600461504f565b600d6020525f908152604090205481565b348015610ea3575f80fd5b5061061d610eb236600461504f565b60276020525f908152604090205481565b348015610ece575f80fd5b50610563610edd366004615346565b612aba565b348015610eed575f80fd5b50610563610efc3660046155f6565b612ad6565b348015610f0c575f80fd5b50610563610f1b3660046151c7565b612bba565b348015610f2b575f80fd5b50610563610f3a3660046153ec565b612bd4565b348015610f4a575f80fd5b50610563610f59366004615664565b612be9565b348015610f69575f80fd5b5061061d610f783660046150cd565b612c81565b348015610f88575f80fd5b50610563610f9736600461504f565b612cf7565b348015610fa7575f80fd5b50610e39610fb636600461504f565b612d05565b348015610fc6575f80fd5b50610598610fd536600461504f565b612d25565b348015610fe5575f80fd5b5061061d610ff43660046151c7565b612df2565b348015611004575f80fd5b506105346110133660046156a0565b612e6f565b348015611023575f80fd5b5061061d60195481565b348015611038575f80fd5b506105636110473660046156f4565b612f8f565b348015611057575f80fd5b506105636110663660046153ec565b61301d565b348015611076575f80fd5b5061061d601e5481565b34801561108b575f80fd5b5061061d61109a36600461504f565b60186020525f908152604090205481565b3480156110b6575f80fd5b50610598613032565b3480156110ca575f80fd5b506105346110d9366004615732565b61303c565b3480156110e9575f80fd5b5061061d6110f836600461504f565b601c6020525f908152604090205481565b348015611114575f80fd5b5061053461112336600461504f565b60246020525f908152604090205460ff1681565b348015611142575f80fd5b50610563611151366004614f93565b613083565b348015611161575f80fd5b5061061d6111703660046151c7565b601760209081525f928352604080842090915290825290205481565b348015611197575f80fd5b506015546105349060ff1681565b3480156111b0575f80fd5b506105636111bf366004614f93565b6130f9565b60606111ce61310b565b905090565b5f6111dd82613117565b92915050565b6111ec3361313b565b600980546001600160a01b0319166001600160a01b03831617905550565b50565b6112163361313b565b61122082826131a8565b5050565b6060600280546112339061575e565b80601f016020809104026020016040519081016040528092919081815260200182805461125f9061575e565b80156112aa5780601f10611281576101008083540402835291602001916112aa565b820191905f5260205f20905b81548152906001019060200180831161128d57829003601f168201915b5050505050905090565b5f6112be826132a1565b6113275760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084015b60405180910390fd5b505f908152600660205260409020546001600160a01b031690565b816daaeb6d7670e522a718067333cd4e3b15801590611363575060155460ff165b156113f957604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c61711349061139b9030908590600401615790565b602060405180830381865afa1580156113b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113da91906157aa565b6113f95780604051633b79c77360e21b815260040161131e9190615066565b60255460405163d68f4dd160e01b8152600481018490526001916201000090046001600160a01b03169063d68f4dd190602401602060405180830381865afa158015611447573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146b91906157c5565b106114c95760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420617070726f76652c207472616e7366657272696e67206e6f7460448201526708185b1b1bddd95960c21b606482015260840161131e565b6114d383836132c2565b505050565b5f60016114e460055490565b6111ce91906157f0565b6114f73361313b565b600f55565b6115053361313b565b5f5b818110156115a4575f61151a8286615803565b90505f610122821180156115305750610e568211155b15611556575f611542610123846157f0565b905061154e81876132d6565b91505061157f565b5f858152601c602052604081205461156f908590615803565b905061157b81876132d6565b9150505b5f828152602f6020526040902081905561159a818684613384565b5050600101611507565b505f828152601c6020526040812080548392906115c2908490615803565b9091555050505050565b5f6115d56134b3565b6114e4613508565b6115e5613518565b60255460ff1661162e5760405162461bcd60e51b81526020600482015260146024820152731c1d589b1a58d35a5b9d081a5cc814185d5cd95960621b604482015260640161131e565b5f838152602a60205260409020548211156116995760405162461bcd60e51b815260206004820152602560248201527f7075626c69634d696e743a204f766572206d6178206d696e7473207065722077604482015264185b1b195d60da1b606482015260840161131e565b601e545f908152602c6020908152604080832086845282528083206001600160a01b03851684529091529020546116d1908390615803565b5f848152602a6020526040902054101561172b5760405162461bcd60e51b815260206004820152601b60248201527a165bdd481a185d99481b9bc81c1d589b1a58d35a5b9d081b19599d602a1b604482015260640161131e565b5f83815260186020526040902054611744908390615816565b34146117625760405162461bcd60e51b815260040161131e9061582d565b601a5461176d6115cc565b6117779084615803565b11156117955760405162461bcd60e51b815260040161131e9061585f565b5f838152601b6020908152604080832054601c909252909120546117b99084615803565b11156117d75760405162461bcd60e51b815260040161131e90615885565b601e545f908152602c6020908152604080832086845282528083206001600160a01b038516845290915281208054849290611813908490615803565b9091555061182390508383613571565b61182d818361360c565b6114d36001601055565b6118403361313b565b5f928352601760209081526040808520938552929052912055565b6118643361313b565b5f928352602960209081526040808520938552929052912055565b826daaeb6d7670e522a718067333cd4e3b158015906118a0575060155460ff165b1561195657336001600160a01b038216036118c5576118c0848484613625565b611961565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c6171134906118f89030903390600401615790565b602060405180830381865afa158015611913573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061193791906157aa565b6119565733604051633b79c77360e21b815260040161131e9190615066565b611961848484613625565b50505050565b602380546119749061575e565b80601f01602080910402602001604051908101604052809291908181526020018280546119a09061575e565b80156119eb5780601f106119c2576101008083540402835291602001916119eb565b820191905f5260205f20905b8154815290600101906020018083116119ce57829003601f168201915b505050505081565b6119fb613656565b61120a816136b5565b60605f611a10836124f2565b90505f816001600160401b03811115611a2b57611a2b615200565b604051908082528060200260200182016040528015611a5e57816020015b6060815260200190600190039081611a495790505b5090505f60015b6001611a7060055490565b611a7a91906157f0565b8111611bd9576040516320c2ce9960e21b815260048101829052309063830b3a6490602401602060405180830381865afa158015611aba573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ade91906158ae565b6001600160a01b0316866001600160a01b031603611bc7575f80611b04610e3484612a2d565b6040805160028082526060820190925292945090925081602001602082028036833701905050858581518110611b3c57611b3c6158c9565b602002602001018190525081858581518110611b5a57611b5a6158c9565b60200260200101515f81518110611b7357611b736158c9565b60200260200101818152505080858581518110611b9257611b926158c9565b6020026020010151600181518110611bac57611bac6158c9565b602090810291909101015283611bc1816158dd565b94505050505b80611bd1816158dd565b915050611a65565b5090949350505050565b5f8281526014602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291611c575750604080518082019091526013546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090611c75906001600160601b031687615816565b611c7f91906158f5565b91519350909150505b9250929050565b611c983361313b565b5f90815260186020526040902055565b611cb13361313b565b602680546001600160a01b0319166001600160a01b039290921691821790556025805462010000600160b01b03191662010000909202919091179055565b611cf83361313b565b601e55565b611d05613518565b5f8581526024602052604090205460ff16611d5c5760405162461bcd60e51b8152602060048201526017602482015276185b1b1bdddb1a5cdd135a5b9d081a5cc814185d5cd959604a1b604482015260640161131e565b611d67828683612e6f565b611dae5760405162461bcd60e51b8152602060048201526018602482015277596f7520617265206e6f742077686974656c69737465642160401b604482015260640161131e565b82611dba868685612c81565b1015611e195760405162461bcd60e51b815260206004820152602860248201527f616c6c6f776c6973744d696e743a204f766572206d6178206d696e74732070656044820152671c881dd85b1b195d60c21b606482015260840161131e565b5f858152602b6020908152604080832060278352818420548452825280832087845282528083206001600160a01b0386168452909152902054611e5d908490615803565b611e68868685612c81565b1015611eb65760405162461bcd60e51b815260206004820152601e60248201527f596f752068617665206e6f2077686974656c6973744d696e74206c6566740000604482015260640161131e565b5f858152601760209081526040808320878452909152902054611eda908490615816565b3414611ef85760405162461bcd60e51b815260040161131e9061582d565b601a54611f036115cc565b611f0d9085615803565b1115611f2b5760405162461bcd60e51b815260040161131e9061585f565b5f848152601b6020908152604080832054601c90925290912054611f4f9085615803565b1115611f6d5760405162461bcd60e51b815260040161131e90615885565b5f858152602b6020908152604080832060278352818420548452825280832087845282528083206001600160a01b038616845290915281208054859290611fb5908490615803565b90915550611fc590508484613571565b611fcf828461360c565b611fd96001601055565b5050505050565b611fe93361313b565b611ff1613518565b60205447905f906001600160a01b031615612060576020546040516001600160a01b039091169083905f81818185875af1925050503d805f8114612050576040519150601f19603f3d011682016040523d82523d5f602084013e612055565b606091505b5050809150506120ba565b6120686127f9565b6001600160a01b0316826040515f6040518083038185875af1925050503d805f81146120af576040519150601f19603f3d011682016040523d82523d5f602084013e6120b4565b606091505b50909150505b806121025760405162461bcd60e51b81526020600482015260186024820152772330b4b632b2103a37903bb4ba34323930bb9022ba3432b960411b604482015260640161131e565b505061210e6001601055565b565b6121193361313b565b5f918252602a602052604090912055565b826daaeb6d7670e522a718067333cd4e3b1580159061214b575060155460ff165b156121fc57336001600160a01b0382160361216b576118c084848461373b565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c61711349061219e9030903390600401615790565b602060405180830381865afa1580156121b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121dd91906157aa565b6121fc5733604051633b79c77360e21b815260040161131e9190615066565b61196184848461373b565b33612211826124b7565b6001600160a01b03161461225a5760405162461bcd60e51b815260206004820152601060248201526f34b9b73a1037bbb732b9103a37b5b2b760811b604482015260640161131e565b602554610100900460ff161561229e5760405162461bcd60e51b81526020600482015260096024820152686e6f7420616c6c6f7760b81b604482015260640161131e565b61120a81613755565b6122b03361313b565b602580549115156101000261ff0019909216919091179055565b60605f6122d6836124f2565b90505f816001600160401b038111156122f1576122f1615200565b60405190808252806020026020018201604052801561231a578160200160208202803683370190505b5090505f60015b600161232c60055490565b61233691906157f0565b8111611bd9576040516320c2ce9960e21b815260048101829052309063830b3a6490602401602060405180830381865afa158015612376573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061239a91906158ae565b6001600160a01b0316866001600160a01b0316036123dd578083836123be816158dd565b9450815181106123d0576123d06158c9565b6020026020010181815250505b806123e7816158dd565b915050612321565b6123f83361313b565b60226112208282615958565b61240d3361313b565b61244b83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506137aa92505050565b6031828154811061245e5761245e6158c9565b5f91825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055603154612495906001906157f0565b603255505050565b6124a63361313b565b5f9182526027602052604090912055565b5f806124c28361380d565b509392505050565b6124d33361313b565b601955565b6124e13361313b565b5f9182526011602052604090912055565b5f6001600160a01b03821661255f5760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b606482015260840161131e565b5f60015b6005548110156125b057612576816132a1565b156125a857612584816124b7565b6001600160a01b0316846001600160a01b0316036125a8576125a5826158dd565b91505b600101612563565b5092915050565b6125bf613656565b61210e5f6138a2565b6125d13361313b565b61120a816138f1565b6125e2613656565b601f55565b816125f1816124b7565b6001600160a01b0316336001600160a01b0316146126645760405162461bcd60e51b815260206004820152602a60248201527f5265737472696374417070726f76653a206f7065726174696f6e206973206f6e604482015269363c903437b63232b91760b11b606482015260840161131e565b505f918252600d602052604090912055565b5f818152603060205260408120541561269b57505f9081526030602052604090205490565b506001919050565b919050565b6040516331a9108f60e11b8152600481018290525f903090636352211e90602401602060405180830381865afa925050508015612702575060408051601f3d908101601f191682019092526126ff918101906158ae565b60015b6111dd57505f919050565b60605f8061271a846124f2565b90505f816001600160401b0381111561273557612735615200565b60405190808252806020026020018201604052801561275e578160200160208202803683370190505b50905060015b8284146127c857612774816132a1565b156127c057856001600160a01b031661278c826124b7565b6001600160a01b0316036127c057808285806001019650815181106127b3576127b36158c9565b6020026020010181815250505b600101612764565b50949350505050565b6127da3361313b565b5f91825260246020526040909120805460ff1916911515919091179055565b5f546001600160a01b031690565b6128103361313b565b601a55565b6060600380546112339061575e565b5f838152602b6020908152604080832060278352818420548452825280832084845282528083206001600160a01b03861684529091529020545b9392505050565b61286e3361313b565b5f5b8251811015611fd95781818151811061288b5761288b6158c9565b6020026020010151602e5f8781526020019081526020015f205f8681526020019081526020015f205f8584815181106128c6576128c66158c9565b6020908102919091018101516001600160a01b031682528101919091526040015f2055600101612870565b6128f9613518565b5f34116129185760405162461bcd60e51b815260040161131e9061582d565b61210e6001601055565b5f8061292e8484612df2565b905080156129475761293f816124b7565b9150506111dd565b505f9392505050565b816daaeb6d7670e522a718067333cd4e3b15801590612971575060155460ff165b15612a0757604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c6171134906129a99030908590600401615790565b602060405180830381865afa1580156129c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e891906157aa565b612a075780604051633b79c77360e21b815260040161131e9190615066565b6114d38383613935565b612a1a3361313b565b6025805460ff1916911515919091179055565b5f61012282118015612a415750610e568211155b15612a60575f612a53610123846157f0565b905061285e8160046132d6565b505f908152602f602052604090205490565b5f8061ffff601084901c811690841682612a8d60aa84615a13565b90505f612a9b60af84615a13565b919791965090945050505050565b612ab1613656565b61120a816139b3565b612ac33361313b565b6015805460ff1916911515919091179055565b836daaeb6d7670e522a718067333cd4e3b15801590612af7575060155460ff165b15612bae57336001600160a01b03821603612b1d57612b18858585856139dc565b611fd9565b604051633185c44d60e21b81526daaeb6d7670e522a718067333cd4e9063c617113490612b509030903390600401615790565b602060405180830381865afa158015612b6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8f91906157aa565b612bae5733604051633b79c77360e21b815260040161131e9190615066565b611fd9858585856139dc565b612bc33361313b565b5f918252601b602052604090912055565b612bdd3361313b565b60216112208282615958565b612bf23361313b565b601954612bfd6115cc565b612c079085615803565b1115612c255760405162461bcd60e51b815260040161131e9061585f565b5f848152601b6020908152604080832054601c90925290912054612c499085615803565b1115612c675760405162461bcd60e51b815260040161131e90615885565b8015612c7757612c778484613571565b611961828461360c565b5f838152602960209081526040808320858452825280832054868452602e835281842086855283528184206001600160a01b038616855290925282205415612cef57505f848152602e6020908152604080832086845282528083206001600160a01b03861684529091529020545b949350505050565b612d003361313b565b601d55565b5f80612d103361313b565b612d1c610e3484612a2d565b91509150915091565b6060612d30826132a1565b612d7c5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00604482015260640161131e565b612d8882601d54101590565b15612dd057612d95613a0e565b612da6612da184612a2d565b613a1d565b6023604051602001612dba93929190615aa1565b6040516020818303038152906040529050919050565b6021612dde612da184612676565b6023604051602001612dba93929190615add565b5f82815b6014811215612e65575f858152602d6020908152604080832087845290915290205415612e3e575050505f828152602d602090815260408083208484529091529020546111dd565b84612e4881615af8565b9550612e579050826014615b0f565b8513612e6557600101612df6565b505f949350505050565b6040516001600160601b0319606085901b1660208201525f9081906034016040516020818303038152906040528051906020012090505f5b8351811015612f7657838181518110612ec257612ec26158c9565b60200260200101518210612f2057838181518110612ee257612ee26158c9565b602002602001015182604051602001612f05929190918252602082015260400190565b60405160208183030381529060405280519060200120612f6c565b81848281518110612f3357612f336158c9565b6020026020010151604051602001612f55929190918252602082015260400190565b604051602081830303815290604052805190602001205b9150600101612ea7565b505f848152601160205260409020541490509392505050565b612f983361313b565b6031612fd883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506137aa92505050565b8154600180820184555f93845260209093200180546001600160a01b0319166001600160a01b039290921691909117905560315461301691906157f0565b6032555050565b6130263361313b565b60236112208282615958565b60606111ce613aac565b5f6130478383613b2b565b15155f0361305657505f6111dd565b6001600160a01b038084165f9081526007602090815260408083209386168352929052205460ff1661285e565b61308b613656565b6001600160a01b0381166130f05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161131e565b61120a816138a2565b6131023361313b565b61120a81613b42565b60606111ce600a613b86565b5f6001600160e01b0319821663152a902d60e11b14806111dd57506111dd82613b92565b6001600160a01b0381165f9081526016602052604090205460ff1661316b335b6001600160a01b03166014613bb6565b60405160200161317b9190615b36565b604051602081830303815290604052906112205760405162461bcd60e51b815260040161131e919061503d565b6127106001600160601b03821611156132165760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840161131e565b6001600160a01b0382166132685760405162461bcd60e51b815260206004820152601960248201527822a921991c9c189d1034b73b30b634b2103932b1b2b4bb32b960391b604482015260640161131e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601355565b5f6132ad600883613d4b565b156132b957505f919050565b6111dd82613d71565b6132cc8282613d8c565b6112208282613e07565b5f81816132e4856004615816565b90506003841115613337576132fb611180866158f5565b613306906004615803565b91506133136004836157f0565b61331f90611180615816565b61332990866157f0565b613334906004615816565b90505b5f6133736031848154811061334e5761334e6158c9565b5f918252602090912001546001600160a01b03168361336e816004615803565b613f16565b6020015160e01c9695505050505050565b5f8061338f85612a72565b915091505f805f865f036133ad5750600a9150600990506014613413565b866001036133c557506004915060059050600a613413565b866002036133dc5750600291508190506005613413565b866003036133f35750600191508190506003613413565b5050505f918252602d602090815260408084209284529190529020555050565b5f86815260306020526040812082905561342d8487615a13565b90505f600161343c8484615b0f565b6134469190615a13565b90505f6134538588615a13565b90505f60016134628684615b0f565b61346c9190615a13565b9050815b8181136134a4575f848152602d6020908152604080832084845290915290208b90558061349c81615af8565b915050613470565b50505050505050505050505050565b6005545f90819081906134ca9060081c6001615803565b9050815b81811015613502575f818152600860205260409020546134ed81613f37565b6134f79086615803565b9450506001016134ce565b50505090565b5f60016005546111ce91906157f0565b60026010540361356a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161131e565b6002601055565b5f61357a6115cc565b613585906001615803565b90505f5b828110156135ee575f61359c8284615803565b5f868152601c6020526040812054919250906135b9908490615803565b90505f6135c682886132d6565b5f848152602f6020526040902081905590506135e3818885613384565b505050600101613589565b505f838152601c6020526040812080548492906115c2908490615803565b611220828260405180602001604052805f815250613f4f565b61362f3382613f8e565b61364b5760405162461bcd60e51b815260040161131e90615b82565b6114d3838383614051565b3361365f6127f9565b6001600160a01b03161461210e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161131e565b6001600160a01b0381165f9081526016602052604090205460ff16156136da3361315b565b6040516020016136ea9190615bd6565b604051602081830303815290604052906137175760405162461bcd60e51b815260040161131e919061503d565b506001600160a01b03165f908152601660205260409020805460ff19166001179055565b6114d383838360405180602001604052805f815250612ad6565b5f61375f826124b7565b905061376e815f84600161422b565b613779600883614321565b60405182905f906001600160a01b038416905f80516020615e7e833981519152908390a4611220815f84600161434c565b5f806137d4836040516020016137c09190615c2c565b60405160208183030381529060405261436e565b90508051602082015ff091506001600160a01b0382166138075760405163046a55db60e11b815260040160405180910390fd5b50919050565b5f80613818836132a1565b6138795760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161131e565b61388283614384565b5f818152600460205260409020546001600160a01b031694909350915050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6138fc600a82614390565b506040516001600160a01b0382169033907f3b01c97343869ca2757fcc37cdb8f71683b0a7aed858e3755f4529a1db857292905f90a350565b61393e826143a4565b80613947575080155b6139a95760405162461bcd60e51b815260206004820152602d60248201527f5265737472696374417070726f76653a2043616e206e6f7420617070726f766560448201526c103637b1b5b2b2103a37b5b2b760991b606482015260840161131e565b61122082826143af565b6139bc8161313b565b6001600160a01b03165f908152601660205260409020805460ff19169055565b6139e63383613f8e565b613a025760405162461bcd60e51b815260040161131e90615b82565b61196184848484614472565b6060602280546112339061575e565b60605f613a298361448b565b60010190505f816001600160401b03811115613a4757613a47615200565b6040519080825280601f01601f191660200182016040528015613a71576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613a7b57509392505050565b60605f80613abc81612710611be3565b91509150613b05613acc82613a1d565b613ae0846001600160a01b03166014613bb6565b604051602001613af1929190615c50565b604051602081830303815290604052614560565b604051602001613b159190615cd4565b6040516020818303038152906040529250505090565b5f80613b36846146be565b9050612cef83826146fe565b613b4d600a82614792565b506040516001600160a01b0382169033907fbd0af1fe0a2c1c7bb340c17a284a291138979c8eeb797e176dbd1c415199af3c905f90a350565b60605f61285e836147a6565b5f6001600160e01b03198216630101c11560e71b14806111dd57506111dd826147ff565b60605f613bc4836002615816565b613bcf906002615803565b6001600160401b03811115613be657613be6615200565b6040519080825280601f01601f191660200182016040528015613c10576020820181803683370190505b509050600360fc1b815f81518110613c2a57613c2a6158c9565b60200101906001600160f81b03191690815f1a905350600f60fb1b81600181518110613c5857613c586158c9565b60200101906001600160f81b03191690815f1a9053505f613c7a846002615816565b613c85906001615803565b90505b6001811115613cfc576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613cb957613cb96158c9565b1a60f81b828281518110613ccf57613ccf6158c9565b60200101906001600160f81b03191690815f1a90535060049490941c93613cf581615d18565b9050613c88565b50831561285e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161131e565b600881901c5f90815260208390526040902054600160ff1b60ff83161c16151592915050565b5f613d7b60055490565b821080156111dd5750506001111590565b6001600160a01b0382161561122057613da5818361484e565b6112205760405162461bcd60e51b815260206004820152602d60248201527f5265737472696374417070726f76653a2054686520636f6e747261637420697360448201526c103737ba1030b63637bbb2b21760991b606482015260840161131e565b5f613e11826124b7565b9050806001600160a01b0316836001600160a01b031603613e805760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b606482015260840161131e565b336001600160a01b0382161480613e9c5750613e9c813361303c565b613f0c5760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b606482015260840161131e565b6114d3838361485a565b6060612cef84613f27856001615803565b613f32856001615803565b6148c7565b5f5b81156126a3575f19820190911690600101613f39565b5f613f5960055490565b9050613f658484614978565b613f725f85838686614ae1565b6119615760405162461bcd60e51b815260040161131e90615d2d565b5f613f98826132a1565b613ffc5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161131e565b5f614006836124b7565b9050806001600160a01b0316846001600160a01b031614806140415750836001600160a01b0316614036846112b4565b6001600160a01b0316145b80612cef5750612cef818561303c565b5f8061405c8361380d565b91509150846001600160a01b0316826001600160a01b0316146140d65760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b606482015260840161131e565b6001600160a01b03841661413c5760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b606482015260840161131e565b614149858585600161422b565b6141535f8461485a565b5f61415f846001615803565b905061416c600182613d4b565b15801561417a575060055481105b156141b0575f81815260046020526040902080546001600160a01b0319166001600160a01b0388161790556141b0600182614321565b5f84815260046020526040902080546001600160a01b0319166001600160a01b0387161790558184146141e8576141e8600185614321565b83856001600160a01b0316876001600160a01b03165f80516020615e7e83398151915260405160405180910390a4614223868686600161434c565b505050505050565b6001600160a01b038416156118c0575f5b8181101561431b575f61424f8285615803565b60255460405163d68f4dd160e01b815260048101839052919250600191620100009091046001600160a01b03169063d68f4dd190602401602060405180830381865afa1580156142a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142c591906157c5565b106143125760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207472616e736665722c20746f6b656e206973206c6f636b6564604482015260640161131e565b5060010161423c565b50611961565b600881901c5f90815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b6001600160a01b03841615611961575f828152600d6020526040812055611961565b6060815182604051602001612dba929190615d82565b5f6111dd600183614c0a565b5f61285e836001600160a01b038416614cfe565b5f6111dd3383613b2b565b336001600160a01b038316036144075760405162461bcd60e51b815260206004820152601c60248201527f4552433732315073693a20617070726f766520746f2063616c6c657200000000604482015260640161131e565b335f8181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61447d848484614051565b613f72848484600185614ae1565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106144c95772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b83106144f3576904ee2d6d415b85acef8160201b830492506020015b662386f26fc10000831061451157662386f26fc10000830492506010015b6305f5e1008310614529576305f5e100830492506008015b612710831061453d57612710830492506004015b6064831061454f576064830492506002015b600a83106111dd5760010192915050565b606081515f0361457d57505060408051602081019091525f815290565b5f604051806060016040528060408152602001615e3e6040913990505f6003845160026145aa9190615803565b6145b491906158f5565b6145bf906004615816565b90505f6145cd826020615803565b6001600160401b038111156145e4576145e4615200565b6040519080825280601f01601f19166020018201604052801561460e576020820181803683370190505b509050818152600183018586518101602084015b8183101561467a576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101614622565b60038951066001811461469457600281146146a5576146b0565b613d3d60f01b6001198301526146b0565b603d60f81b5f198301525b509398975050505050505050565b6001600160a01b0381165f908152600e6020526040812054156146f657506001600160a01b03165f908152600e602052604090205490565b5050600f5490565b600c545f9060ff16614712575060016111dd565b61471b83614de1565b8061285e5750600954604051630f8350ed60e41b81526001600160a01b039091169063f8350ed09061475390869086906004016151e7565b602060405180830381865afa15801561476e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061285e91906157aa565b5f61285e836001600160a01b038416614e09565b6060815f018054806020026020016040519081016040528092919081815260200182805480156147f357602002820191905f5260205f20905b8154815260200190600101908083116147df575b50505050509050919050565b5f6001600160e01b031982166380ac58cd60e01b148061482f57506001600160e01b03198216635b5e139f60e01b145b806111dd57506301ffc9a760e01b6001600160e01b03198316146111dd565b5f80613b363385614e55565b5f81815260066020526040902080546001600160a01b0319166001600160a01b038416908117909155819061488e826124b7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6060833b5f8190036148e857505060408051602081019091525f815261285e565b8084111561490557505060408051602081019091525f815261285e565b838310156149375760405163162544fd60e11b815260048101829052602481018590526044810184905260640161131e565b8383038482035f82821061494b578261494d565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b5f61498260055490565b90505f82116149e15760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b606482015260840161131e565b6001600160a01b038316614a435760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b606482015260840161131e565b614a4f5f84838561422b565b8160055f828254614a609190615803565b90915550505f81815260046020526040902080546001600160a01b0319166001600160a01b038516179055614a96600182614321565b614aa25f84838561434c565b805b614aae8383615803565b8110156119615760405181906001600160a01b038616905f905f80516020615e7e833981519152908290a4600101614aa4565b5f6001600160a01b0385163b15614bfd57506001835b614b018486615803565b811015614bf757604051630a85bd0160e11b81526001600160a01b0387169063150b7a0290614b3a9033908b9086908990600401615dd2565b6020604051808303815f875af1925050508015614b74575060408051601f3d908101601f19168201909252614b7191810190615e0e565b60015b614bcf573d808015614ba1576040519150601f19603f3d011682016040523d82523d5f602084013e614ba6565b606091505b5080515f03614bc75760405162461bcd60e51b815260040161131e90615d2d565b805181602001fd5b828015614bec57506001600160e01b03198116630a85bd0160e11b145b925050600101614af7565b50614c01565b5060015b95945050505050565b600881901c5f8181526020849052604081205490919060ff808516919082181c8015614c4b57614c3981614e85565b60ff168203600884901b179350614cf5565b5f8311614cb75760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b606482015260840161131e565b505f199091015f818152602086905260409020549091908015614cf057614cdd81614e85565b60ff0360ff16600884901b179350614cf5565b614c4b565b50505092915050565b5f8181526001830160205260408120548015614dd8575f614d206001836157f0565b85549091505f90614d33906001906157f0565b9050818114614d92575f865f018281548110614d5157614d516158c9565b905f5260205f200154905080875f018481548110614d7157614d716158c9565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080614da357614da3615e29565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f9055600193505050506111dd565b5f9150506111dd565b5f6111dd600a836001600160a01b0381165f908152600183016020526040812054151561285e565b5f818152600183016020526040812054614e4e57508154600181810184555f8481526020808220909301849055845484825282860190935260409020919091556111dd565b505f6111dd565b5f818152600d602052604081205415614e7c57505f818152600d60205260409020546111dd565b61285e836146be565b5f6040518061012001604052806101008152602001615e9e610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff614ecd85614eee565b02901c81518110614ee057614ee06158c9565b016020015160f81c92915050565b5f808211614efa575f80fd5b505f8190031690565b602080825282518282018190525f9190848201906040850190845b81811015614f435783516001600160a01b031683529284019291840191600101614f1e565b50909695505050505050565b6001600160e01b03198116811461120a575f80fd5b5f60208284031215614f74575f80fd5b813561285e81614f4f565b6001600160a01b038116811461120a575f80fd5b5f60208284031215614fa3575f80fd5b813561285e81614f7f565b5f8060408385031215614fbf575f80fd5b8235614fca81614f7f565b915060208301356001600160601b0381168114614fe5575f80fd5b809150509250929050565b5f5b8381101561500a578181015183820152602001614ff2565b50505f910152565b5f8151808452615029816020860160208601614ff0565b601f01601f19169290920160200192915050565b602081525f61285e6020830184615012565b5f6020828403121561505f575f80fd5b5035919050565b6001600160a01b0391909116815260200190565b5f806040838503121561508b575f80fd5b823561509681614f7f565b946020939093013593505050565b5f805f606084860312156150b6575f80fd5b505081359360208301359350604090920135919050565b5f805f606084860312156150df575f80fd5b833592506020840135915060408401356150f881614f7f565b809150509250925092565b5f805f60608486031215615115575f80fd5b833561512081614f7f565b9250602084013561513081614f7f565b929592945050506040919091013590565b5f602080830181845280855180835260408601915060408160051b87010192508387015f5b828110156151ba57878503603f190184528151805180875290870190878701905f5b818110156151a457835183529289019291890191600101615188565b5090965050509285019290850190600101615166565b5092979650505050505050565b5f80604083850312156151d8575f80fd5b50508035926020909101359150565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561523c5761523c615200565b604052919050565b5f6001600160401b0382111561525c5761525c615200565b5060051b60200190565b5f82601f830112615275575f80fd5b8135602061528a61528583615244565b615214565b8083825260208201915060208460051b8701019350868411156152ab575f80fd5b602086015b848110156152c757803583529183019183016152b0565b509695505050505050565b5f805f805f60a086880312156152e6575f80fd5b853594506020860135935060408601359250606086013561530681614f7f565b915060808601356001600160401b03811115615320575f80fd5b61532c88828901615266565b9150509295509295909350565b801515811461120a575f80fd5b5f60208284031215615356575f80fd5b813561285e81615339565b602080825282518282018190525f9190848201906040850190845b81811015614f435783518352928401929184019160010161537c565b5f6001600160401b038311156153b0576153b0615200565b6153c3601f8401601f1916602001615214565b90508281528383830111156153d6575f80fd5b828260208301375f602084830101529392505050565b5f602082840312156153fc575f80fd5b81356001600160401b03811115615411575f80fd5b8201601f81018413615421575f80fd5b612cef84823560208401615398565b5f8083601f840112615440575f80fd5b5081356001600160401b03811115615456575f80fd5b602083019150836020828501011115611c88575f80fd5b5f805f6040848603121561547f575f80fd5b83356001600160401b03811115615494575f80fd5b6154a086828701615430565b909790965060209590950135949350505050565b5f80604083850312156154c5575f80fd5b823591506020830135614fe581615339565b5f805f606084860312156154e9575f80fd5b83359250602084013561513081614f7f565b5f805f806080858703121561550e575f80fd5b84359350602080860135935060408601356001600160401b0380821115615533575f80fd5b818801915088601f830112615546575f80fd5b813561555461528582615244565b81815260059190911b8301840190848101908b831115615572575f80fd5b938501935b8285101561559957843561558a81614f7f565b82529385019390850190615577565b9650505060608801359250808311156155b0575f80fd5b50506155be87828801615266565b91505092959194509250565b5f80604083850312156155db575f80fd5b82356155e681614f7f565b91506020830135614fe581615339565b5f805f8060808587031215615609575f80fd5b843561561481614f7f565b9350602085013561562481614f7f565b92506040850135915060608501356001600160401b03811115615645575f80fd5b8501601f81018713615655575f80fd5b6155be87823560208401615398565b5f805f8060808587031215615677575f80fd5b8435935060208501359250604085013561569081614f7f565b9396929550929360600135925050565b5f805f606084860312156156b2575f80fd5b83356156bd81614f7f565b92506020840135915060408401356001600160401b038111156156de575f80fd5b6156ea86828701615266565b9150509250925092565b5f8060208385031215615705575f80fd5b82356001600160401b0381111561571a575f80fd5b61572685828601615430565b90969095509350505050565b5f8060408385031215615743575f80fd5b823561574e81614f7f565b91506020830135614fe581614f7f565b600181811c9082168061577257607f821691505b60208210810361380757634e487b7160e01b5f52602260045260245ffd5b6001600160a01b0392831681529116602082015260400190565b5f602082840312156157ba575f80fd5b815161285e81615339565b5f602082840312156157d5575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156111dd576111dd6157dc565b808201808211156111dd576111dd6157dc565b80820281158282048414176111dd576111dd6157dc565b602080825260189082015277115512081d985b1d59481a5cc81b9bdd0818dbdc9c9958dd60421b604082015260600190565b6020808252600c908201526b4e6f206d6f7265204e46547360a01b604082015260600190565b6020808252600f908201526e4e6f206d6f72652070617263656c7360881b604082015260600190565b5f602082840312156158be575f80fd5b815161285e81614f7f565b634e487b7160e01b5f52603260045260245ffd5b5f600182016158ee576158ee6157dc565b5060010190565b5f8261590f57634e487b7160e01b5f52601260045260245ffd5b500490565b601f8211156114d357805f5260205f20601f840160051c810160208510156159395750805b601f840160051c820191505b81811015611fd9575f8155600101615945565b81516001600160401b0381111561597157615971615200565b6159858161597f845461575e565b84615914565b602080601f8311600181146159b8575f84156159a15750858301515b5f19600386901b1c1916600185901b178555614223565b5f85815260208120601f198616915b828110156159e6578886015182559484019460019091019084016159c7565b5085821015615a0357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b8181035f8312801583831316838312821617156125b0576125b06157dc565b5f8154615a3e8161575e565b60018281168015615a565760018114615a6b57615a97565b60ff1984168752821515830287019450615a97565b855f526020805f205f5b85811015615a8e5781548a820152908401908201615a75565b50505082870194505b5050505092915050565b5f8451615ab2818460208901614ff0565b845190830190615ac6818360208901614ff0565b615ad281830186615a32565b979650505050505050565b5f615ae88286615a32565b8451615ac6818360208901614ff0565b5f6001600160ff1b0182016158ee576158ee6157dc565b8082018281125f831280158216821582161715615b2e57615b2e6157dc565b505092915050565b67030b1b1b7bab73a160c51b81525f8251615b58816008850160208701614ff0565b721034b9903737ba1030b71037b832b930ba37b960691b6008939091019283015250601b01919050565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b67030b1b1b7bab73a160c51b81525f8251615bf8816008850160208701614ff0565b7f20697320616c72656164792068617320616e206f70657261746f7220726f6c656008939091019283015250602801919050565b5f81525f8251615c43816001850160208701614ff0565b9190910160010192915050565b7a3d9139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60291b815282515f90615c8681601b850160208801614ff0565b721610113332b2afb932b1b4b834b2b73a111d1160691b601b918401918201528351615cb981602e840160208801614ff0565b61227d60f01b602e9290910191820152603001949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081525f8251615d0b81601d850160208701614ff0565b91909101601d0192915050565b5f81615d2657615d266157dc565b505f190190565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b600582015281515f90615dc481600e850160208701614ff0565b91909101600e019392505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90615e0490830184615012565b9695505050505050565b5f60208284031215615e1e575f80fd5b815161285e81614f4f565b634e487b7160e01b5f52603160045260245ffdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a2646970667358221220d61ca505ea5e5c4944f79381bfdcb3b559f3e7df765702e9c73c9564b1c9adae64736f6c63430008170033

Deployed Bytecode Sourcemap

145596:26357:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;166217:182;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;150340:251;;;;;;;;;;-1:-1:-1;150340:251:0;;;;;:::i;:::-;;:::i;:::-;;;1228:14:1;;1221:22;1203:41;;1191:2;1176:18;150340:251:0;1063:187:1;166515:105:0;;;;;;;;;;-1:-1:-1;166515:105:0;;;;;:::i;:::-;;:::i;:::-;;150127:186;;;;;;;;;;-1:-1:-1;150127:186:0;;;;;:::i;:::-;;:::i;103748:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;139973:33::-;;;;;;;;;;-1:-1:-1;139973:33:0;;;;;;;;105364:277;;;;;;;;;;-1:-1:-1;105364:277:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;164657:315::-;;;;;;;;;;-1:-1:-1;164657:315:0;;;;;:::i;:::-;;:::i;155268:111::-;;;;;;;;;;;;;:::i;:::-;;;3690:25:1;;;3678:2;3663:18;155268:111:0;3544:177:1;166407:100:0;;;;;;;;;;-1:-1:-1;166407:100:0;;;;;:::i;:::-;;:::i;153921:180::-;;;;;;;;;;-1:-1:-1;153921:180:0;;;;;:::i;:::-;154065:10;;154028:7;154055:21;;;:9;:21;;;;;;;;:28;;;;;;;;-1:-1:-1;;;;;154055:38:0;;;;;;;;;;153921:180;;;;;160809:714;;;;;;;;;;-1:-1:-1;160809:714:0;;;;;:::i;:::-;;:::i;119376:122::-;;;;;;;;;;;;;:::i;159300:997::-;;;;;;:::i;:::-;;:::i;146632:48::-;;;;;;;;;;-1:-1:-1;146632:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;152969:187;;;;;;;;;;-1:-1:-1;152969:187:0;;;;;:::i;:::-;;:::i;154154:184::-;;;;;;;;;;-1:-1:-1;154154:184:0;;;;;:::i;:::-;;:::i;140111:49::-;;;;;;;;;;-1:-1:-1;140111:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;164980:197;;;;;;;;;;-1:-1:-1;164980:197:0;;;;;:::i;:::-;;:::i;146311:38::-;;;;;;;;;;;;;:::i;166678:115::-;;;;;;;;;;-1:-1:-1;166678:115:0;;;;;:::i;:::-;;:::i;171252:698::-;;;;;;;;;;-1:-1:-1;171252:698:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;96545:480::-;;;;;;;;;;-1:-1:-1;96545:480:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;153180:156::-;;;;;;;;;;-1:-1:-1;153180:156:0;;;;;:::i;:::-;;:::i;149760:164::-;;;;;;;;;;-1:-1:-1;149760:164:0;;;;;:::i;:::-;;:::i;152808:117::-;;;;;;;;;;-1:-1:-1;152808:117:0;;;;;:::i;:::-;;:::i;139527:34::-;;;;;;;;;;-1:-1:-1;139527:34:0;;;;-1:-1:-1;;;;;139527:34:0;;;158017:1255;;;;;;:::i;:::-;;:::i;161758:465::-;;;:::i;147423:21::-;;;;;;;;;;;;;;;;145993:46;;;;;;;;;;-1:-1:-1;145993:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;154364:153;;;;;;;;;;-1:-1:-1;154364:153:0;;;;;:::i;:::-;;:::i;146425:31::-;;;;;;;;;;-1:-1:-1;146425:31:0;;;;;;;;152294:133;;;;;;;;;;-1:-1:-1;152294:133:0;;;;;:::i;:::-;152377:7;152404:15;;;:8;:15;;;;;;;152294:133;134202:143;;;;;;;;;;;;134302:42;134202:143;;165185:205;;;;;;;;;;-1:-1:-1;165185:205:0;;;;;:::i;:::-;;:::i;162243:201::-;;;;;;;;;;-1:-1:-1;162243:201:0;;;;;:::i;:::-;;:::i;162473:98::-;;;;;;;;;;-1:-1:-1;162473:98:0;;;;;:::i;:::-;;:::i;162616:536::-;;;;;;;;;;-1:-1:-1;162616:536:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;145955:31::-;;;;;;;;;;;;;;;;140191:27;;;;;;;;;;;;;;;;146096:23;;;;;;;;;;;;;;;;155445:109;;;;;;;;;;-1:-1:-1;155445:109:0;;;;;:::i;:::-;;:::i;167180:202::-;;;;;;;;;;-1:-1:-1;167180:202:0;;;;;:::i;:::-;;:::i;128727:22::-;;;;;;;;;;;;;;;;152638:162;;;;;;;;;;-1:-1:-1;152638:162:0;;;;;:::i;:::-;;:::i;103125:188::-;;;;;;;;;;-1:-1:-1;103125:188:0;;;;;:::i;:::-;;:::i;129775:113::-;;;;;;;;;;-1:-1:-1;129775:113:0;;;;;:::i;:::-;-1:-1:-1;;;;;129859:21:0;129835:4;129859:21;;;:10;:21;;;;;;;;;129775:113;151807;;;;;;;;;;-1:-1:-1;151807:113:0;;;;;:::i;:::-;;:::i;154891:189::-;;;;;;;;;;-1:-1:-1;154891:189:0;;;;;:::i;:::-;;:::i;102573:490::-;;;;;;;;;;-1:-1:-1;102573:490:0;;;;;:::i;:::-;;:::i;122060:103::-;;;;;;;;;;;;;:::i;166044:165::-;;;;;;;;;;-1:-1:-1;166044:165:0;;;;;:::i;:::-;;:::i;155888:98::-;;;;;;;;;;-1:-1:-1;155888:98:0;;;;;:::i;:::-;;:::i;146527:25::-;;;;;;;;;;-1:-1:-1;146527:25:0;;;;-1:-1:-1;;;;;146527:25:0;;;142831:169;;;;;;;;;;-1:-1:-1;142831:169:0;;;;;:::i;:::-;;:::i;167765:205::-;;;;;;;;;;-1:-1:-1;167765:205:0;;;;;:::i;:::-;;:::i;146158:24::-;;;;;;;;;;;;;;;;146762:48;;;;;;;;;;-1:-1:-1;146762:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;163219:284;;;;;;;;;;-1:-1:-1;163219:284:0;;;;;:::i;:::-;;:::i;115704:680::-;;;;;;;;;;-1:-1:-1;115704:680:0;;;;;:::i;:::-;;:::i;154574:163::-;;;;;;;;;;-1:-1:-1;154574:163:0;;;;;:::i;:::-;;:::i;121412:87::-;;;;;;;;;;;;;:::i;151960:109::-;;;;;;;;;;-1:-1:-1;151960:109:0;;;;;:::i;:::-;;:::i;103917:104::-;;;;;;;;;;;;;:::i;153695:218::-;;;;;;;;;;-1:-1:-1;153695:218:0;;;;;:::i;:::-;;:::i;155994:319::-;;;;;;;;;;-1:-1:-1;155994:319:0;;;;;:::i;:::-;;:::i;161557:131::-;;;:::i;171015:229::-;;;;;;;;;;-1:-1:-1;171015:229:0;;;;;:::i;:::-;;:::i;164448:201::-;;;;;;;;;;-1:-1:-1;164448:201:0;;;;;:::i;:::-;;:::i;154766:117::-;;;;;;;;;;-1:-1:-1;154766:117:0;;;;;:::i;:::-;;:::i;143008:112::-;;;;;;;;;;-1:-1:-1;143008:112:0;;;;;:::i;:::-;143093:10;143078:26;;;;:14;:26;;;;;:34;143008:112;167976:300;;;;;;;;;;-1:-1:-1;167976:300:0;;;;;:::i;:::-;;:::i;146687:68::-;;;;;;;;;;-1:-1:-1;146687:68:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;167390:369;;;;;;;;;;-1:-1:-1;167390:369:0;;;;;:::i;:::-;;:::i;:::-;;;;14969:25:1;;;15025:2;15010:18;;15003:34;;;;14942:18;167390:369:0;14799:244:1;166854:117:0;;;;;;;;;;-1:-1:-1;166854:117:0;;;;;:::i;:::-;;:::i;140034:48::-;;;;;;;;;;-1:-1:-1;140034:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;146582:43;;;;;;;;;;-1:-1:-1;146582:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;164318:122;;;;;;;;;;-1:-1:-1;164318:122:0;;;;;:::i;:::-;;:::i;165398:239::-;;;;;;;;;;-1:-1:-1;165398:239:0;;;;;:::i;:::-;;:::i;152109:156::-;;;;;;;;;;-1:-1:-1;152109:156:0;;;;;:::i;:::-;;:::i;155125:107::-;;;;;;;;;;-1:-1:-1;155125:107:0;;;;;:::i;:::-;;:::i;157492:501::-;;;;;;;;;;-1:-1:-1;157492:501:0;;;;;:::i;:::-;;:::i;156321:345::-;;;;;;;;;;-1:-1:-1;156321:345:0;;;;;:::i;:::-;;:::i;153374:113::-;;;;;;;;;;-1:-1:-1;153374:113:0;;;;;:::i;:::-;;:::i;168284:185::-;;;;;;;;;;-1:-1:-1;168284:185:0;;;;;:::i;:::-;;:::i;156674:749::-;;;;;;;;;;-1:-1:-1;156674:749:0;;;;;:::i;:::-;;:::i;170633:374::-;;;;;;;;;;-1:-1:-1;170633:374:0;;;;;:::i;:::-;;:::i;129062:497::-;;;;;;;;;;-1:-1:-1;129062:497:0;;;;;:::i;:::-;;:::i;145916:32::-;;;;;;;;;;;;;;;;167017:155;;;;;;;;;;-1:-1:-1;167017:155:0;;;;;:::i;:::-;;:::i;155562:150::-;;;;;;;;;;-1:-1:-1;155562:150:0;;;;;:::i;:::-;;:::i;146126:25::-;;;;;;;;;;;;;;;;145863:46;;;;;;;;;;-1:-1:-1;145863:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;150626:115;;;;;;;;;;;;;:::i;143312:284::-;;;;;;;;;;-1:-1:-1;143312:284:0;;;;;:::i;:::-;;:::i;146046:43::-;;;;;;;;;;-1:-1:-1;146046:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;146371:47;;;;;;;;;;-1:-1:-1;146371:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;122318:238;;;;;;;;;;-1:-1:-1;122318:238:0;;;;;:::i;:::-;;:::i;145790:66::-;;;;;;;;;;-1:-1:-1;145790:66:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;134150:43;;;;;;;;;;-1:-1:-1;134150:43:0;;;;;;;;165877:159;;;;;;;;;;-1:-1:-1;165877:159:0;;;;;:::i;:::-;;:::i;166217:182::-;166322:16;166363:28;:26;:28::i;:::-;166356:35;;166217:182;:::o;150340:251::-;150518:4;150547:36;150571:11;150547:23;:36::i;:::-;150540:43;150340:251;-1:-1:-1;;150340:251:0:o;166515:105::-;129715:32;99936:10;129715:18;:32::i;:::-;142660:3;:35;;-1:-1:-1;;;;;;142660:35:0;-1:-1:-1;;;;;142660:35:0;;;;;166515:105;:::o;166593:19::-:1;166515:105:::0;:::o;150127:186::-;129715:32;99936:10;129715:18;:32::i;:::-;150261:44:::1;150280:9;150291:13;150261:18;:44::i;:::-;150127:186:::0;;:::o;103748:100::-;103802:13;103835:5;103828:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103748:100;:::o;105364:277::-;105456:7;105498:16;105506:7;105498;:16::i;:::-;105476:113;;;;-1:-1:-1;;;105476:113:0;;18255:2:1;105476:113:0;;;18237:21:1;18294:2;18274:18;;;18267:30;18333:34;18313:18;;;18306:62;-1:-1:-1;;;18384:18:1;;;18377:45;18439:19;;105476:113:0;;;;;;;;;-1:-1:-1;105609:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;105609:24:0;;105364:277::o;164657:315::-;164778:8;134302:42;136502:45;:49;;;;:90;;-1:-1:-1;136568:24:0;;;;136502:90;136484:383;;;136642:128;;-1:-1:-1;;;136642:128:0;;134302:42;;136642;;:128;;136715:4;;136743:8;;136642:128;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136619:237;;136831:8;136812:28;;-1:-1:-1;;;136812:28:0;;;;;;;;:::i;136619:237::-;164821:11:::1;::::0;:28:::1;::::0;-1:-1:-1;;;164821:28:0;;::::1;::::0;::::1;3690:25:1::0;;;164852:1:0::1;::::0;164821:11;;::::1;-1:-1:-1::0;;;;;164821:11:0::1;::::0;:19:::1;::::0;3663:18:1;;164821:28:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:32;164799:122;;;::::0;-1:-1:-1;;;164799:122:0;;19419:2:1;164799:122:0::1;::::0;::::1;19401:21:1::0;19458:2;19438:18;;;19431:30;19497:34;19477:18;;;19470:62;-1:-1:-1;;;19548:18:1;;;19541:38;19596:19;;164799:122:0::1;19217:404:1::0;164799:122:0::1;164932:32;164946:8;164956:7;164932:13;:32::i;:::-;164657:315:::0;;;:::o;155268:111::-;155326:7;155370:1;155353:14;101876:13;;;101794:103;155353:14;:18;;;;:::i;166407:100::-;129715:32;99936:10;129715:18;:32::i;:::-;166483:8:::1;:16:::0;166407:100::o;160809:714::-;129715:32;99936:10;129715:18;:32::i;:::-;160925:9:::1;160920:559;160944:7;160940:1;:11;160920:559;;;160973:15;160991:12;161002:1:::0;160991:8;:12:::1;:::i;:::-;160973:30;;161018:18;161064:3;161054:7;:13;:32;;;;;161082:4;161071:7;:15;;161054:32;161051:310;;;161106:16;161125:13;161135:3;161125:7:::0;:13:::1;:::i;:::-;161106:32;;161170:33;161187:8;161197:5;161170:16;:33::i;:::-;161157:46;;161087:132;161051:310;;;161242:16;161261:15:::0;;;:8:::1;:15;::::0;;;;;:19:::1;::::0;161279:1;;161261:19:::1;:::i;:::-;161242:38;;161312:33;161329:8;161339:5;161312:16;:33::i;:::-;161299:46;;161223:138;161051:310;161375:17;::::0;;;:8:::1;:17;::::0;;;;:30;;;161420:47:::1;161395:10:::0;161452:5;161384:7;161420:12:::1;:47::i;:::-;-1:-1:-1::0;;160953:3:0::1;;160920:559;;;-1:-1:-1::0;161489:15:0::1;::::0;;;:8:::1;:15;::::0;;;;:26;;161508:7;;161489:15;:26:::1;::::0;161508:7;;161489:26:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;160809:714:0:o;119376:122::-;119437:7;119481:9;:7;:9::i;:::-;119464:14;:12;:14::i;159300:997::-;85386:21;:19;:21::i;:::-;159462:19:::1;::::0;::::1;;159454:52;;;::::0;-1:-1:-1;;;159454:52:0;;20223:2:1;159454:52:0::1;::::0;::::1;20205:21:1::0;20262:2;20242:18;;;20235:30;-1:-1:-1;;;20281:18:1;;;20274:50;20341:18;;159454:52:0::1;20021:344:1::0;159454:52:0::1;159539:20;::::0;;;:13:::1;:20;::::0;;;;;:31;-1:-1:-1;159539:31:0::1;159517:118;;;::::0;-1:-1:-1;;;159517:118:0;;20572:2:1;159517:118:0::1;::::0;::::1;20554:21:1::0;20611:2;20591:18;;;20584:30;20650:34;20630:18;;;20623:62;-1:-1:-1;;;20701:18:1;;;20694:35;20746:19;;159517:118:0::1;20370:401:1::0;159517:118:0::1;159719:10;::::0;159709:21:::1;::::0;;;:9:::1;:21;::::0;;;;;;;:28;;;;;;;;-1:-1:-1;;;;;159709:39:0;::::1;::::0;;;;;;;;:49:::1;::::0;159751:7;;159709:49:::1;:::i;:::-;159668:20;::::0;;;:13:::1;:20;::::0;;;;;:90:::1;;159646:167;;;::::0;-1:-1:-1;;;159646:167:0;;20978:2:1;159646:167:0::1;::::0;::::1;20960:21:1::0;21017:2;20997:18;;;20990:30;-1:-1:-1;;;21036:18:1;;;21029:57;21103:18;;159646:167:0::1;20776:351:1::0;159646:167:0::1;159859:18;::::0;;;:11:::1;:18;::::0;;;;;:28:::1;::::0;159880:7;;159859:28:::1;:::i;:::-;159846:9;:41;159824:115;;;;-1:-1:-1::0;;;159824:115:0::1;;;;;;;:::i;:::-;159988:8;;159969:13;:11;:13::i;:::-;159959:23;::::0;:7;:23:::1;:::i;:::-;159958:39;;159950:64;;;;-1:-1:-1::0;;;159950:64:0::1;;;;;;;:::i;:::-;160079:18;::::0;;;:11:::1;:18;::::0;;;;;;;;160058:8:::1;:15:::0;;;;;;;160048:25:::1;::::0;:7;:25:::1;:::i;:::-;160047:51;;160025:116;;;;-1:-1:-1::0;;;160025:116:0::1;;;;;;;:::i;:::-;160162:10;::::0;160152:21:::1;::::0;;;:9:::1;:21;::::0;;;;;;;:28;;;;;;;;-1:-1:-1;;;;;160152:39:0;::::1;::::0;;;;;;;:50;;160195:7;;160152:21;:50:::1;::::0;160195:7;;160152:50:::1;:::i;:::-;::::0;;;-1:-1:-1;160213:36:0::1;::::0;-1:-1:-1;160234:5:0;160241:7;160213:20:::1;:36::i;:::-;160260:29;160270:9;160281:7;160260:9;:29::i;:::-;85430:20:::0;84824:1;85950:7;:22;85767:213;152969:187;129715:32;99936:10;129715:18;:32::i;:::-;153112:18:::1;::::0;;;:11:::1;:18;::::0;;;;;;;:25;;;;;;;;:36;152969:187::o;154154:184::-;129715:32;99936:10;129715:18;:32::i;:::-;154296:20:::1;::::0;;;:13:::1;:20;::::0;;;;;;;:27;;;;;;;;:34;154154:184::o;164980:197::-;165115:4;134302:42;135598:45;:49;;;;:90;;-1:-1:-1;135664:24:0;;;;135598:90;135580:697;;;135938:10;-1:-1:-1;;;;;135930:18:0;;;135926:85;;165132:37:::1;165151:4;165157:2;165161:7;165132:18;:37::i;:::-;135989:7:::0;;135926:85;136048:130;;-1:-1:-1;;;136048:130:0;;134302:42;;136048;;:130;;136121:4;;136149:10;;136048:130;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136025:241;;136239:10;136220:30;;-1:-1:-1;;;136220:30:0;;;;;;;;:::i;136025:241::-;165132:37:::1;165151:4;165157:2;165161:7;165132:18;:37::i;:::-;164980:197:::0;;;;:::o;146311:38::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;166678:115::-;121298:13;:11;:13::i;:::-;166755:30:::1;166774:10;166755:18;:30::i;171252:698::-:0;171331:17;171361:23;171387:19;171397:8;171387:9;:19::i;:::-;171361:45;;171417:24;171459:15;-1:-1:-1;;;;;171444:31:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;171417:58:0;-1:-1:-1;171488:18:0;150052:1;171521:398;171578:1;171561:14;101876:13;;;101794:103;171561:14;:18;;;;:::i;:::-;171555:1;:25;171521:398;;171618:18;;-1:-1:-1;;;171618:18:0;;;;;3690:25:1;;;171618:4:0;;:15;;3663:18:1;;171618::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;171606:30:0;:8;-1:-1:-1;;;;;171606:30:0;;171602:306;;171658:8;171668;171680:38;171703:14;171715:1;171703:11;:14::i;171680:38::-;171758:15;;;171771:1;171758:15;;;;;;;;;171657:61;;-1:-1:-1;171657:61:0;;-1:-1:-1;171758:15:0;;;;;;;;;;;;-1:-1:-1;171758:15:0;171737:6;171744:10;171737:18;;;;;;;;:::i;:::-;;;;;;:36;;;;171816:1;171792:6;171799:10;171792:18;;;;;;;;:::i;:::-;;;;;;;171811:1;171792:21;;;;;;;;:::i;:::-;;;;;;:25;;;;;171860:1;171836:6;171843:10;171836:18;;;;;;;;:::i;:::-;;;;;;;171855:1;171836:21;;;;;;;;:::i;:::-;;;;;;;;;;:25;171880:12;;;;:::i;:::-;;;;171638:270;;171602:306;171582:3;;;;:::i;:::-;;;;171521:398;;;-1:-1:-1;171936:6:0;;171252:698;-1:-1:-1;;;;171252:698:0:o;96545:480::-;96667:7;96725:27;;;:17;:27;;;;;;;;96696:56;;;;;;;;;-1:-1:-1;;;;;96696:56:0;;;;;-1:-1:-1;;;96696:56:0;;;-1:-1:-1;;;;;96696:56:0;;;;;;;;96667:7;;96765:92;;-1:-1:-1;96816:29:0;;;;;;;;;96826:19;96816:29;-1:-1:-1;;;;;96816:29:0;;;;-1:-1:-1;;;96816:29:0;;-1:-1:-1;;;;;96816:29:0;;;;;96765:92;96907:23;;;;96869:21;;97391:5;;96894:36;;-1:-1:-1;;;;;96894:36:0;:10;:36;:::i;:::-;96893:71;;;;:::i;:::-;96985:16;;;-1:-1:-1;96869:95:0;;-1:-1:-1;;96545:480:0;;;;;;:::o;153180:156::-;129715:32;99936:10;129715:18;:32::i;:::-;153299:18:::1;::::0;;;:11:::1;:18;::::0;;;;:29;153180:156::o;149760:164::-;129715:32;99936:10;129715:18;:32::i;:::-;149841:10:::1;:29:::0;;-1:-1:-1;;;;;;149841:29:0::1;-1:-1:-1::0;;;;;149841:29:0;;;::::1;::::0;;::::1;::::0;;149881:11:::1;:35:::0;;-1:-1:-1;;;;;;149881:35:0::1;::::0;;;::::1;::::0;;;::::1;::::0;;149760:164::o;152808:117::-;129715:32;99936:10;129715:18;:32::i;:::-;152893:10:::1;:24:::0;152808:117::o;158017:1255::-;85386:21;:19;:21::i;:::-;158240:22:::1;::::0;;;:15:::1;:22;::::0;;;;;::::1;;158232:58;;;::::0;-1:-1:-1;;;158232:58:0;;23427:2:1;158232:58:0::1;::::0;::::1;23409:21:1::0;23466:2;23446:18;;;23439:30;-1:-1:-1;;;23485:18:1;;;23478:53;23548:18;;158232:58:0::1;23225:347:1::0;158232:58:0::1;158323:39;158337:9;158348:5;158355:6;158323:13;:39::i;:::-;158301:113;;;::::0;-1:-1:-1;;;158301:113:0;;23779:2:1;158301:113:0::1;::::0;::::1;23761:21:1::0;23818:2;23798:18;;;23791:30;-1:-1:-1;;;23837:18:1;;;23830:54;23901:18;;158301:113:0::1;23577:348:1::0;158301:113:0::1;158486:7;158447:35;158458:5;158465;158472:9;158447:10;:35::i;:::-;:46;;158425:136;;;::::0;-1:-1:-1;;;158425:136:0;;24132:2:1;158425:136:0::1;::::0;::::1;24114:21:1::0;24171:2;24151:18;;;24144:30;24210:34;24190:18;;;24183:62;-1:-1:-1;;;24261:18:1;;;24254:38;24309:19;;158425:136:0::1;23930:404:1::0;158425:136:0::1;158650:16;::::0;;;:9:::1;:16;::::0;;;;;;;158667:8:::1;:15:::0;;;;;;158650:33;;;;;;;:40;;;;;;;;-1:-1:-1;;;;;158650:51:0;::::1;::::0;;;;;;;;:61:::1;::::0;158704:7;;158650:61:::1;:::i;:::-;158594:35;158605:5;158612;158619:9;158594:10;:35::i;:::-;:117;;158572:197;;;::::0;-1:-1:-1;;;158572:197:0;;24541:2:1;158572:197:0::1;::::0;::::1;24523:21:1::0;24580:2;24560:18;;;24553:30;24619:32;24599:18;;;24592:60;24669:18;;158572:197:0::1;24339:354:1::0;158572:197:0::1;158815:18;::::0;;;:11:::1;:18;::::0;;;;;;;:25;;;;;;;;;:35:::1;::::0;158843:7;;158815:35:::1;:::i;:::-;158802:9;:48;158780:122;;;;-1:-1:-1::0;;;158780:122:0::1;;;;;;;:::i;:::-;158951:8;;158932:13;:11;:13::i;:::-;158922:23;::::0;:7;:23:::1;:::i;:::-;158921:39;;158913:64;;;;-1:-1:-1::0;;;158913:64:0::1;;;;;;;:::i;:::-;159042:18;::::0;;;:11:::1;:18;::::0;;;;;;;;159021:8:::1;:15:::0;;;;;;;159011:25:::1;::::0;:7;:25:::1;:::i;:::-;159010:51;;158988:116;;;;-1:-1:-1::0;;;158988:116:0::1;;;;;;;:::i;:::-;159115:16;::::0;;;:9:::1;:16;::::0;;;;;;;159132:8:::1;:15:::0;;;;;;159115:33;;;;;;;:40;;;;;;;;-1:-1:-1;;;;;159115:51:0;::::1;::::0;;;;;;;:62;;159170:7;;159115:16;:62:::1;::::0;159170:7;;159115:62:::1;:::i;:::-;::::0;;;-1:-1:-1;159188:36:0::1;::::0;-1:-1:-1;159209:5:0;159216:7;159188:20:::1;:36::i;:::-;159235:29;159245:9;159256:7;159235:9;:29::i;:::-;85430:20:::0;84824:1;85950:7;:22;85767:213;85430:20;158017:1255;;;;;:::o;161758:465::-;129715:32;99936:10;129715:18;:32::i;:::-;85386:21:::1;:19;:21::i;:::-;161916:15:::2;::::0;161862:21:::2;::::0;161840:19:::2;::::0;-1:-1:-1;;;;;161916:15:0::2;:29:::0;161912:254:::2;;162018:15;::::0;162010:55:::2;::::0;-1:-1:-1;;;;;162018:15:0;;::::2;::::0;162048:11;;162010:55:::2;::::0;;;162048:11;162018:15;162010:55:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162001:64;;;;;161912:254;;;162115:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;162107:21:0::2;162137:11;162107:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;162098:56:0;;-1:-1:-1;;161912:254:0::2;162184:2;162176:39;;;::::0;-1:-1:-1;;;162176:39:0;;25110:2:1;162176:39:0::2;::::0;::::2;25092:21:1::0;25149:2;25129:18;;;25122:30;-1:-1:-1;;;25168:18:1;;;25161:54;25232:18;;162176:39:0::2;24908:348:1::0;162176:39:0::2;161829:394;;85430:20:::1;84824:1:::0;85950:7;:22;85767:213;85430:20:::1;161758:465::o:0;154364:153::-;129715:32;99936:10;129715:18;:32::i;:::-;154482:20:::1;::::0;;;:13:::1;:20;::::0;;;;;:27;154364:153::o;165185:205::-;165324:4;134302:42;135598:45;:49;;;;:90;;-1:-1:-1;135664:24:0;;;;135598:90;135580:697;;;135938:10;-1:-1:-1;;;;;135930:18:0;;;135926:85;;165341:41:::1;165364:4;165370:2;165374:7;165341:22;:41::i;135926:85::-:0;136048:130;;-1:-1:-1;;;136048:130:0;;134302:42;;136048;;:130;;136121:4;;136149:10;;136048:130;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136025:241;;136239:10;136220:30;;-1:-1:-1;;;136220:30:0;;;;;;;;:::i;136025:241::-;165341:41:::1;165364:4;165370:2;165374:7;165341:22;:41::i;162243:201::-:0;162330:10;162310:16;162318:7;162310;:16::i;:::-;-1:-1:-1;;;;;162310:30:0;;162302:59;;;;-1:-1:-1;;;162302:59:0;;25463:2:1;162302:59:0;;;25445:21:1;25502:2;25482:18;;;25475:30;-1:-1:-1;;;25521:18:1;;;25514:46;25577:18;;162302:59:0;25261:340:1;162302:59:0;162380:8;;;;;;;:17;162372:39;;;;-1:-1:-1;;;162372:39:0;;25808:2:1;162372:39:0;;;25790:21:1;25847:1;25827:18;;;25820:29;-1:-1:-1;;;25865:18:1;;;25858:39;25914:18;;162372:39:0;25606:332:1;162372:39:0;162422:14;162428:7;162422:5;:14::i;162473:98::-;129715:32;99936:10;129715:18;:32::i;:::-;162547:8:::1;:16:::0;;;::::1;;;;-1:-1:-1::0;;162547:16:0;;::::1;::::0;;;::::1;::::0;;162473:98::o;162616:536::-;162704:16;162733:23;162759:19;162769:8;162759:9;:19::i;:::-;162733:45;;162789:25;162831:15;-1:-1:-1;;;;;162817:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;162817:30:0;-1:-1:-1;162789:58:0;-1:-1:-1;162931:18:0;150052:1;162964:155;163021:1;163004:14;101876:13;;;101794:103;163004:14;:18;;;;:::i;:::-;162998:1;:25;162964:155;;163061:18;;-1:-1:-1;;;163061:18:0;;;;;3690:25:1;;;163061:4:0;;:15;;3663:18:1;;163061::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;163049:30:0;:8;-1:-1:-1;;;;;163049:30:0;;163045:62;;163106:1;163081:8;163090:12;;;;:::i;:::-;;;163081:22;;;;;;;;:::i;:::-;;;;;;:26;;;;;163045:62;163025:3;;;;:::i;:::-;;;;162964:155;;155445:109;129715:32;99936:10;129715:18;:32::i;:::-;155526:13:::1;:20;155542:4:::0;155526:13;:20:::1;:::i;167180:202::-:0;129715:32;99936:10;129715:18;:32::i;:::-;167315:21:::1;167329:6;;167315:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;167315:13:0::1;::::0;-1:-1:-1;;;167315:21:0:i:1;:::-;167299:7;167307:4;167299:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:37:::0;;-1:-1:-1;;;;;;167299:37:0::1;-1:-1:-1::0;;;;;167299:37:0;;;::::1;::::0;;;::::1;::::0;;167356:7:::1;:14:::0;:18:::1;::::0;-1:-1:-1;;167356:18:0::1;:::i;:::-;167347:6;:27:::0;-1:-1:-1;;;167180:202:0:o;152638:162::-;129715:32;99936:10;129715:18;:32::i;:::-;152766:15:::1;::::0;;;:8:::1;:15;::::0;;;;;:26;152638:162::o;103125:188::-;103213:7;103234:13;103253:29;103274:7;103253:20;:29::i;:::-;-1:-1:-1;103233:49:0;103125:188;-1:-1:-1;;;103125:188:0:o;151807:113::-;129715:32;99936:10;129715:18;:32::i;:::-;151890:9:::1;:22:::0;151807:113::o;154891:189::-;129715:32;99936:10;129715:18;:32::i;:::-;128882:23;;;;:13;:23;;;;;;:37;150127:186::o;102573:490::-;102661:4;-1:-1:-1;;;;;102700:19:0;;102678:114;;;;-1:-1:-1;;;102678:114:0;;28315:2:1;102678:114:0;;;28297:21:1;28354:2;28334:18;;;28327:30;28393:34;28373:18;;;28366:62;-1:-1:-1;;;28444:18:1;;;28437:43;28497:19;;102678:114:0;28113:409:1;102678:114:0;102805:10;150052:1;102826:207;101876:13;;102857:1;:18;102826:207;;;102901:10;102909:1;102901:7;:10::i;:::-;102897:125;;;102945:10;102953:1;102945:7;:10::i;:::-;-1:-1:-1;;;;;102936:19:0;:5;-1:-1:-1;;;;;102936:19:0;;102932:75;;102980:7;;;:::i;:::-;;;102932:75;102877:3;;102826:207;;;-1:-1:-1;103050:5:0;102573:490;-1:-1:-1;;102573:490:0:o;122060:103::-;121298:13;:11;:13::i;:::-;122125:30:::1;122152:1;122125:18;:30::i;166044:165::-:0;129715:32;99936:10;129715:18;:32::i;:::-;166160:41:::1;166190:10;166160:29;:41::i;155888:98::-:0;121298:13;:11;:13::i;:::-;155962:9:::1;:16:::0;155888:98::o;142831:169::-;142942:7;139707:16;139715:7;139707;:16::i;:::-;-1:-1:-1;;;;;139693:30:0;:10;-1:-1:-1;;;;;139693:30:0;;139671:122;;;;-1:-1:-1;;;139671:122:0;;28729:2:1;139671:122:0;;;28711:21:1;28768:2;28748:18;;;28741:30;28807:34;28787:18;;;28780:62;-1:-1:-1;;;28858:18:1;;;28851:40;28908:19;;139671:122:0;28527:406:1;139671:122:0;-1:-1:-1;142962:22:0::1;::::0;;;:13:::1;:22;::::0;;;;;:30;142831:169::o;167765:205::-;167826:7;167849:19;;;:9;:19;;;;;;:21;167846:117;;-1:-1:-1;167893:19:0;;;;:9;:19;;;;;;;167765:205::o;167846:117::-;-1:-1:-1;167950:1:0;;167765:205;-1:-1:-1;167765:205:0:o;167846:117::-;167765:205;;;:::o;163219:284::-;163327:21;;-1:-1:-1;;;163327:21:0;;;;;3690:25:1;;;163303:7:0;;163327:4;;:12;;3663:18:1;;163327:21:0;;;;;;;;;;;;;;;;;;-1:-1:-1;163327:21:0;;;;;;;;-1:-1:-1;;163327:21:0;;;;;;;;;;;;:::i;:::-;;;163323:173;;-1:-1:-1;163458:1:0;;163219:284;-1:-1:-1;163219:284:0:o;115704:680::-;115789:16;115843:19;115877:22;115902:16;115912:5;115902:9;:16::i;:::-;115877:41;;115933:25;115975:14;-1:-1:-1;;;;;115961:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;115961:29:0;-1:-1:-1;115933:57:0;-1:-1:-1;150052:1:0;116005:331;116089:14;116074:11;:29;116005:331;;116164:10;116172:1;116164:7;:10::i;:::-;116160:161;;;116217:5;-1:-1:-1;;;;;116203:19:0;:10;116211:1;116203:7;:10::i;:::-;-1:-1:-1;;;;;116203:19:0;;116199:103;;116277:1;116251:8;116260:13;;;;;;116251:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;116199:103;116122:3;;116005:331;;;-1:-1:-1;116357:8:0;115704:680;-1:-1:-1;;;;115704:680:0:o;154574:163::-;129715:32;99936:10;129715:18;:32::i;:::-;154699:22:::1;::::0;;;:15:::1;:22;::::0;;;;;:30;;-1:-1:-1;;154699:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;154574:163::o;121412:87::-;121458:7;121485:6;-1:-1:-1;;;;;121485:6:0;;121412:87::o;151960:109::-;129715:32;99936:10;129715:18;:32::i;:::-;152041:8:::1;:20:::0;151960:109::o;103917:104::-;103973:13;104006:7;103999:14;;;;;:::i;153695:218::-;153828:7;153855:16;;;:9;:16;;;;;;;;153872:8;:15;;;;;;153855:33;;;;;;;:40;;;;;;;;-1:-1:-1;;;;;153855:50:0;;;;;;;;;;153695:218;;;;;;:::o;155994:319::-;129715:32;99936:10;129715:18;:32::i;:::-;156190:9:::1;156185:121;156209:8;:15;156205:1;:19;156185:121;;;156286:5;156292:1;156286:8;;;;;;;;:::i;:::-;;;;;;;156246:10;:17;156257:5;156246:17;;;;;;;;;;;:24;156264:5;156246:24;;;;;;;;;;;:37;156271:8;156280:1;156271:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;156246:37:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;156246:37:0;:48;156226:3:::1;;156185:121;;161557:131:::0;85386:21;:19;:21::i;:::-;161650:1:::1;161638:9;:13;161630:50;;;;-1:-1:-1::0;;;161630:50:0::1;;;;;;;:::i;:::-;85430:20:::0;84824:1;85950:7;:22;85767:213;171015:229;171080:7;171100:16;171119:12;171127:1;171129;171119:7;:12::i;:::-;171100:31;-1:-1:-1;171145:12:0;;171142:67;;171180:17;171188:8;171180:7;:17::i;:::-;171173:24;;;;;171142:67;-1:-1:-1;171234:1:0;;171015:229;-1:-1:-1;;;171015:229:0:o;164448:201::-;164577:8;134302:42;136502:45;:49;;;;:90;;-1:-1:-1;136568:24:0;;;;136502:90;136484:383;;;136642:128;;-1:-1:-1;;;136642:128:0;;134302:42;;136642;;:128;;136715:4;;136743:8;;136642:128;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136619:237;;136831:8;136812:28;;-1:-1:-1;;;136812:28:0;;;;;;;;:::i;136619:237::-;164598:43:::1;164622:8;164632;164598:23;:43::i;154766:117::-:0;129715:32;99936:10;129715:18;:32::i;:::-;154848:19:::1;:27:::0;;-1:-1:-1;;154848:27:0::1;::::0;::::1;;::::0;;;::::1;::::0;;154766:117::o;167976:300::-;168036:7;168070:3;168059:8;:14;:34;;;;;168089:4;168077:8;:16;;168059:34;168056:213;;;168113:16;168132:14;168143:3;168132:8;:14;:::i;:::-;168113:33;;168172:29;168189:8;168199:1;168172:16;:29::i;168056:213::-;-1:-1:-1;168239:18:0;;;;:8;:18;;;;;;;167976:300::o;167390:369::-;167479:6;;167546;167540:2;167526:16;;;167525:27;;;167582:19;;167479:6;167623:22;167642:3;167525:27;167623:22;:::i;:::-;167612:33;-1:-1:-1;167675:8:0;167686:22;167705:3;167693:8;167686:22;:::i;:::-;167746:1;;167675:33;;-1:-1:-1;167390:369:0;;-1:-1:-1;;;;;167390:369:0:o;166854:117::-;121298:13;:11;:13::i;:::-;166932:31:::1;166952:10;166932:19;:31::i;164318:122::-:0;129715:32;99936:10;129715:18;:32::i;:::-;164400:24:::1;:32:::0;;-1:-1:-1;;164400:32:0::1;::::0;::::1;;::::0;;;::::1;::::0;;164318:122::o;165398:239::-;165565:4;134302:42;135598:45;:49;;;;:90;;-1:-1:-1;135664:24:0;;;;135598:90;135580:697;;;135938:10;-1:-1:-1;;;;;135930:18:0;;;135926:85;;165582:47:::1;165605:4;165611:2;165615:7;165624:4;165582:22;:47::i;:::-;135989:7:::0;;135926:85;136048:130;;-1:-1:-1;;;136048:130:0;;134302:42;;136048;;:130;;136121:4;;136149:10;;136048:130;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136025:241;;136239:10;136220:30;;-1:-1:-1;;;136220:30:0;;;;;;;;:::i;136025:241::-;165582:47:::1;165605:4;165611:2;165615:7;165624:4;165582:22;:47::i;152109:156::-:0;129715:32;99936:10;129715:18;:32::i;:::-;152230:18:::1;::::0;;;:11:::1;:18;::::0;;;;;:27;152109:156::o;155125:107::-;129715:32;99936:10;129715:18;:32::i;:::-;155208:9:::1;:16;155220:4:::0;155208:9;:16:::1;:::i;157492:501::-:0;129715:32;99936:10;129715:18;:32::i;:::-;157704:9:::1;;157685:13;:11;:13::i;:::-;157675:23;::::0;:7;:23:::1;:::i;:::-;157674:40;;157666:65;;;;-1:-1:-1::0;;;157666:65:0::1;;;;;;;:::i;:::-;157796:18;::::0;;;:11:::1;:18;::::0;;;;;;;;157775:8:::1;:15:::0;;;;;;;157765:25:::1;::::0;:7;:25:::1;:::i;:::-;157764:51;;157742:116;;;;-1:-1:-1::0;;;157742:116:0::1;;;;;;;:::i;:::-;157872:11:::0;;157869:78:::1;;157899:36;157920:5;157927:7;157899:20;:36::i;:::-;157957:28;157967:8;157977:7;157957:9;:28::i;156321:345::-:0;156452:7;156487:20;;;:13;:20;;;;;;;;:27;;;;;;;;;156529:17;;;:10;:17;;;;;:24;;;;;;;;-1:-1:-1;;;;;156529:34:0;;;;;;;;;;:38;156525:112;;-1:-1:-1;156591:17:0;;;;:10;:17;;;;;;;;:24;;;;;;;;-1:-1:-1;;;;;156591:34:0;;;;;;;;;;156525:112;156654:4;156321:345;-1:-1:-1;;;;156321:345:0:o;153374:113::-;129715:32;99936:10;129715:18;:32::i;:::-;153456:8:::1;:23:::0;153374:113::o;168284:185::-;168382:6;;129715:32;99936:10;129715:18;:32::i;:::-;168416:45:::1;168439:21;168451:8;168439:11;:21::i;168416:45::-;168409:52;;;;168284:185:::0;;;:::o;156674:749::-;156764:13;156798:17;156806:8;156798:7;:17::i;:::-;156790:61;;;;-1:-1:-1;;;156790:61:0;;29345:2:1;156790:61:0;;;29327:21:1;29384:2;29364:18;;;29357:30;29423:33;29403:18;;;29396:61;29474:18;;156790:61:0;29143:355:1;156790:61:0;156866:21;156878:8;153645;;-1:-1:-1;153633:20:0;;153523:138;156866:21;156862:316;;;157000:17;:15;:17::i;:::-;157044:39;157061:21;157073:8;157061:11;:21::i;:::-;157044:16;:39::i;:::-;157110:14;156957:190;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;156904:262;;156674:749;;;:::o;156862:316::-;157272:9;157304:40;157321:22;157334:8;157321:12;:22::i;157304:40::-;157367:14;157233:167;;;;;;;;;;:::i;170633:374::-;170691:7;170730:1;170691:7;170742:239;170765:2;170761:1;:6;170742:239;;;170793:13;;;;:10;:13;;;;;;;;:16;;;;;;;;;:21;170789:85;;-1:-1:-1;;;170842:13:0;;;;:10;:13;;;;;;;;:16;;;;;;;;;170835:23;;170789:85;170888:3;;;;:::i;:::-;;-1:-1:-1;170914:14:0;;-1:-1:-1;170914:9:0;170926:2;170914:14;:::i;:::-;170910:1;:18;170949:5;170906:64;170769:3;;170742:239;;;-1:-1:-1;170998:1:0;;170633:374;-1:-1:-1;;;;170633:374:0:o;129062:497::-;129241:26;;-1:-1:-1;;;;;;31833:2:1;31804:15;;;31800:45;129241:26:0;;;31788:58:1;129198:4:0;;;;31862:12:1;;129241:26:0;;;;;;;;;;;;129231:37;;;;;;129215:53;;129284:9;129279:226;129303:6;:13;129299:1;:17;129279:226;;;129354:6;129361:1;129354:9;;;;;;;;:::i;:::-;;;;;;;129346:5;:17;:147;;129475:6;129482:1;129475:9;;;;;;;;:::i;:::-;;;;;;;129486:5;129458:34;;;;;;;;32042:19:1;;;32086:2;32077:12;;32070:28;32123:2;32114:12;;31885:247;129458:34:0;;;;;;;;;;;;;129448:45;;;;;;129346:147;;;129410:5;129417:6;129424:1;129417:9;;;;;;;;:::i;:::-;;;;;;;129393:34;;;;;;;;32042:19:1;;;32086:2;32077:12;;32070:28;32123:2;32114:12;;31885:247;129393:34:0;;;;;;;;;;;;;129383:45;;;;;;129346:147;129338:155;-1:-1:-1;129318:3:0;;129279:226;;;-1:-1:-1;129531:20:0;;;;:13;:20;;;;;;129522:29;;-1:-1:-1;129062:497:0;;;;;:::o;167017:155::-;129715:32;99936:10;129715:18;:32::i;:::-;167091:7:::1;167104:21;167118:6;;167104:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;167104:13:0::1;::::0;-1:-1:-1;;;167104:21:0:i:1;:::-;167091:35:::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;167091:35:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;;;;167091:35:0::1;-1:-1:-1::0;;;;;167091:35:0;;;::::1;::::0;;;::::1;::::0;;167146:7:::1;:14:::0;:18:::1;::::0;167091:35;167146:18:::1;:::i;:::-;167137:6;:27:::0;-1:-1:-1;;167017:155:0:o;155562:150::-;129715:32;99936:10;129715:18;:32::i;:::-;155670:14:::1;:34;155687:17:::0;155670:14;:34:::1;:::i;150626:115::-:0;150680:13;150713:20;:18;:20::i;143312:284::-;143434:4;143455:27;143466:5;143473:8;143455:10;:27::i;:::-;:36;;143486:5;143455:36;143451:81;;-1:-1:-1;143515:5:0;143508:12;;143451:81;-1:-1:-1;;;;;106253:25:0;;;106229:4;106253:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;143549:39;106107:189;122318:238;121298:13;:11;:13::i;:::-;-1:-1:-1;;;;;122421:22:0;::::1;122399:110;;;::::0;-1:-1:-1;;;122399:110:0;;32339:2:1;122399:110:0::1;::::0;::::1;32321:21:1::0;32378:2;32358:18;;;32351:30;32417:34;32397:18;;;32390:62;-1:-1:-1;;;32468:18:1;;;32461:36;32514:19;;122399:110:0::1;32137:402:1::0;122399:110:0::1;122520:28;122539:8;122520:18;:28::i;165877:159::-:0;129715:32;99936:10;129715:18;:32::i;:::-;165990:38:::1;166017:10;165990:26;:38::i;140809:184::-:0;140914:16;140955:30;:21;:28;:30::i;96233:257::-;96351:4;-1:-1:-1;;;;;;96388:41:0;;-1:-1:-1;;;96388:41:0;;:94;;;96446:36;96470:11;96446:23;:36::i;130480:370::-;-1:-1:-1;;;;;130574:21:0;;;;;;:10;:21;;;;;;;;130707:46;99936:10;130735:12;-1:-1:-1;;;;;130707:46:0;130750:2;130707:19;:46::i;:::-;130635:181;;;;;;;;:::i;:::-;;;;;;;;;;;;;130552:290;;;;;-1:-1:-1;;;130552:290:0;;;;;;;;:::i;97675:394::-;97391:5;-1:-1:-1;;;;;97817:33:0;;;;97795:125;;;;-1:-1:-1;;;97795:125:0;;33362:2:1;97795:125:0;;;33344:21:1;33401:2;33381:18;;;33374:30;33440:34;33420:18;;;33413:62;-1:-1:-1;;;33491:18:1;;;33484:40;33541:19;;97795:125:0;33160:406:1;97795:125:0;-1:-1:-1;;;;;97939:22:0;;97931:60;;;;-1:-1:-1;;;97931:60:0;;33773:2:1;97931:60:0;;;33755:21:1;33812:2;33792:18;;;33785:30;-1:-1:-1;;;33831:18:1;;;33824:55;33896:18;;97931:60:0;33571:349:1;97931:60:0;98026:35;;;;;;;;;-1:-1:-1;;;;;98026:35:0;;;;;;-1:-1:-1;;;;;98026:35:0;;;;;;;;;;-1:-1:-1;;;98004:57:0;;;;:19;:57;97675:394::o;119076:224::-;119166:4;119187:25;:12;119204:7;119187:16;:25::i;:::-;119183:70;;;-1:-1:-1;119236:5:0;;119076:224;-1:-1:-1;119076:224:0:o;119183:70::-;119270:22;119284:7;119270:13;:22::i;144205:153::-;144286:27;144301:2;144305:7;144286:14;:27::i;:::-;144324:26;144338:2;144342:7;144324:13;:26::i;168477:597::-;168585:7;168619:5;168585:7;168651:13;:9;168663:1;168651:13;:::i;:::-;168635:29;;168687:1;168679:5;:9;168675:129;;;168712:16;168724:4;168712:9;:16;:::i;:::-;168711:22;;168732:1;168711:22;:::i;:::-;168705:28;-1:-1:-1;168771:7:0;168777:1;168705:28;168771:7;:::i;:::-;168770:16;;168782:4;168770:16;:::i;:::-;168757:30;;:9;:30;:::i;:::-;168756:36;;168791:1;168756:36;:::i;:::-;168748:44;;168675:129;168814:17;168834:44;168847:7;168855:3;168847:12;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;168847:12:0;168861:5;168868:9;168861:5;168876:1;168868:9;:::i;:::-;168834:12;:44::i;:::-;168974:2;168964:13;168958:20;169029:8;169014:24;;168477:597;-1:-1:-1;;;;;;168477:597:0:o;169359:1266::-;169491:8;169501;169513:28;169536:4;169513:22;:28::i;:::-;169490:51;;;;169552:14;169577;169602:13;169693:5;169702:1;169693:10;169689:551;;-1:-1:-1;169729:2:0;;-1:-1:-1;169755:1:0;;-1:-1:-1;169779:2:0;169689:551;;;169803:5;169812:1;169803:10;169799:441;;-1:-1:-1;169839:1:0;;-1:-1:-1;169864:1:0;;-1:-1:-1;169888:2:0;169799:441;;;169912:5;169921:1;169912:10;169908:332;;-1:-1:-1;169948:1:0;;-1:-1:-1;169948:1:0;;-1:-1:-1;169997:1:0;169908:332;;;170020:5;170029:1;170020:10;170016:224;;-1:-1:-1;170056:1:0;;-1:-1:-1;170056:1:0;;-1:-1:-1;170105:1:0;170016:224;;;-1:-1:-1;;;170139:13:0;;;;:10;:13;;;;;;;;:16;;;;;;;;:27;-1:-1:-1;;169359:1266:0:o;170016:224::-;170250:19;;;;:9;:19;;;;;:27;;;170306:18;170317:6;170306:1;:18;:::i;:::-;170290:34;-1:-1:-1;170335:11:0;170374:1;170349:22;170365:5;170290:34;170349:22;:::i;:::-;:26;;;;:::i;:::-;170335:40;-1:-1:-1;170386:13:0;170402:18;170413:6;170402:1;:18;:::i;:::-;170386:34;-1:-1:-1;170431:11:0;170470:1;170445:22;170461:5;170386:34;170445:22;:::i;:::-;:26;;;;:::i;:::-;170431:40;-1:-1:-1;170537:6:0;170521:97;170550:4;170545:1;:9;170521:97;;170576:16;;;;:10;:16;;;;;;;;:19;;;;;;;;:30;;;170593:1;170556:3;170593:1;170556:3;:::i;:::-;;;;170521:97;;;;169479:1146;;;;;;;;;169359:1266;;;:::o;119569:350::-;101876:13;;119611:14;;;;;;119712:25;;119679:1;119713:19;119736:1;119712:25;:::i;:::-;119691:46;-1:-1:-1;119767:11:0;119750:162;119784:10;119780:1;:14;119750:162;;;119816:14;83008:20;;;119833:12;83008:20;;;;;;119883:17;83008:20;119883:9;:17::i;:::-;119873:27;;;;:::i;:::-;;-1:-1:-1;;119796:3:0;;119750:162;;;;119627:292;;119569:350;:::o;101995:121::-;102050:7;150052:1;102077:13;;:31;;;;:::i;85466:293::-;84868:1;85600:7;;:19;85592:63;;;;-1:-1:-1;;;85592:63:0;;34127:2:1;85592:63:0;;;34109:21:1;34166:2;34146:18;;;34139:30;34205:33;34185:18;;;34178:61;34256:18;;85592:63:0;33925:355:1;85592:63:0;84868:1;85733:7;:18;85466:293::o;160305:498::-;160387:20;160410:13;:11;:13::i;:::-;:17;;160426:1;160410:17;:::i;:::-;160387:40;;160443:9;160438:321;160462:7;160458:1;:11;160438:321;;;160491:15;160509:16;160524:1;160509:12;:16;:::i;:::-;160540;160559:15;;;:8;:15;;;;;;160491:34;;-1:-1:-1;160540:16:0;160559:19;;160577:1;;160559:19;:::i;:::-;160540:38;;160593:18;160614:33;160631:8;160641:5;160614:16;:33::i;:::-;160662:17;;;;:8;:17;;;;;:30;;;160593:54;-1:-1:-1;160707:40:0;160593:54;160732:5;160671:7;160707:12;:40::i;:::-;-1:-1:-1;;;160471:3:0;;160438:321;;;-1:-1:-1;160769:15:0;;;;:8;:15;;;;;:26;;160788:7;;160769:15;:26;;160788:7;;160769:26;:::i;110045:112::-;110122:27;110132:2;110136:8;110122:27;;;;;;;;;;;;:9;:27::i;106363:379::-;106572:41;99936:10;106605:7;106572:18;:41::i;:::-;106550:143;;;;-1:-1:-1;;;106550:143:0;;;;;;;:::i;:::-;106706:28;106716:4;106722:2;106726:7;106706:9;:28::i;121577:132::-;99936:10;121641:7;:5;:7::i;:::-;-1:-1:-1;;;;;121641:23:0;;121633:68;;;;-1:-1:-1;;;121633:68:0;;34908:2:1;121633:68:0;;;34890:21:1;;;34927:18;;;34920:30;34986:34;34966:18;;;34959:62;35038:18;;121633:68:0;34706:356:1;129896:421:0;-1:-1:-1;;;;;129987:22:0;;;;;;:10;:22;;;;;;;;129986:23;130121:46;99936:10;130149:12;99856:98;130121:46;130049:194;;;;;;;;:::i;:::-;;;;;;;;;;;;;129964:305;;;;;-1:-1:-1;;;129964:305:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;130280:22:0;;;;;:10;:22;;;;;:29;;-1:-1:-1;;130280:29:0;130305:4;130280:29;;;129896:421::o;106813:185::-;106951:39;106968:4;106974:2;106978:7;106951:39;;;;;;;;;;;;:16;:39::i;118450:313::-;118510:12;118525:16;118533:7;118525;:16::i;:::-;118510:31;;118552:51;118574:4;118588:1;118592:7;118601:1;118552:21;:51::i;:::-;118614:25;:12;118631:7;118614:16;:25::i;:::-;118657:35;;118684:7;;118680:1;;-1:-1:-1;;;;;118657:35:0;;;-1:-1:-1;;;;;;;;;;;118657:35:0;118680:1;;118657:35;118705:50;118726:4;118740:1;118744:7;118753:1;118705:20;:50::i;3781:510::-;3834:15;3949:17;3969:82;4034:5;4008:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;3969:24;:82::i;:::-;3949:102;;4171:4;4165:11;4160:2;4154:4;4150:13;4147:1;4140:37;4129:48;-1:-1:-1;;;;;;4241:21:0;;4237:46;;4271:12;;-1:-1:-1;;;4271:12:0;;;;;;;;;;;4237:46;3851:440;3781:510;;;:::o;103321:360::-;103415:13;103430:24;103489:16;103497:7;103489;:16::i;:::-;103467:110;;;;-1:-1:-1;;;103467:110:0;;36330:2:1;103467:110:0;;;36312:21:1;36369:2;36349:18;;;36342:30;36408:34;36388:18;;;36381:62;-1:-1:-1;;;36459:18:1;;;36452:42;36511:19;;103467:110:0;36128:408:1;103467:110:0;103607:22;103621:7;103607:13;:22::i;:::-;103648:25;;;;:7;:25;;;;;;-1:-1:-1;;;;;103648:25:0;;103588:41;;-1:-1:-1;103321:360:0;-1:-1:-1;;103321:360:0:o;122716:191::-;122790:16;122809:6;;-1:-1:-1;;;;;122826:17:0;;;-1:-1:-1;;;;;;122826:17:0;;;;;;122859:40;;122809:6;;;;;;;122859:40;;122790:16;122859:40;122779:128;122716:191;:::o;140595:206::-;140698:40;:21;140727:10;140698:28;:40::i;:::-;-1:-1:-1;140754:39:0;;-1:-1:-1;;;;;140754:39:0;;;140770:10;;140754:39;;;;;140595:206;:::o;143604:318::-;143746:20;143757:8;143746:10;:20::i;:::-;:41;;;-1:-1:-1;143770:17:0;;143746:41;143724:136;;;;-1:-1:-1;;;143724:136:0;;36743:2:1;143724:136:0;;;36725:21:1;36782:2;36762:18;;;36755:30;36821:34;36801:18;;;36794:62;-1:-1:-1;;;36872:18:1;;;36865:43;36925:19;;143724:136:0;36541:409:1;143724:136:0;143871:43;143895:8;143905;143871:23;:43::i;130325:147::-;130394:30;130413:10;130394:18;:30::i;:::-;-1:-1:-1;;;;;130442:22:0;;;;;:10;:22;;;;;130435:29;;-1:-1:-1;;130435:29:0;;;130325:147::o;107069:368::-;107258:41;99936:10;107291:7;107258:18;:41::i;:::-;107236:143;;;;-1:-1:-1;;;107236:143:0;;;;;;;:::i;:::-;107390:39;107404:4;107410:2;107414:7;107423:5;107390:13;:39::i;155755:104::-;155805:13;155838;155831:20;;;;;:::i;66386:716::-;66442:13;66493:14;66510:17;66521:5;66510:10;:17::i;:::-;66530:1;66510:21;66493:38;;66546:20;66580:6;-1:-1:-1;;;;;66569:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66569:18:0;-1:-1:-1;66546:41:0;-1:-1:-1;66711:28:0;;;66727:2;66711:28;66768:288;-1:-1:-1;;66800:5:0;-1:-1:-1;;;66937:2:0;66926:14;;66921:30;66800:5;66908:44;66998:2;66989:11;;;-1:-1:-1;67019:21:0;66768:288;67019:21;-1:-1:-1;67077:6:0;66386:716;-1:-1:-1;;;66386:716:0:o;150773:993::-;150826:13;150853:16;;150898:70;150853:16;97391:5;150898:11;:70::i;:::-;150852:116;;;;151129:595;151320:33;151337:15;151320:16;:33::i;:::-;151444:160;151518:8;-1:-1:-1;;;;;151502:26:0;151567:2;151444:19;:160::i;:::-;151205:469;;;;;;;;;:::i;:::-;;;;;;;;;;;;;151129:13;:595::i;:::-;151036:707;;;;;;;;:::i;:::-;;;;;;;;;;;;;150991:767;;;;150773:993;:::o;141578:220::-;141690:4;141707:13;141723:20;141736:6;141723:12;:20::i;:::-;141707:36;;141761:29;141772:10;141784:5;141761:10;:29::i;140405:182::-;140489:37;:21;140515:10;140489:25;:37::i;:::-;-1:-1:-1;140542:37:0;;-1:-1:-1;;;;;140542:37:0;;;140556:10;;140542:37;;;;;140405:182;:::o;36778:326::-;36857:16;36886:22;36911:19;36919:3;36911:7;:19::i;144817:254::-;144918:4;-1:-1:-1;;;;;;144955:55:0;;-1:-1:-1;;;144955:55:0;;:108;;;145027:36;145051:11;145027:23;:36::i;67518:472::-;67618:13;67644:19;67676:10;67680:6;67676:1;:10;:::i;:::-;:14;;67689:1;67676:14;:::i;:::-;-1:-1:-1;;;;;67666:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67666:25:0;;67644:47;;-1:-1:-1;;;67702:6:0;67709:1;67702:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;67702:15:0;;;;;;;;;-1:-1:-1;;;67728:6:0;67735:1;67728:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;67728:15:0;;;;;;;;-1:-1:-1;67759:9:0;67771:10;67775:6;67771:1;:10;:::i;:::-;:14;;67784:1;67771:14;:::i;:::-;67759:26;;67754:131;67791:1;67787;:5;67754:131;;;-1:-1:-1;;;67835:5:0;67843:3;67835:11;67826:21;;;;;;;:::i;:::-;;;;67814:6;67821:1;67814:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;67814:33:0;;;;;;;;-1:-1:-1;67872:1:0;67862:11;;;;;67794:3;;;:::i;:::-;;;67754:131;;;-1:-1:-1;67903:10:0;;67895:55;;;;-1:-1:-1;;;67895:55:0;;38818:2:1;67895:55:0;;;38800:21:1;;;38837:18;;;38830:30;38896:34;38876:18;;;38869:62;38948:18;;67895:55:0;38616:356:1;75841:260:0;75983:1;75974:10;;;75940:4;76061:20;;;;;;;;;;;-1:-1:-1;;;76038:4:0;76030:12;;76010:33;76061:27;:32;;75841:260;;;;:::o;108932:151::-;108997:4;109031:14;101876:13;;;101794:103;109031:14;109021:7;:24;:54;;;;-1:-1:-1;;150052:1:0;109049:26;;;108932:151::o;143930:267::-;-1:-1:-1;;;;;144015:16:0;;;144011:179;;144074:23;144085:7;144094:2;144074:10;:23::i;:::-;144048:130;;;;-1:-1:-1;;;144048:130:0;;39179:2:1;144048:130:0;;;39161:21:1;39218:2;39198:18;;;39191:30;39257:34;39237:18;;;39230:62;-1:-1:-1;;;39308:18:1;;;39301:43;39361:19;;144048:130:0;38977:409:1;104888:410:0;104969:13;104985:16;104993:7;104985;:16::i;:::-;104969:32;;105026:5;-1:-1:-1;;;;;105020:11:0;:2;-1:-1:-1;;;;;105020:11:0;;105012:60;;;;-1:-1:-1;;;105012:60:0;;39593:2:1;105012:60:0;;;39575:21:1;39632:2;39612:18;;;39605:30;39671:34;39651:18;;;39644:62;-1:-1:-1;;;39722:18:1;;;39715:34;39766:19;;105012:60:0;39391:400:1;105012:60:0;99936:10;-1:-1:-1;;;;;105107:21:0;;;;:62;;-1:-1:-1;105132:37:0;105149:5;99936:10;143312:284;:::i;105132:37::-;105085:171;;;;-1:-1:-1;;;105085:171:0;;39998:2:1;105085:171:0;;;39980:21:1;40037:2;40017:18;;;40010:30;40076:34;40056:18;;;40049:62;-1:-1:-1;;;40127:18:1;;;40120:57;40194:19;;105085:171:0;39796:423:1;105085:171:0;105269:21;105278:2;105282:7;105269:8;:21::i;5563:206::-;5682:12;5714:47;5730:8;5740:10;:6;5749:1;5740:10;:::i;:::-;5752:8;:4;5759:1;5752:8;:::i;:::-;5714:15;:47::i;119986:165::-;120038:13;120089:43;120105:6;;120089:43;;-1:-1:-1;;120127:5:0;;120122:10;;;;120131:1;120113:7;120089:43;;110165:487;110296:19;110318:14;101876:13;;;101794:103;110318:14;110296:36;;110343:19;110349:2;110353:8;110343:5;:19::i;:::-;110395:168;110444:1;110465:2;110486:11;110516:8;110543:5;110395:22;:168::i;:::-;110373:271;;;;-1:-1:-1;;;110373:271:0;;;;;;;:::i;109250:432::-;109368:4;109407:16;109415:7;109407;:16::i;:::-;109385:113;;;;-1:-1:-1;;;109385:113:0;;40848:2:1;109385:113:0;;;40830:21:1;40887:2;40867:18;;;40860:30;40926:34;40906:18;;;40899:62;-1:-1:-1;;;40977:18:1;;;40970:45;41032:19;;109385:113:0;40646:411:1;109385:113:0;109509:13;109525:16;109533:7;109525;:16::i;:::-;109509:32;;109571:5;-1:-1:-1;;;;;109560:16:0;:7;-1:-1:-1;;;;;109560:16:0;;:64;;;;109617:7;-1:-1:-1;;;;;109593:31:0;:20;109605:7;109593:11;:20::i;:::-;-1:-1:-1;;;;;109593:31:0;;109560:64;:113;;;;109641:32;109658:5;109665:7;109641:16;:32::i;111749:1055::-;111874:13;111889:24;111917:53;111952:7;111917:20;:53::i;:::-;111873:97;;;;112000:4;-1:-1:-1;;;;;111991:13:0;:5;-1:-1:-1;;;;;111991:13:0;;111983:70;;;;-1:-1:-1;;;111983:70:0;;41264:2:1;111983:70:0;;;41246:21:1;41303:2;41283:18;;;41276:30;41342:34;41322:18;;;41315:62;-1:-1:-1;;;41393:18:1;;;41386:42;41445:19;;111983:70:0;41062:408:1;111983:70:0;-1:-1:-1;;;;;112072:16:0;;112064:68;;;;-1:-1:-1;;;112064:68:0;;41677:2:1;112064:68:0;;;41659:21:1;41716:2;41696:18;;;41689:30;41755:34;41735:18;;;41728:62;-1:-1:-1;;;41806:18:1;;;41799:37;41853:19;;112064:68:0;41475:403:1;112064:68:0;112145:43;112167:4;112173:2;112177:7;112186:1;112145:21;:43::i;:::-;112253:29;112270:1;112274:7;112253:8;:29::i;:::-;112295:25;112323:11;:7;112333:1;112323:11;:::i;:::-;112295:39;-1:-1:-1;112366:33:0;:10;112295:39;112366:14;:33::i;:::-;112365:34;:85;;;;-1:-1:-1;101876:13:0;;112416:17;:34;112365:85;112347:223;;;112477:26;;;;:7;:26;;;;;:33;;-1:-1:-1;;;;;;112477:33:0;-1:-1:-1;;;;;112477:33:0;;;;;112525;-1:-1:-1;112477:26:0;112525:14;:33::i;:::-;112582:16;;;;:7;:16;;;;;:21;;-1:-1:-1;;;;;;112582:21:0;-1:-1:-1;;;;;112582:21:0;;;;;112618:27;;;112614:83;;112662:23;:10;112677:7;112662:14;:23::i;:::-;112733:7;112729:2;-1:-1:-1;;;;;112714:27:0;112723:4;-1:-1:-1;;;;;112714:27:0;-1:-1:-1;;;;;;;;;;;112714:27:0;;;;;;;;;112754:42;112775:4;112781:2;112785:7;112794:1;112754:20;:42::i;:::-;111862:942;;;111749:1055;;;:::o;163511:577::-;-1:-1:-1;;;;;163684:18:0;;;163680:329;;163724:9;163719:279;163743:8;163739:1;:12;163719:279;;;163777:22;163802:16;163817:1;163802:12;:16;:::i;:::-;163867:11;;:35;;-1:-1:-1;;;163867:35:0;;;;;3690:25:1;;;163777:41:0;;-1:-1:-1;163905:1:0;;163867:11;;;;-1:-1:-1;;;;;163867:11:0;;:19;;3663:18:1;;163867:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;163837:145;;;;-1:-1:-1;;;163837:145:0;;42085:2:1;163837:145:0;;;42067:21:1;;;42104:18;;;42097:30;42163:34;42143:18;;;42136:62;42215:18;;163837:145:0;41883:356:1;163837:145:0;-1:-1:-1;163753:3:0;;163719:279;;;;164019:61;164980:197;76453:204;76550:1;76541:10;;;76524:14;76621:20;;;;;;;;;;;;:28;;-1:-1:-1;;;76605:4:0;76597:12;;;76577:33;;;;76621:28;;;;;76453:204::o;144366:443::-;-1:-1:-1;;;;;144662:18:0;;;144658:144;;142793:22;;;;:13;:22;;;;;142786:29;144756:34;142711:112;466:805;550:12;1161:5;:12;1243:5;1093:170;;;;;;;;;:::i;115125:174::-;115204:24;115260:31;:10;115283:7;115260:22;:31::i;35027:183::-;35125:4;35149:53;35157:3;-1:-1:-1;;;;;35177:23:0;;35149:7;:53::i;141175:153::-;141262:4;141286:34;141297:10;141309;141286;:34::i;105713:323::-;99936:10;-1:-1:-1;;;;;105841:24:0;;;105833:65;;;;-1:-1:-1;;;105833:65:0;;43142:2:1;105833:65:0;;;43124:21:1;43181:2;43161:18;;;43154:30;43220;43200:18;;;43193:58;43268:18;;105833:65:0;42940:352:1;105833:65:0;99936:10;105911:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;105911:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;105911:53:0;;;;;;;;;;105980:48;;1203:41:1;;;105911:42:0;;99936:10;105980:48;;1176:18:1;105980:48:0;;;;;;;105713:323;;:::o;108319:358::-;108476:28;108486:4;108492:2;108496:7;108476:9;:28::i;:::-;108537:51;108560:4;108566:2;108570:7;108579:1;108582:5;108537:22;:51::i;63110:948::-;63163:7;;-1:-1:-1;;;63241:17:0;;63237:106;;-1:-1:-1;;;63279:17:0;;;-1:-1:-1;63325:2:0;63315:12;63237:106;-1:-1:-1;;;63361:5:0;:17;63357:106;;-1:-1:-1;;;63399:17:0;;;-1:-1:-1;63445:2:0;63435:12;63357:106;63490:8;63481:5;:17;63477:106;;63528:8;63519:17;;;-1:-1:-1;63565:2:0;63555:12;63477:106;63610:7;63601:5;:16;63597:103;;63647:7;63638:16;;;-1:-1:-1;63683:1:0;63673:11;63597:103;63727:7;63718:5;:16;63714:103;;63764:7;63755:16;;;-1:-1:-1;63800:1:0;63790:11;63714:103;63844:7;63835:5;:16;63831:103;;63881:7;63872:16;;;-1:-1:-1;63917:1:0;63907:11;63831:103;63961:7;63952:5;:16;63948:68;;63999:1;63989:11;64044:6;63110:948;-1:-1:-1;;63110:948:0:o;123607:2164::-;123665:13;123695:4;:11;123710:1;123695:16;123691:31;;-1:-1:-1;;123713:9:0;;;;;;;;;-1:-1:-1;123713:9:0;;;123607:2164::o;123691:31::-;123774:19;123796:12;;;;;;;;;;;;;;;;;123774:34;;123860:18;123906:1;123887:4;:11;123901:1;123887:15;;;;:::i;:::-;123886:21;;;;:::i;:::-;123881:27;;:1;:27;:::i;:::-;123860:48;-1:-1:-1;123991:20:0;124025:15;123860:48;124038:2;124025:15;:::i;:::-;-1:-1:-1;;;;;124014:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;124014:27:0;;123991:50;;124138:10;124130:6;124123:26;124233:1;124226:5;124222:13;124292:4;124343;124337:11;124328:7;124324:25;124439:2;124431:6;124427:15;124512:946;124547:6;124538:7;124535:19;124512:946;;;124650:1;124641:7;124637:15;124626:26;;124689:7;124683:14;124858:4;124850:5;124846:2;124842:14;124838:25;124828:8;124824:40;124818:47;124786:9;124756:128;124930:1;124919:9;124915:17;124902:30;;125052:4;125044:5;125040:2;125036:14;125032:25;125022:8;125018:40;125012:47;124980:9;124950:128;125124:1;125113:9;125109:17;125096:30;;125245:4;125237:5;125234:1;125230:13;125226:24;125216:8;125212:39;125206:46;125174:9;125144:127;125317:1;125306:9;125302:17;125289:30;;125387:4;125380:5;125376:16;125366:8;125362:31;125356:38;125345:9;125337:58;-1:-1:-1;125441:1:0;125426:17;124512:946;;;125531:1;125524:4;125518:11;125514:19;125552:1;125547:84;;;;125650:1;125645:82;;;;125507:220;;125547:84;-1:-1:-1;;;;;125580:17:0;;125573:43;125547:84;;125645:82;-1:-1:-1;;;;;125678:17:0;;125671:41;125507:220;-1:-1:-1;125757:6:0;;123607:2164;-1:-1:-1;;;;;;;;123607:2164:0:o;142365:228::-;-1:-1:-1;;;;;142474:22:0;;142450:7;142474:22;;;:14;:22;;;;;;:26;142470:88;;-1:-1:-1;;;;;;142524:22:0;;;;;:14;:22;;;;;;;142365:228::o;142470:88::-;-1:-1:-1;;142577:8:0;;;142365:228::o;141806:277::-;141939:14;;141917:4;;141939:14;;141934:59;;-1:-1:-1;141977:4:0;141970:11;;141934:59;142012:27;142028:10;142012:15;:27::i;:::-;:63;;;-1:-1:-1;142043:3:0;;:32;;-1:-1:-1;;;142043:32:0;;-1:-1:-1;;;;;142043:3:0;;;;:13;;:32;;142057:10;;142069:5;;142043:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;34674:177::-;34769:4;34793:50;34798:3;-1:-1:-1;;;;;34818:23:0;;34793:4;:50::i;31733:111::-;31789:16;31825:3;:11;;31818:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31733:111;;;:::o;102188:321::-;102306:4;-1:-1:-1;;;;;;102343:40:0;;-1:-1:-1;;;102343:40:0;;:105;;-1:-1:-1;;;;;;;102400:48:0;;-1:-1:-1;;;102400:48:0;102343:105;:158;;;-1:-1:-1;;;;;;;;;;93906:40:0;;;102465:36;93781:173;141336:234;141449:4;141466:13;141482:33;141495:10;141507:7;141482:12;:33::i;112922:167::-;112997:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;112997:29:0;-1:-1:-1;;;;;112997:29:0;;;;;;;;:24;;113051:16;112997:24;113051:7;:16::i;:::-;-1:-1:-1;;;;;113042:39:0;;;;;;;;;;;112922:167;;:::o;2043:1193::-;2161:18;1578;;2192:13;2238:10;;;2234:32;;-1:-1:-1;;2257:9:0;;;;;;;;;-1:-1:-1;2257:9:0;;2250:16;;2234:32;2292:5;2283:6;:14;2279:36;;;-1:-1:-1;;2306:9:0;;;;;;;;;-1:-1:-1;2306:9:0;;2299:16;;2279:36;2337:6;2330:4;:13;2326:65;;;2352:39;;-1:-1:-1;;;2352:39:0;;;;;43499:25:1;;;43540:18;;;43533:34;;;43583:18;;;43576:34;;;43472:18;;2352:39:0;43297:319:1;2326:65:0;2447:13;;;2493:14;;;2429:15;2539:17;;;:37;;2569:7;2539:37;;;2559:7;2539:37;2780:4;2774:11;;2929:26;;;-1:-1:-1;;2925:42:0;2914:54;;2858:129;;;3048:19;;;2774:11;-1:-1:-1;2524:52:0;-1:-1:-1;2524:52:0;3190:6;2943:4;3172:16;;3165:5;3153:50;2602:616;;;2181:1055;2043:1193;;;;;:::o;110660:752::-;110733:19;110755:14;101876:13;;;101794:103;110755:14;110733:36;;110801:1;110790:8;:12;110782:62;;;;-1:-1:-1;;;110782:62:0;;43823:2:1;110782:62:0;;;43805:21:1;43862:2;43842:18;;;43835:30;43901:34;43881:18;;;43874:62;-1:-1:-1;;;43952:18:1;;;43945:35;43997:19;;110782:62:0;43621:401:1;110782:62:0;-1:-1:-1;;;;;110863:16:0;;110855:64;;;;-1:-1:-1;;;110855:64:0;;44229:2:1;110855:64:0;;;44211:21:1;44268:2;44248:18;;;44241:30;44307:34;44287:18;;;44280:62;-1:-1:-1;;;44358:18:1;;;44351:33;44401:19;;110855:64:0;44027:399:1;110855:64:0;110932:60;110962:1;110966:2;110970:11;110983:8;110932:21;:60::i;:::-;111020:8;111003:13;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;111039:20:0;;;;:7;:20;;;;;:25;;-1:-1:-1;;;;;;111039:25:0;-1:-1:-1;;;;;111039:25:0;;;;;111075:27;-1:-1:-1;111039:20:0;111075:14;:27::i;:::-;111113:59;111142:1;111146:2;111150:11;111163:8;111113:20;:59::i;:::-;111246:11;111209:196;111282:22;111296:8;111282:11;:22;:::i;:::-;111272:7;:32;111209:196;;;111360:33;;111385:7;;-1:-1:-1;;;;;111360:33:0;;;111377:1;;-1:-1:-1;;;;;;;;;;;111360:33:0;111377:1;;111360:33;111319:9;;111209:196;;113743:1374;113930:6;-1:-1:-1;;;;;113953:13:0;;44050:19;:23;113949:1161;;-1:-1:-1;113989:4:0;114049:12;114008:1024;114090:23;114105:8;114090:12;:23;:::i;:::-;114080:7;:33;114008:1024;;;114201:195;;-1:-1:-1;;;114201:195:0;;-1:-1:-1;;;;;114201:36:0;;;;;:195;;99936:10;;114303:4;;114334:7;;114368:5;;114201:195;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;114201:195:0;;;;;;;;-1:-1:-1;;114201:195:0;;;;;;;;;;;;:::i;:::-;;;114176:841;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114647:6;:13;114664:1;114647:18;114643:355;;114694:119;;-1:-1:-1;;;114694:119:0;;;;;;;:::i;114643:355::-;114940:6;114934:13;114925:6;114921:2;114917:15;114910:38;114176:841;114490:1;:81;;;;-1:-1:-1;;;;;;;114520:51:0;;-1:-1:-1;;;114520:51:0;114490:81;114461:110;;114414:177;114132:9;;114008:1024;;;;115046:8;;113949:1161;-1:-1:-1;115094:4:0;113949:1161;113743:1374;;;;;;;:::o;81475:1392::-;81640:1;81631:10;;;81582:19;81797:20;;;;;;;;;;;81582:19;;81631:10;81721:4;81713:12;;;;81902:18;;;81895:26;81967:6;;81963:897;;82106:22;:2;:20;:22::i;:::-;82092:36;;:11;:36;82065:1;82055:6;:11;;82054:75;82019:110;;81963:897;;;82248:1;82239:6;:10;82209:136;;;;-1:-1:-1;;;82209:136:0;;45381:2:1;82209:136:0;;;45363:21:1;45420:2;45400:18;;;45393:30;45459:34;45439:18;;;45432:62;-1:-1:-1;;;45510:18:1;;;45503:50;45570:19;;82209:136:0;45179:416:1;82209:136:0;-1:-1:-1;;;82397:8:0;;;82528:12;:20;;;;;;;;;;;82397:8;;-1:-1:-1;82573:6:0;;82569:265;;82736:22;:2;:20;:22::i;:::-;82730:3;:28;82684:75;;82695:1;82685:6;:11;;82684:75;82641:118;;82786:5;;82569:265;82177:672;;;81603:1264;;;81475:1392;;;;:::o;28829:1420::-;28895:4;29034:19;;;:12;;;:19;;;;;;29070:15;;29066:1176;;29445:21;29469:14;29482:1;29469:10;:14;:::i;:::-;29518:18;;29445:38;;-1:-1:-1;29498:17:0;;29518:22;;29539:1;;29518:22;:::i;:::-;29498:42;;29574:13;29561:9;:26;29557:405;;29608:17;29628:3;:11;;29640:9;29628:22;;;;;;;;:::i;:::-;;;;;;;;;29608:42;;29782:9;29753:3;:11;;29765:13;29753:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;29867:23;;;:12;;;:23;;;;;:36;;;29557:405;30043:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;30138:3;:12;;:19;30151:5;30138:19;;;;;;;;;;;30131:26;;;30181:4;30174:11;;;;;;;29066:1176;30225:5;30218:12;;;;;141001:166;141093:4;141117:42;:21;141148:10;-1:-1:-1;;;;;35455:23:0;;35401:4;30457:19;;;:12;;;:19;;;;;;:24;;35425:55;30335:154;28239:414;28302:4;30457:19;;;:12;;;:19;;;;;;28319:327;;-1:-1:-1;28362:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;28545:18;;28523:19;;;:12;;;:19;;;;;;:40;;;;28578:11;;28319:327;-1:-1:-1;28629:5:0;28622:12;;142091:266;142202:7;142226:22;;;:13;:22;;;;;;:26;142222:88;;-1:-1:-1;142276:22:0;;;;:13;:22;;;;;;142269:29;;142222:88;142329:20;142342:6;142329:12;:20::i;73212:255::-;73274:5;73369:16;;;;;;;;;;;;;;;;;73425:3;71736:64;73387:18;73402:2;73387:14;:18::i;:::-;:33;73386:42;;73369:60;;;;;;;;:::i;:::-;;;;;;;;73212:255;-1:-1:-1;;73212:255:0:o;72455:169::-;72514:7;72547:1;72542:2;:6;72534:15;;;;;;-1:-1:-1;72598:1:0;:6;;;72592:13;;72455:169::o;14:658:1:-;185:2;237:21;;;307:13;;210:18;;;329:22;;;156:4;;185:2;408:15;;;;382:2;367:18;;;156:4;451:195;465:6;462:1;459:13;451:195;;;530:13;;-1:-1:-1;;;;;526:39:1;514:52;;621:15;;;;586:12;;;;562:1;480:9;451:195;;;-1:-1:-1;663:3:1;;14:658;-1:-1:-1;;;;;;14:658:1:o;677:131::-;-1:-1:-1;;;;;;751:32:1;;741:43;;731:71;;798:1;795;788:12;813:245;871:6;924:2;912:9;903:7;899:23;895:32;892:52;;;940:1;937;930:12;892:52;979:9;966:23;998:30;1022:5;998:30;:::i;1255:131::-;-1:-1:-1;;;;;1330:31:1;;1320:42;;1310:70;;1376:1;1373;1366:12;1391:247;1450:6;1503:2;1491:9;1482:7;1478:23;1474:32;1471:52;;;1519:1;1516;1509:12;1471:52;1558:9;1545:23;1577:31;1602:5;1577:31;:::i;1643:427::-;1710:6;1718;1771:2;1759:9;1750:7;1746:23;1742:32;1739:52;;;1787:1;1784;1777:12;1739:52;1826:9;1813:23;1845:31;1870:5;1845:31;:::i;:::-;1895:5;-1:-1:-1;1952:2:1;1937:18;;1924:32;-1:-1:-1;;;;;1987:32:1;;1975:45;;1965:73;;2034:1;2031;2024:12;1965:73;2057:7;2047:17;;;1643:427;;;;;:::o;2075:250::-;2160:1;2170:113;2184:6;2181:1;2178:13;2170:113;;;2260:11;;;2254:18;2241:11;;;2234:39;2206:2;2199:10;2170:113;;;-1:-1:-1;;2317:1:1;2299:16;;2292:27;2075:250::o;2330:271::-;2372:3;2410:5;2404:12;2437:6;2432:3;2425:19;2453:76;2522:6;2515:4;2510:3;2506:14;2499:4;2492:5;2488:16;2453:76;:::i;:::-;2583:2;2562:15;-1:-1:-1;;2558:29:1;2549:39;;;;2590:4;2545:50;;2330:271;-1:-1:-1;;2330:271:1:o;2606:220::-;2755:2;2744:9;2737:21;2718:4;2775:45;2816:2;2805:9;2801:18;2793:6;2775:45;:::i;2831:180::-;2890:6;2943:2;2931:9;2922:7;2918:23;2914:32;2911:52;;;2959:1;2956;2949:12;2911:52;-1:-1:-1;2982:23:1;;2831:180;-1:-1:-1;2831:180:1:o;3016:203::-;-1:-1:-1;;;;;3180:32:1;;;;3162:51;;3150:2;3135:18;;3016:203::o;3224:315::-;3292:6;3300;3353:2;3341:9;3332:7;3328:23;3324:32;3321:52;;;3369:1;3366;3359:12;3321:52;3408:9;3395:23;3427:31;3452:5;3427:31;:::i;:::-;3477:5;3529:2;3514:18;;;;3501:32;;-1:-1:-1;;;3224:315:1:o;3726:316::-;3803:6;3811;3819;3872:2;3860:9;3851:7;3847:23;3843:32;3840:52;;;3888:1;3885;3878:12;3840:52;-1:-1:-1;;3911:23:1;;;3981:2;3966:18;;3953:32;;-1:-1:-1;4032:2:1;4017:18;;;4004:32;;3726:316;-1:-1:-1;3726:316:1:o;4047:383::-;4124:6;4132;4140;4193:2;4181:9;4172:7;4168:23;4164:32;4161:52;;;4209:1;4206;4199:12;4161:52;4245:9;4232:23;4222:33;;4302:2;4291:9;4287:18;4274:32;4264:42;;4356:2;4345:9;4341:18;4328:32;4369:31;4394:5;4369:31;:::i;:::-;4419:5;4409:15;;;4047:383;;;;;:::o;4435:456::-;4512:6;4520;4528;4581:2;4569:9;4560:7;4556:23;4552:32;4549:52;;;4597:1;4594;4587:12;4549:52;4636:9;4623:23;4655:31;4680:5;4655:31;:::i;:::-;4705:5;-1:-1:-1;4762:2:1;4747:18;;4734:32;4775:33;4734:32;4775:33;:::i;:::-;4435:456;;4827:7;;-1:-1:-1;;;4881:2:1;4866:18;;;;4853:32;;4435:456::o;4896:1263::-;5086:4;5115:2;5155;5144:9;5140:18;5185:2;5174:9;5167:21;5208:6;5243;5237:13;5274:6;5266;5259:22;5312:2;5301:9;5297:18;5290:25;;5374:2;5364:6;5361:1;5357:14;5346:9;5342:30;5338:39;5324:53;;5412:2;5404:6;5400:15;5433:1;5443:687;5457:6;5454:1;5451:13;5443:687;;;5522:22;;;-1:-1:-1;;5518:36:1;5506:49;;5578:13;;5652:9;;5674:24;;;5764:11;;;;5720:15;;;;5799:1;5813:209;5829:8;5824:3;5821:17;5813:209;;;5906:15;;5892:30;;5991:17;;;;5948:14;;;;5857:1;5848:11;5813:209;;;-1:-1:-1;6045:5:1;;-1:-1:-1;;;6108:12:1;;;;6073:15;;;;5479:1;5472:9;5443:687;;;-1:-1:-1;6147:6:1;;4896:1263;-1:-1:-1;;;;;;;4896:1263:1:o;6164:248::-;6232:6;6240;6293:2;6281:9;6272:7;6268:23;6264:32;6261:52;;;6309:1;6306;6299:12;6261:52;-1:-1:-1;;6332:23:1;;;6402:2;6387:18;;;6374:32;;-1:-1:-1;6164:248:1:o;6417:274::-;-1:-1:-1;;;;;6609:32:1;;;;6591:51;;6673:2;6658:18;;6651:34;6579:2;6564:18;;6417:274::o;6936:127::-;6997:10;6992:3;6988:20;6985:1;6978:31;7028:4;7025:1;7018:15;7052:4;7049:1;7042:15;7068:275;7139:2;7133:9;7204:2;7185:13;;-1:-1:-1;;7181:27:1;7169:40;;-1:-1:-1;;;;;7224:34:1;;7260:22;;;7221:62;7218:88;;;7286:18;;:::i;:::-;7322:2;7315:22;7068:275;;-1:-1:-1;7068:275:1:o;7348:183::-;7408:4;-1:-1:-1;;;;;7433:6:1;7430:30;7427:56;;;7463:18;;:::i;:::-;-1:-1:-1;7508:1:1;7504:14;7520:4;7500:25;;7348:183::o;7536:668::-;7590:5;7643:3;7636:4;7628:6;7624:17;7620:27;7610:55;;7661:1;7658;7651:12;7610:55;7697:6;7684:20;7723:4;7747:60;7763:43;7803:2;7763:43;:::i;:::-;7747:60;:::i;:::-;7829:3;7853:2;7848:3;7841:15;7881:4;7876:3;7872:14;7865:21;;7938:4;7932:2;7929:1;7925:10;7917:6;7913:23;7909:34;7895:48;;7966:3;7958:6;7955:15;7952:35;;;7983:1;7980;7973:12;7952:35;8019:4;8011:6;8007:17;8033:142;8049:6;8044:3;8041:15;8033:142;;;8115:17;;8103:30;;8153:12;;;;8066;;8033:142;;;-1:-1:-1;8193:5:1;7536:668;-1:-1:-1;;;;;;7536:668:1:o;8209:689::-;8329:6;8337;8345;8353;8361;8414:3;8402:9;8393:7;8389:23;8385:33;8382:53;;;8431:1;8428;8421:12;8382:53;8467:9;8454:23;8444:33;;8524:2;8513:9;8509:18;8496:32;8486:42;;8575:2;8564:9;8560:18;8547:32;8537:42;;8629:2;8618:9;8614:18;8601:32;8642:31;8667:5;8642:31;:::i;:::-;8692:5;-1:-1:-1;8748:3:1;8733:19;;8720:33;-1:-1:-1;;;;;8765:30:1;;8762:50;;;8808:1;8805;8798:12;8762:50;8831:61;8884:7;8875:6;8864:9;8860:22;8831:61;:::i;:::-;8821:71;;;8209:689;;;;;;;;:::o;9143:118::-;9229:5;9222:13;9215:21;9208:5;9205:32;9195:60;;9251:1;9248;9241:12;9266:241;9322:6;9375:2;9363:9;9354:7;9350:23;9346:32;9343:52;;;9391:1;9388;9381:12;9343:52;9430:9;9417:23;9449:28;9471:5;9449:28;:::i;9512:632::-;9683:2;9735:21;;;9805:13;;9708:18;;;9827:22;;;9654:4;;9683:2;9906:15;;;;9880:2;9865:18;;;9654:4;9949:169;9963:6;9960:1;9957:13;9949:169;;;10024:13;;10012:26;;10093:15;;;;10058:12;;;;9985:1;9978:9;9949:169;;10149:407;10214:5;-1:-1:-1;;;;;10240:6:1;10237:30;10234:56;;;10270:18;;:::i;:::-;10308:57;10353:2;10332:15;;-1:-1:-1;;10328:29:1;10359:4;10324:40;10308:57;:::i;:::-;10299:66;;10388:6;10381:5;10374:21;10428:3;10419:6;10414:3;10410:16;10407:25;10404:45;;;10445:1;10442;10435:12;10404:45;10494:6;10489:3;10482:4;10475:5;10471:16;10458:43;10548:1;10541:4;10532:6;10525:5;10521:18;10517:29;10510:40;10149:407;;;;;:::o;10561:451::-;10630:6;10683:2;10671:9;10662:7;10658:23;10654:32;10651:52;;;10699:1;10696;10689:12;10651:52;10739:9;10726:23;-1:-1:-1;;;;;10764:6:1;10761:30;10758:50;;;10804:1;10801;10794:12;10758:50;10827:22;;10880:4;10872:13;;10868:27;-1:-1:-1;10858:55:1;;10909:1;10906;10899:12;10858:55;10932:74;10998:7;10993:2;10980:16;10975:2;10971;10967:11;10932:74;:::i;11017:347::-;11068:8;11078:6;11132:3;11125:4;11117:6;11113:17;11109:27;11099:55;;11150:1;11147;11140:12;11099:55;-1:-1:-1;11173:20:1;;-1:-1:-1;;;;;11205:30:1;;11202:50;;;11248:1;11245;11238:12;11202:50;11285:4;11277:6;11273:17;11261:29;;11337:3;11330:4;11321:6;11313;11309:19;11305:30;11302:39;11299:59;;;11354:1;11351;11344:12;11369:477;11448:6;11456;11464;11517:2;11505:9;11496:7;11492:23;11488:32;11485:52;;;11533:1;11530;11523:12;11485:52;11573:9;11560:23;-1:-1:-1;;;;;11598:6:1;11595:30;11592:50;;;11638:1;11635;11628:12;11592:50;11677:58;11727:7;11718:6;11707:9;11703:22;11677:58;:::i;:::-;11754:8;;11651:84;;-1:-1:-1;11836:2:1;11821:18;;;;11808:32;;11369:477;-1:-1:-1;;;;11369:477:1:o;12104:309::-;12169:6;12177;12230:2;12218:9;12209:7;12205:23;12201:32;12198:52;;;12246:1;12243;12236:12;12198:52;12282:9;12269:23;12259:33;;12342:2;12331:9;12327:18;12314:32;12355:28;12377:5;12355:28;:::i;12418:383::-;12495:6;12503;12511;12564:2;12552:9;12543:7;12539:23;12535:32;12532:52;;;12580:1;12577;12570:12;12532:52;12616:9;12603:23;12593:33;;12676:2;12665:9;12661:18;12648:32;12689:31;12714:5;12689:31;:::i;12806:1350::-;12942:6;12950;12958;12966;13019:3;13007:9;12998:7;12994:23;12990:33;12987:53;;;13036:1;13033;13026:12;12987:53;13072:9;13059:23;13049:33;;13101:2;13150;13139:9;13135:18;13122:32;13112:42;;13205:2;13194:9;13190:18;13177:32;-1:-1:-1;;;;;13269:2:1;13261:6;13258:14;13255:34;;;13285:1;13282;13275:12;13255:34;13323:6;13312:9;13308:22;13298:32;;13368:7;13361:4;13357:2;13353:13;13349:27;13339:55;;13390:1;13387;13380:12;13339:55;13426:2;13413:16;13449:60;13465:43;13505:2;13465:43;:::i;13449:60::-;13543:15;;;13625:1;13621:10;;;;13613:19;;13609:28;;;13574:12;;;;13649:19;;;13646:39;;;13681:1;13678;13671:12;13646:39;13705:11;;;;13725:217;13741:6;13736:3;13733:15;13725:217;;;13821:3;13808:17;13838:31;13863:5;13838:31;:::i;:::-;13882:18;;13758:12;;;;13920;;;;13725:217;;;13961:5;-1:-1:-1;;;14019:2:1;14004:18;;13991:32;;-1:-1:-1;14035:16:1;;;14032:36;;;14064:1;14061;14054:12;14032:36;;;14087:63;14142:7;14131:8;14120:9;14116:24;14087:63;:::i;:::-;14077:73;;;12806:1350;;;;;;;:::o;14412:382::-;14477:6;14485;14538:2;14526:9;14517:7;14513:23;14509:32;14506:52;;;14554:1;14551;14544:12;14506:52;14593:9;14580:23;14612:31;14637:5;14612:31;:::i;:::-;14662:5;-1:-1:-1;14719:2:1;14704:18;;14691:32;14732:30;14691:32;14732:30;:::i;15048:795::-;15143:6;15151;15159;15167;15220:3;15208:9;15199:7;15195:23;15191:33;15188:53;;;15237:1;15234;15227:12;15188:53;15276:9;15263:23;15295:31;15320:5;15295:31;:::i;:::-;15345:5;-1:-1:-1;15402:2:1;15387:18;;15374:32;15415:33;15374:32;15415:33;:::i;:::-;15467:7;-1:-1:-1;15521:2:1;15506:18;;15493:32;;-1:-1:-1;15576:2:1;15561:18;;15548:32;-1:-1:-1;;;;;15592:30:1;;15589:50;;;15635:1;15632;15625:12;15589:50;15658:22;;15711:4;15703:13;;15699:27;-1:-1:-1;15689:55:1;;15740:1;15737;15730:12;15689:55;15763:74;15829:7;15824:2;15811:16;15806:2;15802;15798:11;15763:74;:::i;15848:452::-;15934:6;15942;15950;15958;16011:3;15999:9;15990:7;15986:23;15982:33;15979:53;;;16028:1;16025;16018:12;15979:53;16064:9;16051:23;16041:33;;16121:2;16110:9;16106:18;16093:32;16083:42;;16175:2;16164:9;16160:18;16147:32;16188:31;16213:5;16188:31;:::i;:::-;15848:452;;;;-1:-1:-1;16238:5:1;;16290:2;16275:18;16262:32;;-1:-1:-1;;15848:452:1:o;16305:551::-;16407:6;16415;16423;16476:2;16464:9;16455:7;16451:23;16447:32;16444:52;;;16492:1;16489;16482:12;16444:52;16531:9;16518:23;16550:31;16575:5;16550:31;:::i;:::-;16600:5;-1:-1:-1;16652:2:1;16637:18;;16624:32;;-1:-1:-1;16707:2:1;16692:18;;16679:32;-1:-1:-1;;;;;16723:30:1;;16720:50;;;16766:1;16763;16756:12;16720:50;16789:61;16842:7;16833:6;16822:9;16818:22;16789:61;:::i;:::-;16779:71;;;16305:551;;;;;:::o;16861:409::-;16931:6;16939;16992:2;16980:9;16971:7;16967:23;16963:32;16960:52;;;17008:1;17005;16998:12;16960:52;17048:9;17035:23;-1:-1:-1;;;;;17073:6:1;17070:30;17067:50;;;17113:1;17110;17103:12;17067:50;17152:58;17202:7;17193:6;17182:9;17178:22;17152:58;:::i;:::-;17229:8;;17126:84;;-1:-1:-1;16861:409:1;-1:-1:-1;;;;16861:409:1:o;17275:388::-;17343:6;17351;17404:2;17392:9;17383:7;17379:23;17375:32;17372:52;;;17420:1;17417;17410:12;17372:52;17459:9;17446:23;17478:31;17503:5;17478:31;:::i;:::-;17528:5;-1:-1:-1;17585:2:1;17570:18;;17557:32;17598:33;17557:32;17598:33;:::i;17668:380::-;17747:1;17743:12;;;;17790;;;17811:61;;17865:4;17857:6;17853:17;17843:27;;17811:61;17918:2;17910:6;17907:14;17887:18;17884:38;17881:161;;17964:10;17959:3;17955:20;17952:1;17945:31;17999:4;17996:1;17989:15;18027:4;18024:1;18017:15;18469:304;-1:-1:-1;;;;;18699:15:1;;;18681:34;;18751:15;;18746:2;18731:18;;18724:43;18631:2;18616:18;;18469:304::o;18778:245::-;18845:6;18898:2;18886:9;18877:7;18873:23;18869:32;18866:52;;;18914:1;18911;18904:12;18866:52;18946:9;18940:16;18965:28;18987:5;18965:28;:::i;19028:184::-;19098:6;19151:2;19139:9;19130:7;19126:23;19122:32;19119:52;;;19167:1;19164;19157:12;19119:52;-1:-1:-1;19190:16:1;;19028:184;-1:-1:-1;19028:184:1:o;19626:127::-;19687:10;19682:3;19678:20;19675:1;19668:31;19718:4;19715:1;19708:15;19742:4;19739:1;19732:15;19758:128;19825:9;;;19846:11;;;19843:37;;;19860:18;;:::i;19891:125::-;19956:9;;;19977:10;;;19974:36;;;19990:18;;:::i;21132:168::-;21205:9;;;21236;;21253:15;;;21247:22;;21233:37;21223:71;;21274:18;;:::i;21305:348::-;21507:2;21489:21;;;21546:2;21526:18;;;21519:30;-1:-1:-1;;;21580:2:1;21565:18;;21558:54;21644:2;21629:18;;21305:348::o;21658:336::-;21860:2;21842:21;;;21899:2;21879:18;;;21872:30;-1:-1:-1;;;21933:2:1;21918:18;;21911:42;21985:2;21970:18;;21658:336::o;21999:339::-;22201:2;22183:21;;;22240:2;22220:18;;;22213:30;-1:-1:-1;;;22274:2:1;22259:18;;22252:45;22329:2;22314:18;;21999:339::o;22343:251::-;22413:6;22466:2;22454:9;22445:7;22441:23;22437:32;22434:52;;;22482:1;22479;22472:12;22434:52;22514:9;22508:16;22533:31;22558:5;22533:31;:::i;22599:127::-;22660:10;22655:3;22651:20;22648:1;22641:31;22691:4;22688:1;22681:15;22715:4;22712:1;22705:15;22731:135;22770:3;22791:17;;;22788:43;;22811:18;;:::i;:::-;-1:-1:-1;22858:1:1;22847:13;;22731:135::o;23003:217::-;23043:1;23069;23059:132;;23113:10;23108:3;23104:20;23101:1;23094:31;23148:4;23145:1;23138:15;23176:4;23173:1;23166:15;23059:132;-1:-1:-1;23205:9:1;;23003:217::o;26069:518::-;26171:2;26166:3;26163:11;26160:421;;;26207:5;26204:1;26197:16;26251:4;26248:1;26238:18;26321:2;26309:10;26305:19;26302:1;26298:27;26292:4;26288:38;26357:4;26345:10;26342:20;26339:47;;;-1:-1:-1;26380:4:1;26339:47;26435:2;26430:3;26426:12;26423:1;26419:20;26413:4;26409:31;26399:41;;26490:81;26508:2;26501:5;26498:13;26490:81;;;26567:1;26553:16;;26534:1;26523:13;26490:81;;26763:1345;26889:3;26883:10;-1:-1:-1;;;;;26908:6:1;26905:30;26902:56;;;26938:18;;:::i;:::-;26967:97;27057:6;27017:38;27049:4;27043:11;27017:38;:::i;:::-;27011:4;26967:97;:::i;:::-;27119:4;;27176:2;27165:14;;27193:1;27188:663;;;;27895:1;27912:6;27909:89;;;-1:-1:-1;27964:19:1;;;27958:26;27909:89;-1:-1:-1;;26720:1:1;26716:11;;;26712:24;26708:29;26698:40;26744:1;26740:11;;;26695:57;28011:81;;27158:944;;27188:663;26016:1;26009:14;;;26053:4;26040:18;;-1:-1:-1;;27224:20:1;;;27342:236;27356:7;27353:1;27350:14;27342:236;;;27445:19;;;27439:26;27424:42;;27537:27;;;;27505:1;27493:14;;;;27372:19;;27342:236;;;27346:3;27606:6;27597:7;27594:19;27591:201;;;27667:19;;;27661:26;-1:-1:-1;;27750:1:1;27746:14;;;27762:3;27742:24;27738:37;27734:42;27719:58;27704:74;;27591:201;-1:-1:-1;;;;;27838:1:1;27822:14;;;27818:22;27805:36;;-1:-1:-1;26763:1345:1:o;28938:200::-;29004:9;;;28977:4;29032:9;;29060:10;;29072:12;;;29056:29;29095:12;;;29087:21;;29053:56;29050:82;;;29112:18;;:::i;29503:723::-;29553:3;29594:5;29588:12;29623:36;29649:9;29623:36;:::i;:::-;29678:1;29695:17;;;29721:133;;;;29868:1;29863:357;;;;29688:532;;29721:133;-1:-1:-1;;29754:24:1;;29742:37;;29827:14;;29820:22;29808:35;;29799:45;;;-1:-1:-1;29721:133:1;;29863:357;29894:5;29891:1;29884:16;29923:4;29968;29965:1;29955:18;29995:1;30009:165;30023:6;30020:1;30017:13;30009:165;;;30101:14;;30088:11;;;30081:35;30144:16;;;;30038:10;;30009:165;;;30013:3;;;30203:6;30198:3;30194:16;30187:23;;29688:532;;;;;29503:723;;;;:::o;30231:576::-;30455:3;30493:6;30487:13;30509:66;30568:6;30563:3;30556:4;30548:6;30544:17;30509:66;:::i;:::-;30638:13;;30597:16;;;;30660:70;30638:13;30597:16;30707:4;30695:17;;30660:70;:::i;:::-;30746:55;30791:8;30784:5;30780:20;30772:6;30746:55;:::i;:::-;30739:62;30231:576;-1:-1:-1;;;;;;;30231:576:1:o;30812:469::-;31033:3;31061:38;31095:3;31087:6;31061:38;:::i;:::-;31128:6;31122:13;31144:65;31202:6;31198:2;31191:4;31183:6;31179:17;31144:65;:::i;31286:147::-;31324:3;-1:-1:-1;;;;;31345:30:1;;31342:56;;31378:18;;:::i;31438:216::-;31502:9;;;31530:11;;;31477:3;31560:9;;31588:10;;31584:19;;31613:10;;31605:19;;31581:44;31578:70;;;31628:18;;:::i;:::-;31578:70;;31438:216;;;;:::o;32544:611::-;-1:-1:-1;;;32902:3:1;32895:23;32877:3;32947:6;32941:13;32963:74;33030:6;33026:1;33021:3;33017:11;33010:4;33002:6;32998:17;32963:74;:::i;:::-;-1:-1:-1;;;33096:1:1;33056:16;;;;33088:10;;;33081:41;-1:-1:-1;33146:2:1;33138:11;;32544:611;-1:-1:-1;32544:611:1:o;34285:416::-;34487:2;34469:21;;;34526:2;34506:18;;;34499:30;34565:34;34560:2;34545:18;;34538:62;-1:-1:-1;;;34631:2:1;34616:18;;34609:50;34691:3;34676:19;;34285:416::o;35067:624::-;-1:-1:-1;;;35425:3:1;35418:23;35400:3;35470:6;35464:13;35486:74;35553:6;35549:1;35544:3;35540:11;35533:4;35525:6;35521:17;35486:74;:::i;:::-;35623:34;35619:1;35579:16;;;;35611:10;;;35604:54;-1:-1:-1;35682:2:1;35674:11;;35067:624;-1:-1:-1;35067:624:1:o;35696:427::-;35956:1;35951:3;35944:14;35926:3;35987:6;35981:13;36003:74;36070:6;36066:1;36061:3;36057:11;36050:4;36042:6;36038:17;36003:74;:::i;:::-;36097:16;;;;36115:1;36093:24;;35696:427;-1:-1:-1;;35696:427:1:o;36955:1049::-;-1:-1:-1;;;37455:78:1;;37556:13;;37437:3;;37578:75;37556:13;37641:2;37632:12;;37625:4;37613:17;;37578:75;:::i;:::-;-1:-1:-1;;;37712:2:1;37672:16;;;37704:11;;;37697:71;37793:13;;37815:76;37793:13;37877:2;37869:11;;37862:4;37850:17;;37815:76;:::i;:::-;-1:-1:-1;;;37951:2:1;37910:17;;;;37943:11;;;37936:35;37995:2;37987:11;;36955:1049;-1:-1:-1;;;;36955:1049:1:o;38009:461::-;38271:31;38266:3;38259:44;38241:3;38332:6;38326:13;38348:75;38416:6;38411:2;38406:3;38402:12;38395:4;38387:6;38383:17;38348:75;:::i;:::-;38443:16;;;;38461:2;38439:25;;38009:461;-1:-1:-1;;38009:461:1:o;38475:136::-;38514:3;38542:5;38532:39;;38551:18;;:::i;:::-;-1:-1:-1;;;38587:18:1;;38475:136::o;40224:417::-;40426:2;40408:21;;;40465:2;40445:18;;;40438:30;40504:34;40499:2;40484:18;;40477:62;-1:-1:-1;;;40570:2:1;40555:18;;40548:51;40631:3;40616:19;;40224:417::o;42244:691::-;-1:-1:-1;;;42619:16:1;;42690:3;42668:16;;;-1:-1:-1;;;;;;42664:43:1;42660:1;42651:11;;42644:64;-1:-1:-1;;;42733:1:1;42724:11;;42717:51;42791:13;;-1:-1:-1;;42813:75:1;42791:13;42876:2;42867:12;;42860:4;42848:17;;42813:75;:::i;:::-;42908:16;;;;42926:2;42904:25;;42244:691;-1:-1:-1;;;42244:691:1:o;44431:489::-;-1:-1:-1;;;;;44700:15:1;;;44682:34;;44752:15;;44747:2;44732:18;;44725:43;44799:2;44784:18;;44777:34;;;44847:3;44842:2;44827:18;;44820:31;;;44625:4;;44868:46;;44894:19;;44886:6;44868:46;:::i;:::-;44860:54;44431:489;-1:-1:-1;;;;;;44431:489:1:o;44925:249::-;44994:6;45047:2;45035:9;45026:7;45022:23;45018:32;45015:52;;;45063:1;45060;45053:12;45015:52;45095:9;45089:16;45114:30;45138:5;45114:30;:::i;45600:127::-;45661:10;45656:3;45652:20;45649:1;45642:31;45692:4;45689:1;45682:15;45716:4;45713:1;45706:15

Swarm Source

ipfs://d61ca505ea5e5c4944f79381bfdcb3b559f3e7df765702e9c73c9564b1c9adae
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.