ETH Price: $2,360.82 (+0.34%)

Token

Taaalls (TAAALL)
 

Overview

Max Total Supply

104 TAAALL

Holders

60

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
2 TAAALL
0x1b9C0f09441605785f600837bde06B326122C163
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:
Taaalls

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-07-13
*/

/**
 *Submitted for verification at Etherscan.io on 2022-07-11
*/

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

// SPDX-License-Identifier: MIT

//
//      taaalls 
//      taaalls.com
//  
//      no warranty expressed or implied
//      see taaalls.com for important terms of service
//
//
//
//  
//                                              
//                                        WIIIIIIIIIIIIIIIIIIIIIIDE             
//                           WIIIIIIIIIIDE------------WIIIIIIIIIIDE             
//              WIIIIIIIIIIIDE------------------------WIIIIIIIIIIDE             
//              wiiiiiiiiiiide------------------------WIIIIIIIIIIDE             
//  WIIIIIIIIIIDE,,,,,,,,,,,,-------------------------WIIIIIIIIIIDE             
//  ,,,,,,,,,,,,,-------------------------------------WIIIIIIIIIIIIIIIIIIIIIIIDE
//  .........................-------------------------.........................W
//  ,,,,,,,,,,,,,........................-------------.........................I
//  ,,,,,,,,,,,,,........................-------------.........................I
//  ...........................................................................I
//  ...........................................................................D
//  ...........................................................................E
//  wiiiiiiide..................................................................
//  wiiiiiiiiiiiiiiiiiiiiiide......................................wiiiiiiiiiide
//  WIIIIIIIIIIDE,,,,,,,,,,,,,.....................................WIIIIIIIIIIDE
//  ...........................................................................W
//  ...........................................................................I
//  .....................................wiiiiiiiiiiiiiiiiiiiiiiide............I
//  .....................................WIIIIIIIIIIIIIIIIIIIIIIIDE............I
//  ...........................................................................I
//  ...........WIIIIIIIIIIIDE..................................................I
//  .........................WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDE............I
//  .........................WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDE............I
//  ...........................................................................D
//  ...........................................................................E
//  ...........WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDE
//  ...........WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDE
//  ...........WIIIIIIIIIIIIDE 
//  ...........WIIIIIIIIIIIIDE 
//  
//

// File: https://raw.githubusercontent.com/Arachnid/solidity-stringutils/master/src/strings.sol

/*
 * @title String & slice utility library for Solidity contracts.
 * @author Nick Johnson <[email protected]>
 *
 * @dev Functionality in this library is largely implemented using an
 *      abstraction called a 'slice'. A slice represents a part of a string -
 *      anything from the entire string to a single character, or even no
 *      characters at all (a 0-length slice). Since a slice only has to specify
 *      an offset and a length, copying and manipulating slices is a lot less
 *      expensive than copying and manipulating the strings they reference.
 *
 *      To further reduce gas costs, most functions on slice that need to return
 *      a slice modify the original one instead of allocating a new one; for
 *      instance, `s.split(".")` will return the text up to the first '.',
 *      modifying s to only contain the remainder of the string after the '.'.
 *      In situations where you do not want to modify the original slice, you
 *      can make a copy first with `.copy()`, for example:
 *      `s.copy().split(".")`. Try and avoid using this idiom in loops; since
 *      Solidity has no memory management, it will result in allocating many
 *      short-lived slices that are later discarded.
 *
 *      Functions that return two slices come in two versions: a non-allocating
 *      version that takes the second slice as an argument, modifying it in
 *      place, and an allocating version that allocates and returns the second
 *      slice; see `nextRune` for example.
 *
 *      Functions that have to copy string data will return strings rather than
 *      slices; these can be cast back to slices for further processing if
 *      required.
 *
 *      For convenience, some functions are provided with non-modifying
 *      variants that create a new slice and return both; for instance,
 *      `s.splitNew('.')` leaves s unmodified, and returns two values
 *      corresponding to the left and right parts of the string.
 */

pragma solidity ^0.8.0;

library SStrings {
    struct slice {
        uint _len;
        uint _ptr;
    }

    function memcpy(uint dest, uint src, uint len) private pure {
        // Copy word-length chunks while possible
        for(; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = type(uint).max;
        if (len > 0) {
            mask = 256 ** (32 - len) - 1;
        }
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    /*
     * @dev Returns a slice containing the entire string.
     * @param self The string to make a slice from.
     * @return A newly allocated slice containing the entire string.
     */
    function toSlice(string memory self) internal pure returns (slice memory) {
        uint ptr;
        assembly {
            ptr := add(self, 0x20)
        }
        return slice(bytes(self).length, ptr);
    }

    /*
     * @dev Returns the length of a null-terminated bytes32 string.
     * @param self The value to find the length of.
     * @return The length of the string, from 0 to 32.
     */
    function len(bytes32 self) internal pure returns (uint) {
        uint ret;
        if (self == 0)
            return 0;
        if (uint(self) & type(uint128).max == 0) {
            ret += 16;
            self = bytes32(uint(self) / 0x100000000000000000000000000000000);
        }
        if (uint(self) & type(uint64).max == 0) {
            ret += 8;
            self = bytes32(uint(self) / 0x10000000000000000);
        }
        if (uint(self) & type(uint32).max == 0) {
            ret += 4;
            self = bytes32(uint(self) / 0x100000000);
        }
        if (uint(self) & type(uint16).max == 0) {
            ret += 2;
            self = bytes32(uint(self) / 0x10000);
        }
        if (uint(self) & type(uint8).max == 0) {
            ret += 1;
        }
        return 32 - ret;
    }

    /*
     * @dev Returns a slice containing the entire bytes32, interpreted as a
     *      null-terminated utf-8 string.
     * @param self The bytes32 value to convert to a slice.
     * @return A new slice containing the value of the input argument up to the
     *         first null.
     */
    function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {
        // Allocate space for `self` in memory, copy it there, and point ret at it
        assembly {
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, 0x20))
            mstore(ptr, self)
            mstore(add(ret, 0x20), ptr)
        }
        ret._len = len(self);
    }

    /*
     * @dev Returns a new slice containing the same data as the current slice.
     * @param self The slice to copy.
     * @return A new slice containing the same data as `self`.
     */
    function copy(slice memory self) internal pure returns (slice memory) {
        return slice(self._len, self._ptr);
    }

    /*
     * @dev Copies a slice to a new string.
     * @param self The slice to copy.
     * @return A newly allocated string containing the slice's text.
     */
    function toString(slice memory self) internal pure returns (string memory) {
        string memory ret = new string(self._len);
        uint retptr;
        assembly { retptr := add(ret, 32) }

        memcpy(retptr, self._ptr, self._len);
        return ret;
    }

    /*
     * @dev Returns the length in runes of the slice. Note that this operation
     *      takes time proportional to the length of the slice; avoid using it
     *      in loops, and call `slice.empty()` if you only need to know whether
     *      the slice is empty or not.
     * @param self The slice to operate on.
     * @return The length of the slice in runes.
     */
    function len(slice memory self) internal pure returns (uint l) {
        // Starting at ptr-31 means the LSB will be the byte we care about
        uint ptr = self._ptr - 31;
        uint end = ptr + self._len;
        for (l = 0; ptr < end; l++) {
            uint8 b;
            assembly { b := and(mload(ptr), 0xFF) }
            if (b < 0x80) {
                ptr += 1;
            } else if(b < 0xE0) {
                ptr += 2;
            } else if(b < 0xF0) {
                ptr += 3;
            } else if(b < 0xF8) {
                ptr += 4;
            } else if(b < 0xFC) {
                ptr += 5;
            } else {
                ptr += 6;
            }
        }
    }

    /*
     * @dev Returns true if the slice is empty (has a length of 0).
     * @param self The slice to operate on.
     * @return True if the slice is empty, False otherwise.
     */
    function empty(slice memory self) internal pure returns (bool) {
        return self._len == 0;
    }

    /*
     * @dev Returns a positive number if `other` comes lexicographically after
     *      `self`, a negative number if it comes before, or zero if the
     *      contents of the two slices are equal. Comparison is done per-rune,
     *      on unicode codepoints.
     * @param self The first slice to compare.
     * @param other The second slice to compare.
     * @return The result of the comparison.
     */
    function compare(slice memory self, slice memory other) internal pure returns (int) {
        uint shortest = self._len;
        if (other._len < self._len)
            shortest = other._len;

        uint selfptr = self._ptr;
        uint otherptr = other._ptr;
        for (uint idx = 0; idx < shortest; idx += 32) {
            uint a;
            uint b;
            assembly {
                a := mload(selfptr)
                b := mload(otherptr)
            }
            if (a != b) {
                // Mask out irrelevant bytes and check again
                uint mask = type(uint).max; // 0xffff...
                if(shortest < 32) {
                  mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
                }
                unchecked {
                    uint diff = (a & mask) - (b & mask);
                    if (diff != 0)
                        return int(diff);
                }
            }
            selfptr += 32;
            otherptr += 32;
        }
        return int(self._len) - int(other._len);
    }

    /*
     * @dev Returns true if the two slices contain the same text.
     * @param self The first slice to compare.
     * @param self The second slice to compare.
     * @return True if the slices are equal, false otherwise.
     */
    function equals(slice memory self, slice memory other) internal pure returns (bool) {
        return compare(self, other) == 0;
    }

    /*
     * @dev Extracts the first rune in the slice into `rune`, advancing the
     *      slice to point to the next rune and returning `self`.
     * @param self The slice to operate on.
     * @param rune The slice that will contain the first rune.
     * @return `rune`.
     */
    function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) {
        rune._ptr = self._ptr;

        if (self._len == 0) {
            rune._len = 0;
            return rune;
        }

        uint l;
        uint b;
        // Load the first byte of the rune into the LSBs of b
        assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }
        if (b < 0x80) {
            l = 1;
        } else if(b < 0xE0) {
            l = 2;
        } else if(b < 0xF0) {
            l = 3;
        } else {
            l = 4;
        }

        // Check for truncated codepoints
        if (l > self._len) {
            rune._len = self._len;
            self._ptr += self._len;
            self._len = 0;
            return rune;
        }

        self._ptr += l;
        self._len -= l;
        rune._len = l;
        return rune;
    }

    /*
     * @dev Returns the first rune in the slice, advancing the slice to point
     *      to the next rune.
     * @param self The slice to operate on.
     * @return A slice containing only the first rune from `self`.
     */
    function nextRune(slice memory self) internal pure returns (slice memory ret) {
        nextRune(self, ret);
    }

    /*
     * @dev Returns the number of the first codepoint in the slice.
     * @param self The slice to operate on.
     * @return The number of the first codepoint in the slice.
     */
    function ord(slice memory self) internal pure returns (uint ret) {
        if (self._len == 0) {
            return 0;
        }

        uint word;
        uint length;
        uint divisor = 2 ** 248;

        // Load the rune into the MSBs of b
        assembly { word:= mload(mload(add(self, 32))) }
        uint b = word / divisor;
        if (b < 0x80) {
            ret = b;
            length = 1;
        } else if(b < 0xE0) {
            ret = b & 0x1F;
            length = 2;
        } else if(b < 0xF0) {
            ret = b & 0x0F;
            length = 3;
        } else {
            ret = b & 0x07;
            length = 4;
        }

        // Check for truncated codepoints
        if (length > self._len) {
            return 0;
        }

        for (uint i = 1; i < length; i++) {
            divisor = divisor / 256;
            b = (word / divisor) & 0xFF;
            if (b & 0xC0 != 0x80) {
                // Invalid UTF-8 sequence
                return 0;
            }
            ret = (ret * 64) | (b & 0x3F);
        }

        return ret;
    }

    /*
     * @dev Returns the keccak-256 hash of the slice.
     * @param self The slice to hash.
     * @return The hash of the slice.
     */
    function keccak(slice memory self) internal pure returns (bytes32 ret) {
        assembly {
            ret := keccak256(mload(add(self, 32)), mload(self))
        }
    }

    /*
     * @dev Returns true if `self` starts with `needle`.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return True if the slice starts with the provided text, false otherwise.
     */
    function startsWith(slice memory self, slice memory needle) internal pure returns (bool) {
        if (self._len < needle._len) {
            return false;
        }

        if (self._ptr == needle._ptr) {
            return true;
        }

        bool equal;
        assembly {
            let length := mload(needle)
            let selfptr := mload(add(self, 0x20))
            let needleptr := mload(add(needle, 0x20))
            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
        }
        return equal;
    }

    /*
     * @dev If `self` starts with `needle`, `needle` is removed from the
     *      beginning of `self`. Otherwise, `self` is unmodified.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return `self`
     */
    function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {
        if (self._len < needle._len) {
            return self;
        }

        bool equal = true;
        if (self._ptr != needle._ptr) {
            assembly {
                let length := mload(needle)
                let selfptr := mload(add(self, 0x20))
                let needleptr := mload(add(needle, 0x20))
                equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
            }
        }

        if (equal) {
            self._len -= needle._len;
            self._ptr += needle._len;
        }

        return self;
    }

    /*
     * @dev Returns true if the slice ends with `needle`.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return True if the slice starts with the provided text, false otherwise.
     */
    function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {
        if (self._len < needle._len) {
            return false;
        }

        uint selfptr = self._ptr + self._len - needle._len;

        if (selfptr == needle._ptr) {
            return true;
        }

        bool equal;
        assembly {
            let length := mload(needle)
            let needleptr := mload(add(needle, 0x20))
            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
        }

        return equal;
    }

    /*
     * @dev If `self` ends with `needle`, `needle` is removed from the
     *      end of `self`. Otherwise, `self` is unmodified.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return `self`
     */
    function until(slice memory self, slice memory needle) internal pure returns (slice memory) {
        if (self._len < needle._len) {
            return self;
        }

        uint selfptr = self._ptr + self._len - needle._len;
        bool equal = true;
        if (selfptr != needle._ptr) {
            assembly {
                let length := mload(needle)
                let needleptr := mload(add(needle, 0x20))
                equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
            }
        }

        if (equal) {
            self._len -= needle._len;
        }

        return self;
    }

    // Returns the memory address of the first byte of the first occurrence of
    // `needle` in `self`, or the first byte after `self` if not found.
    function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
        uint ptr = selfptr;
        uint idx;

        if (needlelen <= selflen) {
            if (needlelen <= 32) {
                bytes32 mask;
                if (needlelen > 0) {
                    mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
                }

                bytes32 needledata;
                assembly { needledata := and(mload(needleptr), mask) }

                uint end = selfptr + selflen - needlelen;
                bytes32 ptrdata;
                assembly { ptrdata := and(mload(ptr), mask) }

                while (ptrdata != needledata) {
                    if (ptr >= end)
                        return selfptr + selflen;
                    ptr++;
                    assembly { ptrdata := and(mload(ptr), mask) }
                }
                return ptr;
            } else {
                // For long needles, use hashing
                bytes32 hash;
                assembly { hash := keccak256(needleptr, needlelen) }

                for (idx = 0; idx <= selflen - needlelen; idx++) {
                    bytes32 testHash;
                    assembly { testHash := keccak256(ptr, needlelen) }
                    if (hash == testHash)
                        return ptr;
                    ptr += 1;
                }
            }
        }
        return selfptr + selflen;
    }

    // Returns the memory address of the first byte after the last occurrence of
    // `needle` in `self`, or the address of `self` if not found.
    function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
        uint ptr;

        if (needlelen <= selflen) {
            if (needlelen <= 32) {
                bytes32 mask;
                if (needlelen > 0) {
                    mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
                }

                bytes32 needledata;
                assembly { needledata := and(mload(needleptr), mask) }

                ptr = selfptr + selflen - needlelen;
                bytes32 ptrdata;
                assembly { ptrdata := and(mload(ptr), mask) }

                while (ptrdata != needledata) {
                    if (ptr <= selfptr)
                        return selfptr;
                    ptr--;
                    assembly { ptrdata := and(mload(ptr), mask) }
                }
                return ptr + needlelen;
            } else {
                // For long needles, use hashing
                bytes32 hash;
                assembly { hash := keccak256(needleptr, needlelen) }
                ptr = selfptr + (selflen - needlelen);
                while (ptr >= selfptr) {
                    bytes32 testHash;
                    assembly { testHash := keccak256(ptr, needlelen) }
                    if (hash == testHash)
                        return ptr + needlelen;
                    ptr -= 1;
                }
            }
        }
        return selfptr;
    }

    /*
     * @dev Modifies `self` to contain everything from the first occurrence of
     *      `needle` to the end of the slice. `self` is set to the empty slice
     *      if `needle` is not found.
     * @param self The slice to search and modify.
     * @param needle The text to search for.
     * @return `self`.
     */
    function find(slice memory self, slice memory needle) internal pure returns (slice memory) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
        self._len -= ptr - self._ptr;
        self._ptr = ptr;
        return self;
    }

    /*
     * @dev Modifies `self` to contain the part of the string from the start of
     *      `self` to the end of the first occurrence of `needle`. If `needle`
     *      is not found, `self` is set to the empty slice.
     * @param self The slice to search and modify.
     * @param needle The text to search for.
     * @return `self`.
     */
    function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) {
        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
        self._len = ptr - self._ptr;
        return self;
    }

    /*
     * @dev Splits the slice, setting `self` to everything after the first
     *      occurrence of `needle`, and `token` to everything before it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and `token` is set to the entirety of `self`.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @param token An output parameter to which the first token is written.
     * @return `token`.
     */
    function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
        token._ptr = self._ptr;
        token._len = ptr - self._ptr;
        if (ptr == self._ptr + self._len) {
            // Not found
            self._len = 0;
        } else {
            self._len -= token._len + needle._len;
            self._ptr = ptr + needle._len;
        }
        return token;
    }

    /*
     * @dev Splits the slice, setting `self` to everything after the first
     *      occurrence of `needle`, and returning everything before it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and the entirety of `self` is returned.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @return The part of `self` up to the first occurrence of `delim`.
     */
    function split(slice memory self, slice memory needle) internal pure returns (slice memory token) {
        split(self, needle, token);
    }

    /*
     * @dev Splits the slice, setting `self` to everything before the last
     *      occurrence of `needle`, and `token` to everything after it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and `token` is set to the entirety of `self`.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @param token An output parameter to which the first token is written.
     * @return `token`.
     */
    function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {
        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
        token._ptr = ptr;
        token._len = self._len - (ptr - self._ptr);
        if (ptr == self._ptr) {
            // Not found
            self._len = 0;
        } else {
            self._len -= token._len + needle._len;
        }
        return token;
    }

    /*
     * @dev Splits the slice, setting `self` to everything before the last
     *      occurrence of `needle`, and returning everything after it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and the entirety of `self` is returned.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @return The part of `self` after the last occurrence of `delim`.
     */
    function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) {
        rsplit(self, needle, token);
    }

    /*
     * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.
     * @param self The slice to search.
     * @param needle The text to search for in `self`.
     * @return The number of occurrences of `needle` found in `self`.
     */
    function count(slice memory self, slice memory needle) internal pure returns (uint cnt) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;
        while (ptr <= self._ptr + self._len) {
            cnt++;
            ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;
        }
    }

    /*
     * @dev Returns True if `self` contains `needle`.
     * @param self The slice to search.
     * @param needle The text to search for in `self`.
     * @return True if `needle` is found in `self`, false otherwise.
     */
    function contains(slice memory self, slice memory needle) internal pure returns (bool) {
        return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;
    }

    /*
     * @dev Returns a newly allocated string containing the concatenation of
     *      `self` and `other`.
     * @param self The first slice to concatenate.
     * @param other The second slice to concatenate.
     * @return The concatenation of the two strings.
     */
    function concat(slice memory self, slice memory other) internal pure returns (string memory) {
        string memory ret = new string(self._len + other._len);
        uint retptr;
        assembly { retptr := add(ret, 32) }
        memcpy(retptr, self._ptr, self._len);
        memcpy(retptr + self._len, other._ptr, other._len);
        return ret;
    }

    /*
     * @dev Joins an array of slices, using `self` as a delimiter, returning a
     *      newly allocated string.
     * @param self The delimiter to use.
     * @param parts A list of slices to join.
     * @return A newly allocated string containing all the slices in `parts`,
     *         joined with `self`.
     */
    function join(slice memory self, slice[] memory parts) internal pure returns (string memory) {
        if (parts.length == 0)
            return "";

        uint length = self._len * (parts.length - 1);
        for(uint i = 0; i < parts.length; i++)
            length += parts[i]._len;

        string memory ret = new string(length);
        uint retptr;
        assembly { retptr := add(ret, 32) }

        for(uint i = 0; i < parts.length; i++) {
            memcpy(retptr, parts[i]._ptr, parts[i]._len);
            retptr += parts[i]._len;
            if (i < parts.length - 1) {
                memcpy(retptr, self._ptr, self._len);
                retptr += self._len;
            }
        }

        return ret;
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


// OpenZeppelin Contracts v4.4.1 (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() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

    /**
     * @dev 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/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: @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: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.7.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 functionCall(target, data, "Address: low-level call failed");
    }

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

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

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

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

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

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

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

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

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

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

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

// 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: @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/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/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.7.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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// 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/token/ERC721/ERC721.sol


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

        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 overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

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

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

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _burn(tokenId);
    }
}

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


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

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: Taaalles.sol



//
//      Taaalls
//      
//      @taaallsnft
//      taaalls.com
//  
//      no warranty expressed or implied
//      see taaalls.com for important terms of service
//
//    TTTTTT  AAA   AAA   AAA  LL    LL     SSSS
//      TT   AA AA AA AA AA AA LL    LL    SS
//      TT   AAAAA AAAAA AAAAA LL    LL     SSSS
//      TT   AA AA AA AA AA AA LL    LL        SS
//      TT   AA AA AA AA AA AA LLLLL LLLLL SSSSS
//                                                                                
//              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                          
//              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                          
//         /@@@@%%%%#########################@@@@                      
//         /@@@@%%%%#########################@@@@                      
//     ////%@@@@&&&&#########################@@@@////,                 
//     @@@@@%%%%#################################@@@@(                 
//     @@@@@%%%%#################################@@@@(                 
//     @@@@&############@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
//     @@@@&############@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             
//     @@@@&########@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@         
//     @@@@&########@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@         
//     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         
//     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         
//     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         
//     @@@@@&&&&(((((((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&(((((((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&((((########(((((((((((((########@@@@(                 
//     @@@@@&&&&((((########(((((((((((((########@@@@(                 
// @@@@&&&&&&&&&((((@@@@////(((((((((((((@@@@////@@@@(                 
// @@@@&&&&&&&&&((((@@@@////(((((((((((((@@@@////@@@@(                 
// @@@@&&&&&&&&&((((&&&&////(((((((((((((&&&&////@@@@(                 
// @@@@&&&&&&&&&(((((((((((((((((((((((((((((((((@@@@(                 
// @@@@&&&&&&&&&(((((((((((((((((((((((((((((((((@@@@(                 
// @@@@@@@@@&&&&(((((((((((((((((((((((((((((((((@@@@(                 
// @@@@@@@@@&&&&(((((((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&&&&&((((((((@@@@%((((@@@@((((((((@@@@(                 
//     @@@@@&&&&&&&&((((((((@@@@%((((@@@@((((((((@@@@(                 
//     @@@@@&&&&&&&&&&&&(((((((((((((((((((((&&&&@@@@(                 
//     @@@@@&&&&&&&&&&&&(((((((((((((((((((((&&&&@@@@(                 
//     @@@@@&&&&&&&&%%%%(((((((((((((((((((((%%%%@@@@(                 
//     @@@@@&&&&&&&&(((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&&&&&(((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&@@@@((((@@@@@@@@@@@@@@@@@@@@@((((@@@@(                 
//     @@@@@&&&&@@@@((((@@@@@@@@@@@@@@@@@@@@@((((@@@@(                 
//     @@@@@&&&&@@@@(((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&@@@@(((((((((((((((((((((((((((((@@@@(                 
//     @@@@@&&&&&&&&@@@@(((((((((((((((((((((@@@@....                  
//     @@@@@&&&&&&&&@@@@(((((((((((((((((((((@@@@                      
//     @@@@@&&&&&&&&@@@@#####################&&&&                      
//     @@@@@&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@                          
//     @@@@@&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@                          
//     @@@@@&&&&&&&&&&&&@@@@                                           
//     @@@@@&&&&&&&&&&&&@@@@                                           
//     @@@@@&&&&&&&&&&&&@@@@                                           
//     @@@@@&&&&&&&&&&&&@@@@                                           
//  
//
pragma solidity ^0.8.12;
pragma abicoder v2;








abstract contract CryptoPunksMarket {
    mapping (uint => address) public punkIndexToAddress;
}

abstract contract CryptoPunksData{
    function punkAttributes(uint16 index) external view returns (string memory text) {}
    function punkImageSvg(uint16 index) external view returns (string memory svg) {}
}

abstract contract BrainWorms {
    function uMad(uint256 idx) external pure returns (string memory madResult) {}
    function bigMad(uint256 idx) external pure returns (string memory bigMadResult) {}
}

abstract contract Lockout is ERC721 {}
abstract contract UsrMessage is ERC721 {}
abstract contract IdeasOfMountains is ERC721 {}
abstract contract Neophyte is ERC721 {}

contract Taaalls is
    ERC721Enumerable,
    ERC721Burnable,
    ReentrancyGuard,
    Ownable
{
    using Strings for uint256;
    using SStrings for *;                                                       

    constructor() ERC721 ("Taaalls", "TAAALL") {}

    // Crypto punks
    CryptoPunksMarket cryptoPunks;
    CryptoPunksData cryptoPunksData;


    // Got Brainworms?
    BrainWorms brainWorms;

    // Currency
    uint256 public MINT_PRICE_FIVE = 0.345 ether; // 0.069 each
    uint256 public MINT_PRICE_SIXNINE = 4.20 ether; // 0.06086957 each
    address payable public withdrawalAddress;

    // Minting states
    bool public mintActive = false;
    bool public claimActive = false;

    uint256 public constant maxSupply = 6900;
    mapping(uint256 => uint256) private tokenOrder;
    uint256 tokenOrderRange = 0;
    uint256 nextMintIdx = 0;

    // Token features
    uint256 maxWidth = 6000;
    mapping(uint256 => uint256) public tokenHeight;
    mapping(uint256 => bool) public uMad;
    bool public bigMad;
    bytes desc;

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "The caller is another contract");
        _;
    }
    // Because people can claim ID's with their punk 
    // ahead of the mint sequence,
    // I need to find the next available unclaimed token.
    // I don't expect thousands of people to claim out of sequence,
    // otherwise I would rewrite this to be more gas efficient
    function _mint() internal {
        uint256 tokenToMint;
        while(true){
            // pseudo random mint pattern by sampling from a list of random non-repeating integers
            unchecked{
                tokenToMint = tokenOrder[nextMintIdx%tokenOrderRange] + (nextMintIdx/tokenOrderRange) * tokenOrderRange;
            }
            if(tokenHeight[tokenToMint] == 0 ){
                tokenHeight[tokenToMint] = randHeight(tokenToMint);
                _safeMint(msg.sender, tokenToMint);
                unchecked{
                    nextMintIdx++;
                }
                break;
            } 
            unchecked{
                nextMintIdx++;
            }
        }

    }

    // mint the next available token 
    function mintOne() public nonReentrant callerIsUser {
        require(
            mintActive, 
            "mint not active"
        );
        require(
            balanceOf(msg.sender) + 1 <= 2,
            "limit 2 free mints"
        );
        require(
            totalSupply() + 1 <= maxSupply,
            "Request to mint tokens exceeds supply"
        );
        _mint();
    }

    // mint five
    function mintFive() external payable nonReentrant callerIsUser {
        require(
            balanceOf(msg.sender) + 5 <= 12,
            "you own too many"
        );
        require(
            msg.value >= MINT_PRICE_FIVE,
            "Eth sent too low"
        );
        require(
            mintActive, 
            "mint not active"
        );
        require(
            totalSupply() + 5 <= maxSupply,
            "Request to mint tokens exceeds supply"
        );
        uint256 i;
        while (i < 5) {
            _mint();
            unchecked{
                i++;
            }
        }
    }

    // mint 69
    function mintSixtyNine() external payable nonReentrant callerIsUser {
        require(
            balanceOf(msg.sender) + 69 <= 75,
            "you own too many"
        );
        require(
            msg.value >= MINT_PRICE_SIXNINE,
            "Eth sent too low"
        );
        require(
            mintActive, 
            "mint not active"
        );
        require(
            totalSupply() + 69 <= maxSupply,
            "Request to mint tokens exceeds supply"
        );
        uint256 i;
        while (i < 69) {
            _mint();
            unchecked{
                i++;
            }
        }
    }
   
    // reset the stretch if you're the wiiide holder
    // most people wont bother doing this and the whole collection will trend to oblivion
    // but maybe its nice to give some people a little control 
    function tokenOwnerResetStretch(uint256 id) external {
        require(
            ownerOf(id) == msg.sender,
            "not your taaall"
            );
        tokenHeight[id] = randHeight(id);
    }
    
    // break the trait up from 'Mohawk' into 'M' 'Hawk', and jam some extra o's in there
    function splitTraitHalf(SStrings.slice memory secondHalf,string memory delim) internal pure returns(string memory result){
        if(secondHalf.endsWith(delim.toSlice())){
            secondHalf = string.concat(secondHalf.toString(), delim,delim).toSlice();
        }
        SStrings.slice memory firstHalf = secondHalf.split(delim.toSlice());
        if(secondHalf.len()>0){
            result = string.concat(firstHalf.toString(),delim,delim,delim,secondHalf.toString());
        } else {
            result = "";
        }
        
    }

    // attempt to replace letters in the trait we're going to repeat
    function splitTrait(string memory stringToSplit) internal pure returns(string memory result){

        result = splitTraitHalf(stringToSplit.toSlice(),"o");

        if(bytes(result).length==0){
            result = splitTraitHalf(stringToSplit.toSlice(),"a");
        }
        if(bytes(result).length==0){
            result = splitTraitHalf(stringToSplit.toSlice(),"e");
        }
        if(bytes(result).length==0){
            result = string.concat(stringToSplit,"RRR");
        }
        return result;
    }   

    // generate Wiiides
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        // I really don't want to resort to using these but I might be forced to
        if(bigMad){
            return brainWorms.bigMad(tokenId);
        }
        if(uMad[tokenId]){
            return brainWorms.uMad(tokenId);
        }

        // get the SVG
        string memory punkSVG = cryptoPunksData.punkImageSvg(uint16(tokenId));
        SStrings.slice memory slicePunk = punkSVG.toSlice();            
        // cut the head off
        slicePunk.beyond("data:image/svg+xml;utf8,<svg".toSlice());

        // future proofing max width for browser issues
        uint256 tempInt = tokenHeight[tokenId];
        if(tempInt > maxWidth){
            tempInt = maxWidth;
        }

        string[7] memory parts;
        // replace the svg head of the svg with a stretched style and filled background etc
        parts[0] = '<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><rect width="100%" height="100%" fill="#6a8494"/><svg y="-';
        // the new y offset so the wiiide stays centered
        parts[1] = Strings.toString((tempInt-500)/2);
        parts[2] = '" height="';
        // the new stretched width
        parts[3] = Strings.toString(tempInt);
        parts[4] = '" width="100%" preserveAspectRatio="none" ';
        // reattach the svg head
        parts[5] = slicePunk.toString();
        parts[6] = '</svg>';

       // get attributes which come in as a string like "Male 1, Smile, Mohawk"
        string memory attrs = cryptoPunksData.punkAttributes(uint16(tokenId));
        SStrings.slice memory sliceAttr = attrs.toSlice();            
        SStrings.slice memory delimAttr = ", ".toSlice();     

        // break up that string into an array of independent values
        string[] memory attrParts = new string[](sliceAttr.count(delimAttr)+1); 
        for (uint i = 0; i < attrParts.length; i++) {                              
           attrParts[i] = sliceAttr.split(delimAttr).toString();                               
        }    
     
        string memory output = string.concat(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]);
        string memory trait = string.concat('","attributes": [{"trait_type": "Tyyype","value": "', splitTrait(attrParts[0]) , '"}');
        
        // all the accessories
        for(uint256 i = 1; i < attrParts.length; i++){
            trait = string.concat(trait,',{"trait_type": "Stuuuff","value": "', splitTrait(attrParts[i]), '"}');
        }
        // count the traits
        trait = string.concat(trait,',{"trait_type": "Stuuuff","value": "',  Strings.toString(attrParts.length-1)  , ' Tings"}');
        // show how stretched they are
        attrs = "i";
        uint256 count = 1;
        while(count < (tempInt/500)*100){
            attrs = string.concat(attrs, "i");
            count += 100;
        }
        trait = string.concat(trait,',{"trait_type": "Taaall","value": "Ht', attrs , 'de"}');

        // build the metadata and encode the image as base64
        string memory json = Base64.encode(bytes(string.concat('{"name": "Taaall #', Strings.toString(tokenId),trait, '], "description": "',string(desc),'", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')));
        // encode all of that as base64 and deliver the final TokenURI
        output = string(abi.encodePacked('data:application/json;base64,', json));

        return output;
    }

    // random width of tokens
    function randHeight(uint256 idx) internal view returns(uint256){
        unchecked{
            return rand(((idx%6)+1)*250,totalSupply()) + 550 ;
        }
    }

    // this is not a good random number generator but it's good enough for this
    function rand(uint256 num, uint256 swerve) internal view returns (uint256) {
        return  uint256(keccak256(abi.encodePacked( block.timestamp, num, swerve))) % num;
    }

    // free mint for myself 
    function authorMint(uint256 _amountToMint) external onlyOwner {
        require(
            totalSupply() + _amountToMint <= maxSupply,
            "Request to mint tokens exceeds supply"
        );
        uint256 i;
        while (i < _amountToMint) {
            _mint();
            unchecked{
                i++;
            }
        }
    }

    // set mint prices
    function authorSetMintPrices(uint256 newMintPriceFive, uint256 newMintPriceSixNine) external onlyOwner {
        require(
            newMintPriceFive > 0.01 ether,
            "wrong units"
        );
        require(
            newMintPriceSixNine > 0.01 ether,
            "wrong units"
        );
        MINT_PRICE_FIVE = newMintPriceFive;
        MINT_PRICE_SIXNINE = newMintPriceSixNine;
    }
    
    // this avoids having to pre-populate a giant array
    // where the value stored at an index is equal to the index
    function getSwapIdx(uint256 idx) private view returns(uint256){
        // the index to swap with
        if(tokenOrder[idx] !=0){
            // there's actually a value there
            return tokenOrder[idx];
        } else{
            // no value has been assigned 
            // so by default the value is the index
            return idx;
        }
    }

    // Non repeating integers via Fischer Yates Shuffle
    // this isn't a high security way of doing this,
    // as I'm just going to store the shuffle order as a private variable
    // and anyone determined enough could read it, and mint the wiiides
    // that are rarest. But most people won't bother or know how.
    // And if you're really that determined to exploit such a 
    // goofy project, maybe you should be doing MEV or something instead,
    // or go buy a mountain bike and touch grass
    function authorInitTokenShuffle(uint256 newRange) external onlyOwner {
        require(
            tokenOrderRange == 0,
            "token shuffle already called"
        );
        tokenOrderRange = newRange;
        uint256 i = tokenOrderRange-1;
        uint256 a;
        uint256 b;
        uint256 n;
        while(i > 0){
            // the value we're at
            a = getSwapIdx(i);
            // the value to swap to
            n = rand(i+1,i);
            b = getSwapIdx(n);
            // do the swap 
            tokenOrder[i] = b;
            tokenOrder[n] = a;
            unchecked{
                i = i - 1;
            }
        }
    }

    // register contracts
    function authorRegisterContracts(address[] calldata addr) external onlyOwner{
        cryptoPunks = CryptoPunksMarket(addr[0]);
        cryptoPunksData = CryptoPunksData(addr[1]);
    }

    // set desc for metadata because its looong for wiiides
    function authorSetDesc(bytes calldata newDesc) external onlyOwner{
        desc = newDesc;
    }

    // emergency set new max width if there's a browser rendering problem in the future 
    function authorSetMaxWidth(uint256 val) external onlyOwner {
        maxWidth = val;
    }

    // set withdraw address
    function authorRegisterWithdrawlAddress(address payable givenWithdrawalAddress) external onlyOwner {
        withdrawalAddress = givenWithdrawalAddress;
    }

    // toggle to start/pause minting
    function authorToggleMintState(bool mintState, bool claimState) external onlyOwner {
        mintActive = mintState;
        claimActive = claimState;
    }

    // thank you 
    function authorWithdraw() external onlyOwner {
        (bool success, ) = withdrawalAddress.call{value:address(this).balance}("");
        require(success, "Transfer failed.");
    }

    function authorYouMad(uint256 idx, bool b) external onlyOwner {
        uMad[idx] = b;
    }

    function authorBigMad(bool b) external onlyOwner{
        bigMad = b;
    }

    function authorBrainWorms(address addr) external onlyOwner{
        brainWorms = BrainWorms(addr);
    }

    // thanks but why did you send shitcoins to this contract
    function authorForwardERC20s(IERC20 _token, address _to, uint256 _amount) external onlyOwner {
        require(
            address(_to) != address(0),
            "Can't send to a zero address."
        );
        _token.transfer(_to, _amount);
    }
   
    // tallenoooor
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
        if(tokenHeight[tokenId] < maxWidth){
            // 1.2x to 2x growth rate depending on tokenId 0th to 20th
            // (tokenId %20)*50)+1150
            // it's scaled up and divided by 1000 to behave like a decimal place
            unchecked {
                tokenHeight[tokenId] =  (tokenHeight[tokenId]* ((tokenId % 20)*50+1150 ))/1000;
            }
        } 
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }


}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";
        uint256 encodedLen = 4 * ((len + 2) / 3);
        bytes memory result = new bytes(encodedLen + 32);
        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)
            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)
                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)
                mstore(resultPtr, out)
                resultPtr := add(resultPtr, 4)
            }
            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }
            mstore(result, encodedLen)
        }
        return string(result);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MINT_PRICE_FIVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE_SIXNINE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"b","type":"bool"}],"name":"authorBigMad","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"authorBrainWorms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"authorForwardERC20s","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRange","type":"uint256"}],"name":"authorInitTokenShuffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountToMint","type":"uint256"}],"name":"authorMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addr","type":"address[]"}],"name":"authorRegisterContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"givenWithdrawalAddress","type":"address"}],"name":"authorRegisterWithdrawlAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"newDesc","type":"bytes"}],"name":"authorSetDesc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"authorSetMaxWidth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintPriceFive","type":"uint256"},{"internalType":"uint256","name":"newMintPriceSixNine","type":"uint256"}],"name":"authorSetMintPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"mintState","type":"bool"},{"internalType":"bool","name":"claimState","type":"bool"}],"name":"authorToggleMintState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authorWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"},{"internalType":"bool","name":"b","type":"bool"}],"name":"authorYouMad","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bigMad","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintSixtyNine","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenOwnerResetStretch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uMad","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040526704c9afac0f828000600f55673a4965bf58a400006010556011805461ffff60a01b19169055600060138190556014556117706015553480156200004757600080fd5b506040805180820182526007815266546161616c6c7360c81b60208083019182528351808501909452600684526515105050531360d21b908401528151919291620000959160009162000116565b508051620000ab90600190602084019062000116565b50506001600a5550620000be33620000c4565b620001f9565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200012490620001bc565b90600052602060002090601f01602090048101928262000148576000855562000193565b82601f106200016357805160ff191683800117855562000193565b8280016001018555821562000193579182015b828111156200019357825182559160200191906001019062000176565b50620001a1929150620001a5565b5090565b5b80821115620001a15760008155600101620001a6565b600181811c90821680620001d157607f821691505b60208210811415620001f357634e487b7160e01b600052602260045260246000fd5b50919050565b6149da80620002096000396000f3fe6080604052600436106102fd5760003560e01c8063715018a61161018f578063beae6e3c116100e1578063d5abeb011161008a578063f2bcd02211610064578063f2bcd02214610858578063f2fde38b14610878578063f551a0ef1461089857600080fd5b8063d5abeb01146107c9578063e0530953146107df578063e985e9c51461080f57600080fd5b8063c915e7c6116100bb578063c915e7c614610768578063d110716314610788578063d4a6a2fd146107a857600080fd5b8063beae6e3c14610712578063bf05701814610732578063c87b56dd1461074857600080fd5b8063913de3ff11610143578063a32dfc791161011d578063a32dfc79146106bc578063b20d10bf146106dc578063b88d4fde146106f257600080fd5b8063913de3ff1461066757806395d89b4114610687578063a22cb4651461069c57600080fd5b80638614896a116101745780638614896a146106095780638da5cb5b146106295780638f3ac22e1461064757600080fd5b8063715018a6146105d45780637f0a9d8a146105e957600080fd5b8063370411db116102535780634f6ccce7116101fc5780636352211e116101d65780636352211e1461057f5780636e8ff28e1461059f57806370a08231146105b457600080fd5b80634f6ccce71461052557806352189762146105455780635ac89d531461056557600080fd5b806342842e0e1161022d57806342842e0e146104c557806342966c68146104e55780634dea28431461050557600080fd5b8063370411db1461047057806340826a711461049d57806340dd8e10146104a557600080fd5b80630ced8637116102b557806325fd90f31161028f57806325fd90f31461040f5780632f745c5914610430578063356a36b11461045057600080fd5b80630ced8637146103bb57806318160ddd146103d057806323b872dd146103ef57600080fd5b8063081812fc116102e6578063081812fc1461035957806309327fac14610391578063095ea7b31461039b57600080fd5b806301ffc9a71461030257806306fdde0314610337575b600080fd5b34801561030e57600080fd5b5061032261031d366004613bc1565b6108b8565b60405190151581526020015b60405180910390f35b34801561034357600080fd5b5061034c6108c9565b60405161032e9190613c36565b34801561036557600080fd5b50610379610374366004613c49565b61095b565b6040516001600160a01b03909116815260200161032e565b610399610982565b005b3480156103a757600080fd5b506103996103b6366004613c77565b610bc6565b3480156103c757600080fd5b50610399610cf8565b3480156103dc57600080fd5b506008545b60405190815260200161032e565b3480156103fb57600080fd5b5061039961040a366004613ca3565b610ed0565b34801561041b57600080fd5b5060115461032290600160a01b900460ff1681565b34801561043c57600080fd5b506103e161044b366004613c77565b610f49565b34801561045c57600080fd5b5061039961046b366004613c49565b610ff1565b34801561047c57600080fd5b506103e161048b366004613c49565b60166020526000908152604090205481565b61039961106c565b3480156104b157600080fd5b506103996104c0366004613c49565b6112a3565b3480156104d157600080fd5b506103996104e0366004613ca3565b61133d565b3480156104f157600080fd5b50610399610500366004613c49565b611358565b34801561051157600080fd5b50610399610520366004613cf2565b6113d0565b34801561053157600080fd5b506103e1610540366004613c49565b6113eb565b34801561055157600080fd5b50610399610560366004613d0f565b61148f565b34801561057157600080fd5b506018546103229060ff1681565b34801561058b57600080fd5b5061037961059a366004613c49565b611500565b3480156105ab57600080fd5b50610399611565565b3480156105c057600080fd5b506103e16105cf366004613d48565b611610565b3480156105e057600080fd5b506103996116aa565b3480156105f557600080fd5b50610399610604366004613c49565b6116be565b34801561061557600080fd5b50610399610624366004613d65565b6116cb565b34801561063557600080fd5b50600b546001600160a01b0316610379565b34801561065357600080fd5b50610399610662366004613dda565b611767565b34801561067357600080fd5b50610399610682366004613c49565b61178f565b34801561069357600080fd5b5061034c611860565b3480156106a857600080fd5b506103996106b7366004613dff565b61186f565b3480156106c857600080fd5b506103996106d7366004613e1d565b61187a565b3480156106e857600080fd5b506103e160105481565b3480156106fe57600080fd5b5061039961070d366004613eae565b611915565b34801561071e57600080fd5b5061039961072d366004613f5d565b611994565b34801561073e57600080fd5b506103e1600f5481565b34801561075457600080fd5b5061034c610763366004613c49565b6119a8565b34801561077457600080fd5b50610399610783366004613d48565b6120d0565b34801561079457600080fd5b506103996107a3366004613ca3565b6120fa565b3480156107b457600080fd5b5060115461032290600160a81b900460ff1681565b3480156107d557600080fd5b506103e1611af481565b3480156107eb57600080fd5b506103226107fa366004613c49565b60176020526000908152604090205460ff1681565b34801561081b57600080fd5b5061032261082a366004613fbd565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561086457600080fd5b50601154610379906001600160a01b031681565b34801561088457600080fd5b50610399610893366004613d48565b6121e4565b3480156108a457600080fd5b506103996108b3366004613d48565b612271565b60006108c38261229b565b92915050565b6060600080546108d890613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461090490613feb565b80156109515780601f1061092657610100808354040283529160200191610951565b820191906000526020600020905b81548152906001019060200180831161093457829003601f168201915b5050505050905090565b6000610966826122d9565b506000908152600460205260409020546001600160a01b031690565b6002600a5414156109da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600a55323314610a2e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b600c610a3933611610565b610a4490600561403c565b1115610a925760405162461bcd60e51b815260206004820152601060248201527f796f75206f776e20746f6f206d616e790000000000000000000000000000000060448201526064016109d1565b600f54341015610ae45760405162461bcd60e51b815260206004820152601060248201527f4574682073656e7420746f6f206c6f770000000000000000000000000000000060448201526064016109d1565b601154600160a01b900460ff16610b2f5760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b611af4610b3b60085490565b610b4690600561403c565b1115610ba25760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b6005811015610bbe57610bb661233d565b600101610ba5565b506001600a55565b6000610bd182611500565b9050806001600160a01b0316836001600160a01b03161415610c5b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016109d1565b336001600160a01b0382161480610c775750610c77813361082a565b610ce95760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109d1565b610cf383836123da565b505050565b6002600a541415610d4b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109d1565b6002600a55323314610d9f5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b601154600160a01b900460ff16610dea5760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b6002610df533611610565b610e0090600161403c565b1115610e4e5760405162461bcd60e51b815260206004820152601260248201527f6c696d697420322066726565206d696e7473000000000000000000000000000060448201526064016109d1565b611af4610e5a60085490565b610e6590600161403c565b1115610ec15760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b610ec961233d565b6001600a55565b610edb335b82612448565b610f3e5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b610cf38383836124c7565b6000610f5483611610565b8210610fc85760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109d1565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b33610ffb82611500565b6001600160a01b0316146110515760405162461bcd60e51b815260206004820152600f60248201527f6e6f7420796f757220746161616c6c000000000000000000000000000000000060448201526064016109d1565b61105a8161269f565b60009182526016602052604090912055565b6002600a5414156110bf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109d1565b6002600a553233146111135760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b604b61111e33611610565b61112990604561403c565b11156111775760405162461bcd60e51b815260206004820152601060248201527f796f75206f776e20746f6f206d616e790000000000000000000000000000000060448201526064016109d1565b6010543410156111c95760405162461bcd60e51b815260206004820152601060248201527f4574682073656e7420746f6f206c6f770000000000000000000000000000000060448201526064016109d1565b601154600160a01b900460ff166112145760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b611af461122060085490565b61122b90604561403c565b11156112875760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b6045811015610bbe5761129b61233d565b60010161128a565b6112ab6126c6565b611af4816112b860085490565b6112c2919061403c565b111561131e5760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b818110156113395761133161233d565b600101611321565b5050565b610cf383838360405180602001604052806000815250611915565b61136133610ed5565b6113c45760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b6113cd81612720565b50565b6113d86126c6565b6018805460ff1916911515919091179055565b60006113f660085490565b821061146a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109d1565b6008828154811061147d5761147d614054565b90600052602060002001549050919050565b6114976126c6565b601180547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff16600160a01b931515939093027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1692909217600160a81b91151591909102179055565b6000818152600260205260408120546001600160a01b0316806108c35760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109d1565b61156d6126c6565b6011546040516000916001600160a01b03169047908381818185875af1925050503d80600081146115ba576040519150601f19603f3d011682016040523d82523d6000602084013e6115bf565b606091505b50509050806113cd5760405162461bcd60e51b815260206004820152601060248201527f5472616e73666572206661696c65642e0000000000000000000000000000000060448201526064016109d1565b60006001600160a01b03821661168e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e6572000000000000000000000000000000000000000000000060648201526084016109d1565b506001600160a01b031660009081526003602052604090205490565b6116b26126c6565b6116bc60006127c7565b565b6116c66126c6565b601555565b6116d36126c6565b818160008181106116e6576116e6614054565b90506020020160208101906116fb9190613d48565b600c80546001600160a01b0319166001600160a01b03929092169190911790558181600181811061172e5761172e614054565b90506020020160208101906117439190613d48565b600d80546001600160a01b0319166001600160a01b03929092169190911790555050565b61176f6126c6565b600091825260176020526040909120805460ff1916911515919091179055565b6117976126c6565b601354156117e75760405162461bcd60e51b815260206004820152601c60248201527f746f6b656e2073687566666c6520616c72656164792063616c6c65640000000060448201526064016109d1565b601381905560006117f960018361406a565b905060008060005b83156118595761181084612819565b925061182661182085600161403c565b85612849565b905061183181612819565b6000858152601260205260408082208390558382529020849055600019909401939150611801565b5050505050565b6060600180546108d890613feb565b611339338383612892565b6118826126c6565b662386f26fc1000082116118c65760405162461bcd60e51b815260206004820152600b60248201526a77726f6e6720756e69747360a81b60448201526064016109d1565b662386f26fc10000811161190a5760405162461bcd60e51b815260206004820152600b60248201526a77726f6e6720756e69747360a81b60448201526064016109d1565b600f91909155601055565b61191f3383612448565b6119825760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b61198e84848484612961565b50505050565b61199c6126c6565b610cf360198383613aef565b60185460609060ff1615611a4157600e546040517fb3159b69000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063b3159b69906024015b600060405180830381865afa158015611a19573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c39190810190614081565b60008281526017602052604090205460ff1615611aa257600e546040517fe0530953000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063e0530953906024016119fc565b600d546040517f74beb04700000000000000000000000000000000000000000000000000000000815261ffff841660048201526000916001600160a01b0316906374beb04790602401600060405180830381865afa158015611b08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b309190810190614081565b90506000611b658260408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b604080518082018252601c81527f646174613a696d6167652f7376672b786d6c3b757466382c3c7376670000000060208083019182528351808501855260008082529082015283518085019094529151835290820152909150611bc99082906129df565b50600084815260166020526040902054601554811115611be857506015545b611bf0613b6f565b6040518060c00160405280609681526020016148a5609691398152611c2b6002611c1c6101f48561406a565b611c26919061410e565b612a64565b602082810191909152604080518082018252600a81527f22206865696768743d220000000000000000000000000000000000000000000092810192909252820152611c7582612a64565b606080830191909152604080519182019052602a80825261497b60208301396080820152611ca283612b96565b60a08201526040805180820190915260068082527f3c2f7376673e0000000000000000000000000000000000000000000000000000602083015282906020020152600d546040517f76dfe29700000000000000000000000000000000000000000000000000000000815261ffff881660048201526000916001600160a01b0316906376dfe29790602401600060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d719190810190614081565b90506000611da68260408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b604080518082018252600281527f2c20000000000000000000000000000000000000000000000000000000000000602080830191825283518085018552600080825290820181905284518086019095529251845283015291925090611e0b8383612c06565b611e1690600161403c565b67ffffffffffffffff811115611e2e57611e2e613e3f565b604051908082528060200260200182016040528015611e6157816020015b6060815260200190600190039081611e4c5790505b50905060005b8151811015611eb257611e82611e7d8585612ca0565b612b96565b828281518110611e9457611e94614054565b60200260200101819052508080611eaa90614122565b915050611e67565b50845160208087015160408089015160608a015160808b015160a08c015160c08d01519451600098611ee8989097969101614159565b60405160208183030381529060405290506000611f1e83600081518110611f1157611f11614054565b6020026020010151612cbf565b604051602001611f2e91906141eb565b60408051601f19818403018152919052905060015b8351811015611f975781611f62858381518110611f1157611f11614054565b604051602001611f73929190614262565b60405160208183030381529060405291508080611f8f90614122565b915050611f43565b5080611faa60018551611c26919061406a565b604051602001611fbb9291906142d8565b60408051601f198184030181528282019091526001808352606960f81b602084015291975091505b611fef6101f48a61410e565b611ffa906064614369565b81101561203657866040516020016120129190614388565b60408051601f19818403018152919052965061202f60648261403c565b9050611fe3565b81876040516020016120499291906143ad565b6040516020818303038152906040529150600061209b6120688f612a64565b84601961207488612e39565b6040516020016120879493929190614456565b604051602081830303815290604052612e39565b9050806040516020016120ae91906145e0565b60408051601f198184030181529190529e9d5050505050505050505050505050565b6120d86126c6565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6121026126c6565b6001600160a01b0382166121585760405162461bcd60e51b815260206004820152601d60248201527f43616e27742073656e6420746f2061207a65726f20616464726573732e00000060448201526064016109d1565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af11580156121c0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198e9190614625565b6121ec6126c6565b6001600160a01b0381166122685760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109d1565b6113cd816127c7565b6122796126c6565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806108c357506108c382612fd6565b6000818152600260205260409020546001600160a01b03166113cd5760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109d1565b60005b60135460135460145481612356576123566140f8565b0402601260006013546014548161236f5761236f6140f8565b068152602001908152602001600020540190506016600082815260200190815260200160002054600014156123cc576123a78161269f565b6000828152601660205260409020556123c03382613071565b60148054600101905550565b601480546001019055612340565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061240f82611500565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061245483611500565b9050806001600160a01b0316846001600160a01b0316148061249b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806124bf5750836001600160a01b03166124b48461095b565b6001600160a01b0316145b949350505050565b826001600160a01b03166124da82611500565b6001600160a01b0316146125565760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016109d1565b6001600160a01b0382166125d15760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109d1565b6125dc83838361308b565b6125e76000826123da565b6001600160a01b038316600090815260036020526040812080546001929061261090849061406a565b90915550506001600160a01b038216600090815260036020526040812080546001929061263e90849061403c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006126bc6006830660010160fa026126b760085490565b612849565b6102260192915050565b600b546001600160a01b031633146116bc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d1565b600061272b82611500565b90506127398160008461308b565b6127446000836123da565b6001600160a01b038116600090815260036020526040812080546001929061276d90849061406a565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008181526012602052604081205415612840575060009081526012602052604090205490565b5090565b919050565b604080514260208201529081018390526060810182905260009083906080016040516020818303038152906040528051906020012060001c61288b9190614642565b9392505050565b816001600160a01b0316836001600160a01b031614156128f45760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109d1565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61296c8484846124c7565b612978848484846130d8565b61198e5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b6040805180820190915260008082526020820152815183511015612a045750816108c3565b6020808301519084015160019114612a2b5750815160208481015190840151829020919020145b8015612a5c57825184518590612a4290839061406a565b9052508251602085018051612a5890839061403c565b9052505b509192915050565b606081612aa457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612ace5780612ab881614122565b9150612ac79050600a8361410e565b9150612aa8565b60008167ffffffffffffffff811115612ae957612ae9613e3f565b6040519080825280601f01601f191660200182016040528015612b13576020820181803683370190505b5090505b84156124bf57612b2860018361406a565b9150612b35600a86614642565b612b4090603061403c565b60f81b818381518110612b5557612b55614054565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612b8f600a8661410e565b9450612b17565b60606000826000015167ffffffffffffffff811115612bb757612bb7613e3f565b6040519080825280601f01601f191660200182016040528015612be1576020820181803683370190505b5090506000602082019050612bff8185602001518660000151613221565b5092915050565b6000808260000151612c2a856000015186602001518660000151876020015161329b565b612c34919061403c565b90505b83516020850151612c48919061403c565b8111612bff5781612c5881614122565b9250508260000151612c8f856020015183612c73919061406a565b8651612c7f919061406a565b838660000151876020015161329b565b612c99919061403c565b9050612c37565b6040805180820190915260008082526020820152612bff8383836133bc565b604080518082018252600080825260209182015281518083019092528251825280830190820152606090612d28906040518060400160405280600181526020017f6f00000000000000000000000000000000000000000000000000000000000000815250613468565b9050805160001415612d9d57604080518082018252600080825260209182015281518083019092528351825280840190820152612d9a906040518060400160405280600181526020017f6100000000000000000000000000000000000000000000000000000000000000815250613468565b90505b8051612e0c57604080518082018252600080825260209182015281518083019092528351825280840190820152612e09906040518060400160405280600181526020017f6500000000000000000000000000000000000000000000000000000000000000815250613468565b90505b80516128445781604051602001612e239190614656565b6040516020818303038152906040529050919050565b805160609080612e59575050604080516020810190915260008152919050565b60006003612e6883600261403c565b612e72919061410e565b612e7d906004614369565b90506000612e8c82602061403c565b67ffffffffffffffff811115612ea457612ea4613e3f565b6040519080825280601f01601f191660200182016040528015612ece576020820181803683370190505b509050600060405180606001604052806040815260200161493b604091399050600181016020830160005b86811015612f5a576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612ef9565b506003860660018114612f745760028114612fa057612fc8565b7f3d3d000000000000000000000000000000000000000000000000000000000000600119830152612fc8565b7f3d000000000000000000000000000000000000000000000000000000000000006000198301525b505050918152949350505050565b60006001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000148061303957506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806108c357507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146108c3565b6113398282604051806020016040528060008152506135a0565b61309683838361361e565b6015546000828152601660205260409020541015610cf357600081815260166020526040902080546103e8601490930660320261047e01029190910490555050565b60006001600160a01b0384163b1561321657604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061311c903390899088908890600401614697565b6020604051808303816000875af1925050508015613157575060408051601f3d908101601f19168201909252613154918101906146d3565b60015b6131fc573d808015613185576040519150601f19603f3d011682016040523d82523d6000602084013e61318a565b606091505b5080516131f45760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506124bf565b506001949350505050565b60208110613259578151835261323860208461403c565b925061324560208361403c565b915061325260208261406a565b9050613221565b600019811561328857600161326f83602061406a565b61327b906101006147d4565b613285919061406a565b90505b9151835183169219169190911790915250565b600083818685116133a7576020851161335557600085156132e75760016132c387602061406a565b6132ce906008614369565b6132d99060026147d4565b6132e3919061406a565b1990505b845181166000876132f88b8b61403c565b613302919061406a565b855190915083165b8281146133475781861061332f576133228b8b61403c565b96505050505050506124bf565b8561333981614122565b96505083865116905061330a565b8596505050505050506124bf565b508383206000905b613367868961406a565b82116133a5578583208181141561338457839450505050506124bf565b61338f60018561403c565b935050818061339d90614122565b92505061335d565b505b6133b1878761403c565b979650505050505050565b604080518082019091526000808252602082015260006133ee856000015186602001518660000151876020015161329b565b60208087018051918601919091525190915061340a908261406a565b83528451602086015161341d919061403c565b81141561342d576000855261345f565b8351835161343b919061403c565b8551869061344a90839061406a565b9052508351613459908261403c565b60208601525b50909392505050565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061349d9084906136d6565b156134fa576134f76134ae84612b96565b83846040516020016134c2939291906147e0565b60408051601f198184030181528282018252600080845260209384015281518083019092528051825282019181019190915290565b92505b60006135376135308460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b8590612ca0565b9050600061354485613738565b11156135895761355381612b96565b83848561355f88612b96565b604051602001613573959493929190614823565b6040516020818303038152906040529150612bff565b505060408051602081019091526000815292915050565b6135aa8383613811565b6135b760008484846130d8565b610cf35760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b6001600160a01b0383166136795761367481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61369c565b816001600160a01b0316836001600160a01b03161461369c5761369c838261395f565b6001600160a01b0382166136b357610cf3816139fc565b826001600160a01b0316826001600160a01b031614610cf357610cf38282613aab565b8051825160009111156136eb575060006108c3565b815183516020850151600092916137019161403c565b61370b919061406a565b905082602001518114156137235760019150506108c3565b82516020840151819020912014905092915050565b600080601f836020015161374c919061406a565b835190915060009061375e908361403c565b9050600092505b8082101561380a57815160ff16608081101561378d5761378660018461403c565b92506137f7565b60e08160ff1610156137a45761378660028461403c565b60f08160ff1610156137bb5761378660038461403c565b60f88160ff1610156137d25761378660048461403c565b60fc8160ff1610156137e95761378660058461403c565b6137f460068461403c565b92505b508261380281614122565b935050613765565b5050919050565b6001600160a01b0382166138675760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109d1565b6000818152600260205260409020546001600160a01b0316156138cc5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109d1565b6138d86000838361308b565b6001600160a01b038216600090815260036020526040812080546001929061390190849061403c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161396c84611610565b613976919061406a565b6000838152600760205260409020549091508082146139c9576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613a0e9060019061406a565b60008381526009602052604081205460088054939450909284908110613a3657613a36614054565b906000526020600020015490508060088381548110613a5757613a57614054565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613a8f57613a8f61488e565b6001900381819060005260206000200160009055905550505050565b6000613ab683611610565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054613afb90613feb565b90600052602060002090601f016020900481019282613b1d5760008555613b63565b82601f10613b365782800160ff19823516178555613b63565b82800160010185558215613b63579182015b82811115613b63578235825591602001919060010190613b48565b50612840929150613b96565b6040518060e001604052806007905b6060815260200190600190039081613b7e5790505090565b5b808211156128405760008155600101613b97565b6001600160e01b0319811681146113cd57600080fd5b600060208284031215613bd357600080fd5b813561288b81613bab565b60005b83811015613bf9578181015183820152602001613be1565b8381111561198e5750506000910152565b60008151808452613c22816020860160208601613bde565b601f01601f19169290920160200192915050565b60208152600061288b6020830184613c0a565b600060208284031215613c5b57600080fd5b5035919050565b6001600160a01b03811681146113cd57600080fd5b60008060408385031215613c8a57600080fd5b8235613c9581613c62565b946020939093013593505050565b600080600060608486031215613cb857600080fd5b8335613cc381613c62565b92506020840135613cd381613c62565b929592945050506040919091013590565b80151581146113cd57600080fd5b600060208284031215613d0457600080fd5b813561288b81613ce4565b60008060408385031215613d2257600080fd5b8235613d2d81613ce4565b91506020830135613d3d81613ce4565b809150509250929050565b600060208284031215613d5a57600080fd5b813561288b81613c62565b60008060208385031215613d7857600080fd5b823567ffffffffffffffff80821115613d9057600080fd5b818501915085601f830112613da457600080fd5b813581811115613db357600080fd5b8660208260051b8501011115613dc857600080fd5b60209290920196919550909350505050565b60008060408385031215613ded57600080fd5b823591506020830135613d3d81613ce4565b60008060408385031215613e1257600080fd5b8235613d2d81613c62565b60008060408385031215613e3057600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613e7e57613e7e613e3f565b604052919050565b600067ffffffffffffffff821115613ea057613ea0613e3f565b50601f01601f191660200190565b60008060008060808587031215613ec457600080fd5b8435613ecf81613c62565b93506020850135613edf81613c62565b925060408501359150606085013567ffffffffffffffff811115613f0257600080fd5b8501601f81018713613f1357600080fd5b8035613f26613f2182613e86565b613e55565b818152886020838501011115613f3b57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060208385031215613f7057600080fd5b823567ffffffffffffffff80821115613f8857600080fd5b818501915085601f830112613f9c57600080fd5b813581811115613fab57600080fd5b866020828501011115613dc857600080fd5b60008060408385031215613fd057600080fd5b8235613fdb81613c62565b91506020830135613d3d81613c62565b600181811c90821680613fff57607f821691505b6020821081141561402057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561404f5761404f614026565b500190565b634e487b7160e01b600052603260045260246000fd5b60008282101561407c5761407c614026565b500390565b60006020828403121561409357600080fd5b815167ffffffffffffffff8111156140aa57600080fd5b8201601f810184136140bb57600080fd5b80516140c9613f2182613e86565b8181528560208385010111156140de57600080fd5b6140ef826020830160208601613bde565b95945050505050565b634e487b7160e01b600052601260045260246000fd5b60008261411d5761411d6140f8565b500490565b600060001982141561413657614136614026565b5060010190565b6000815161414f818560208601613bde565b9290920192915050565b60008851602061416c8285838e01613bde565b89519184019161417f8184848e01613bde565b89519201916141918184848d01613bde565b88519201916141a38184848c01613bde565b87519201916141b58184848b01613bde565b86519201916141c78184848a01613bde565b85519201916141d98184848901613bde565b919091019a9950505050505050505050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2081527f22547979797065222c2276616c7565223a202200000000000000000000000000602082015260008251614249816033850160208701613bde565b61227d60f01b6033939091019283015250603501919050565b60008351614274818460208801613bde565b6142b08184017f2c7b2274726169745f74797065223a202253747575756666222c2276616c7565815263111d101160e11b602082015260240190565b905083516142c2818360208801613bde565b61227d60f01b9101908152600201949350505050565b600083516142ea818460208801613bde565b6143268184017f2c7b2274726169745f74797065223a202253747575756666222c2276616c7565815263111d101160e11b602082015260240190565b90508351614338818360208801613bde565b7f2054696e6773227d0000000000000000000000000000000000000000000000009101908152600801949350505050565b600081600019048311821515161561438357614383614026565b500290565b6000825161439a818460208701613bde565b606960f81b920191825250600101919050565b600083516143bf818460208801613bde565b80830190507f2c7b2274726169745f74797065223a2022546161616c6c222c2276616c75652281527f3a2022487400000000000000000000000000000000000000000000000000000060208201528351614420816025840160208801613bde565b7f6465227d0000000000000000000000000000000000000000000000000000000060259290910191820152602901949350505050565b7f7b226e616d65223a2022546161616c6c20230000000000000000000000000000815260008551602061448f8260128601838b01613bde565b8651918401916144a58160128501848b01613bde565b7f5d2c20226465736372697074696f6e223a202200000000000000000000000000601293909101928301528554602590600090600181811c90808316806144ed57607f831692505b86831081141561450b57634e487b7160e01b85526022600452602485fd5b80801561451f576001811461453457614565565b60ff1985168988015283890187019550614565565b60008d81526020902060005b8581101561455b5781548b82018a0152908401908901614540565b505086848a010195505b50507f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b845250507f6261736536342c000000000000000000000000000000000000000000000000006020830152506145c0602782018861413d565b93505050506145d38161227d60f01b9052565b6002019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161461881601d850160208701613bde565b91909101601d0192915050565b60006020828403121561463757600080fd5b815161288b81613ce4565b600082614651576146516140f8565b500690565b60008251614668818460208701613bde565b7f5252520000000000000000000000000000000000000000000000000000000000920191825250600301919050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526146c96080830184613c0a565b9695505050505050565b6000602082840312156146e557600080fd5b815161288b81613bab565b600181815b8085111561472b57816000190482111561471157614711614026565b8085161561471e57918102915b93841c93908002906146f5565b509250929050565b600082614742575060016108c3565b8161474f575060006108c3565b8160018114614765576002811461476f5761478b565b60019150506108c3565b60ff84111561478057614780614026565b50506001821b6108c3565b5060208310610133831016604e8410600b84101617156147ae575081810a6108c3565b6147b883836146f0565b80600019048211156147cc576147cc614026565b029392505050565b600061288b8383614733565b600084516147f2818460208901613bde565b845190830190614806818360208901613bde565b8451910190614819818360208801613bde565b0195945050505050565b60008651614835818460208b01613bde565b865190830190614849818360208b01613bde565b865191019061485c818360208a01613bde565b855191019061486f818360208901613bde565b8451910190614882818360208801613bde565b01979650505050505050565b634e487b7160e01b600052603160045260246000fdfe3c7376672077696474683d2235303022206865696768743d223530302220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d226e6f6e65223e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2223366138343934222f3e3c73766720793d222d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222077696474683d223130302522207072657365727665417370656374526174696f3d226e6f6e652220a2646970667358221220fd89e0faa34deceba58a571b1f54f8c18b7726df59c8cb32d9ff1ef06691c71064736f6c634300080c0033

Deployed Bytecode

0x6080604052600436106102fd5760003560e01c8063715018a61161018f578063beae6e3c116100e1578063d5abeb011161008a578063f2bcd02211610064578063f2bcd02214610858578063f2fde38b14610878578063f551a0ef1461089857600080fd5b8063d5abeb01146107c9578063e0530953146107df578063e985e9c51461080f57600080fd5b8063c915e7c6116100bb578063c915e7c614610768578063d110716314610788578063d4a6a2fd146107a857600080fd5b8063beae6e3c14610712578063bf05701814610732578063c87b56dd1461074857600080fd5b8063913de3ff11610143578063a32dfc791161011d578063a32dfc79146106bc578063b20d10bf146106dc578063b88d4fde146106f257600080fd5b8063913de3ff1461066757806395d89b4114610687578063a22cb4651461069c57600080fd5b80638614896a116101745780638614896a146106095780638da5cb5b146106295780638f3ac22e1461064757600080fd5b8063715018a6146105d45780637f0a9d8a146105e957600080fd5b8063370411db116102535780634f6ccce7116101fc5780636352211e116101d65780636352211e1461057f5780636e8ff28e1461059f57806370a08231146105b457600080fd5b80634f6ccce71461052557806352189762146105455780635ac89d531461056557600080fd5b806342842e0e1161022d57806342842e0e146104c557806342966c68146104e55780634dea28431461050557600080fd5b8063370411db1461047057806340826a711461049d57806340dd8e10146104a557600080fd5b80630ced8637116102b557806325fd90f31161028f57806325fd90f31461040f5780632f745c5914610430578063356a36b11461045057600080fd5b80630ced8637146103bb57806318160ddd146103d057806323b872dd146103ef57600080fd5b8063081812fc116102e6578063081812fc1461035957806309327fac14610391578063095ea7b31461039b57600080fd5b806301ffc9a71461030257806306fdde0314610337575b600080fd5b34801561030e57600080fd5b5061032261031d366004613bc1565b6108b8565b60405190151581526020015b60405180910390f35b34801561034357600080fd5b5061034c6108c9565b60405161032e9190613c36565b34801561036557600080fd5b50610379610374366004613c49565b61095b565b6040516001600160a01b03909116815260200161032e565b610399610982565b005b3480156103a757600080fd5b506103996103b6366004613c77565b610bc6565b3480156103c757600080fd5b50610399610cf8565b3480156103dc57600080fd5b506008545b60405190815260200161032e565b3480156103fb57600080fd5b5061039961040a366004613ca3565b610ed0565b34801561041b57600080fd5b5060115461032290600160a01b900460ff1681565b34801561043c57600080fd5b506103e161044b366004613c77565b610f49565b34801561045c57600080fd5b5061039961046b366004613c49565b610ff1565b34801561047c57600080fd5b506103e161048b366004613c49565b60166020526000908152604090205481565b61039961106c565b3480156104b157600080fd5b506103996104c0366004613c49565b6112a3565b3480156104d157600080fd5b506103996104e0366004613ca3565b61133d565b3480156104f157600080fd5b50610399610500366004613c49565b611358565b34801561051157600080fd5b50610399610520366004613cf2565b6113d0565b34801561053157600080fd5b506103e1610540366004613c49565b6113eb565b34801561055157600080fd5b50610399610560366004613d0f565b61148f565b34801561057157600080fd5b506018546103229060ff1681565b34801561058b57600080fd5b5061037961059a366004613c49565b611500565b3480156105ab57600080fd5b50610399611565565b3480156105c057600080fd5b506103e16105cf366004613d48565b611610565b3480156105e057600080fd5b506103996116aa565b3480156105f557600080fd5b50610399610604366004613c49565b6116be565b34801561061557600080fd5b50610399610624366004613d65565b6116cb565b34801561063557600080fd5b50600b546001600160a01b0316610379565b34801561065357600080fd5b50610399610662366004613dda565b611767565b34801561067357600080fd5b50610399610682366004613c49565b61178f565b34801561069357600080fd5b5061034c611860565b3480156106a857600080fd5b506103996106b7366004613dff565b61186f565b3480156106c857600080fd5b506103996106d7366004613e1d565b61187a565b3480156106e857600080fd5b506103e160105481565b3480156106fe57600080fd5b5061039961070d366004613eae565b611915565b34801561071e57600080fd5b5061039961072d366004613f5d565b611994565b34801561073e57600080fd5b506103e1600f5481565b34801561075457600080fd5b5061034c610763366004613c49565b6119a8565b34801561077457600080fd5b50610399610783366004613d48565b6120d0565b34801561079457600080fd5b506103996107a3366004613ca3565b6120fa565b3480156107b457600080fd5b5060115461032290600160a81b900460ff1681565b3480156107d557600080fd5b506103e1611af481565b3480156107eb57600080fd5b506103226107fa366004613c49565b60176020526000908152604090205460ff1681565b34801561081b57600080fd5b5061032261082a366004613fbd565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561086457600080fd5b50601154610379906001600160a01b031681565b34801561088457600080fd5b50610399610893366004613d48565b6121e4565b3480156108a457600080fd5b506103996108b3366004613d48565b612271565b60006108c38261229b565b92915050565b6060600080546108d890613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461090490613feb565b80156109515780601f1061092657610100808354040283529160200191610951565b820191906000526020600020905b81548152906001019060200180831161093457829003601f168201915b5050505050905090565b6000610966826122d9565b506000908152600460205260409020546001600160a01b031690565b6002600a5414156109da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600a55323314610a2e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b600c610a3933611610565b610a4490600561403c565b1115610a925760405162461bcd60e51b815260206004820152601060248201527f796f75206f776e20746f6f206d616e790000000000000000000000000000000060448201526064016109d1565b600f54341015610ae45760405162461bcd60e51b815260206004820152601060248201527f4574682073656e7420746f6f206c6f770000000000000000000000000000000060448201526064016109d1565b601154600160a01b900460ff16610b2f5760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b611af4610b3b60085490565b610b4690600561403c565b1115610ba25760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b6005811015610bbe57610bb661233d565b600101610ba5565b506001600a55565b6000610bd182611500565b9050806001600160a01b0316836001600160a01b03161415610c5b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016109d1565b336001600160a01b0382161480610c775750610c77813361082a565b610ce95760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109d1565b610cf383836123da565b505050565b6002600a541415610d4b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109d1565b6002600a55323314610d9f5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b601154600160a01b900460ff16610dea5760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b6002610df533611610565b610e0090600161403c565b1115610e4e5760405162461bcd60e51b815260206004820152601260248201527f6c696d697420322066726565206d696e7473000000000000000000000000000060448201526064016109d1565b611af4610e5a60085490565b610e6590600161403c565b1115610ec15760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b610ec961233d565b6001600a55565b610edb335b82612448565b610f3e5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b610cf38383836124c7565b6000610f5483611610565b8210610fc85760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109d1565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b33610ffb82611500565b6001600160a01b0316146110515760405162461bcd60e51b815260206004820152600f60248201527f6e6f7420796f757220746161616c6c000000000000000000000000000000000060448201526064016109d1565b61105a8161269f565b60009182526016602052604090912055565b6002600a5414156110bf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109d1565b6002600a553233146111135760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e7472616374000060448201526064016109d1565b604b61111e33611610565b61112990604561403c565b11156111775760405162461bcd60e51b815260206004820152601060248201527f796f75206f776e20746f6f206d616e790000000000000000000000000000000060448201526064016109d1565b6010543410156111c95760405162461bcd60e51b815260206004820152601060248201527f4574682073656e7420746f6f206c6f770000000000000000000000000000000060448201526064016109d1565b601154600160a01b900460ff166112145760405162461bcd60e51b815260206004820152600f60248201526e6d696e74206e6f742061637469766560881b60448201526064016109d1565b611af461122060085490565b61122b90604561403c565b11156112875760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b6045811015610bbe5761129b61233d565b60010161128a565b6112ab6126c6565b611af4816112b860085490565b6112c2919061403c565b111561131e5760405162461bcd60e51b815260206004820152602560248201527f5265717565737420746f206d696e7420746f6b656e73206578636565647320736044820152647570706c7960d81b60648201526084016109d1565b60005b818110156113395761133161233d565b600101611321565b5050565b610cf383838360405180602001604052806000815250611915565b61136133610ed5565b6113c45760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b6113cd81612720565b50565b6113d86126c6565b6018805460ff1916911515919091179055565b60006113f660085490565b821061146a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109d1565b6008828154811061147d5761147d614054565b90600052602060002001549050919050565b6114976126c6565b601180547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff16600160a01b931515939093027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1692909217600160a81b91151591909102179055565b6000818152600260205260408120546001600160a01b0316806108c35760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109d1565b61156d6126c6565b6011546040516000916001600160a01b03169047908381818185875af1925050503d80600081146115ba576040519150601f19603f3d011682016040523d82523d6000602084013e6115bf565b606091505b50509050806113cd5760405162461bcd60e51b815260206004820152601060248201527f5472616e73666572206661696c65642e0000000000000000000000000000000060448201526064016109d1565b60006001600160a01b03821661168e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e6572000000000000000000000000000000000000000000000060648201526084016109d1565b506001600160a01b031660009081526003602052604090205490565b6116b26126c6565b6116bc60006127c7565b565b6116c66126c6565b601555565b6116d36126c6565b818160008181106116e6576116e6614054565b90506020020160208101906116fb9190613d48565b600c80546001600160a01b0319166001600160a01b03929092169190911790558181600181811061172e5761172e614054565b90506020020160208101906117439190613d48565b600d80546001600160a01b0319166001600160a01b03929092169190911790555050565b61176f6126c6565b600091825260176020526040909120805460ff1916911515919091179055565b6117976126c6565b601354156117e75760405162461bcd60e51b815260206004820152601c60248201527f746f6b656e2073687566666c6520616c72656164792063616c6c65640000000060448201526064016109d1565b601381905560006117f960018361406a565b905060008060005b83156118595761181084612819565b925061182661182085600161403c565b85612849565b905061183181612819565b6000858152601260205260408082208390558382529020849055600019909401939150611801565b5050505050565b6060600180546108d890613feb565b611339338383612892565b6118826126c6565b662386f26fc1000082116118c65760405162461bcd60e51b815260206004820152600b60248201526a77726f6e6720756e69747360a81b60448201526064016109d1565b662386f26fc10000811161190a5760405162461bcd60e51b815260206004820152600b60248201526a77726f6e6720756e69747360a81b60448201526064016109d1565b600f91909155601055565b61191f3383612448565b6119825760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b60648201526084016109d1565b61198e84848484612961565b50505050565b61199c6126c6565b610cf360198383613aef565b60185460609060ff1615611a4157600e546040517fb3159b69000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063b3159b69906024015b600060405180830381865afa158015611a19573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c39190810190614081565b60008281526017602052604090205460ff1615611aa257600e546040517fe0530953000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063e0530953906024016119fc565b600d546040517f74beb04700000000000000000000000000000000000000000000000000000000815261ffff841660048201526000916001600160a01b0316906374beb04790602401600060405180830381865afa158015611b08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b309190810190614081565b90506000611b658260408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b604080518082018252601c81527f646174613a696d6167652f7376672b786d6c3b757466382c3c7376670000000060208083019182528351808501855260008082529082015283518085019094529151835290820152909150611bc99082906129df565b50600084815260166020526040902054601554811115611be857506015545b611bf0613b6f565b6040518060c00160405280609681526020016148a5609691398152611c2b6002611c1c6101f48561406a565b611c26919061410e565b612a64565b602082810191909152604080518082018252600a81527f22206865696768743d220000000000000000000000000000000000000000000092810192909252820152611c7582612a64565b606080830191909152604080519182019052602a80825261497b60208301396080820152611ca283612b96565b60a08201526040805180820190915260068082527f3c2f7376673e0000000000000000000000000000000000000000000000000000602083015282906020020152600d546040517f76dfe29700000000000000000000000000000000000000000000000000000000815261ffff881660048201526000916001600160a01b0316906376dfe29790602401600060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d719190810190614081565b90506000611da68260408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b604080518082018252600281527f2c20000000000000000000000000000000000000000000000000000000000000602080830191825283518085018552600080825290820181905284518086019095529251845283015291925090611e0b8383612c06565b611e1690600161403c565b67ffffffffffffffff811115611e2e57611e2e613e3f565b604051908082528060200260200182016040528015611e6157816020015b6060815260200190600190039081611e4c5790505b50905060005b8151811015611eb257611e82611e7d8585612ca0565b612b96565b828281518110611e9457611e94614054565b60200260200101819052508080611eaa90614122565b915050611e67565b50845160208087015160408089015160608a015160808b015160a08c015160c08d01519451600098611ee8989097969101614159565b60405160208183030381529060405290506000611f1e83600081518110611f1157611f11614054565b6020026020010151612cbf565b604051602001611f2e91906141eb565b60408051601f19818403018152919052905060015b8351811015611f975781611f62858381518110611f1157611f11614054565b604051602001611f73929190614262565b60405160208183030381529060405291508080611f8f90614122565b915050611f43565b5080611faa60018551611c26919061406a565b604051602001611fbb9291906142d8565b60408051601f198184030181528282019091526001808352606960f81b602084015291975091505b611fef6101f48a61410e565b611ffa906064614369565b81101561203657866040516020016120129190614388565b60408051601f19818403018152919052965061202f60648261403c565b9050611fe3565b81876040516020016120499291906143ad565b6040516020818303038152906040529150600061209b6120688f612a64565b84601961207488612e39565b6040516020016120879493929190614456565b604051602081830303815290604052612e39565b9050806040516020016120ae91906145e0565b60408051601f198184030181529190529e9d5050505050505050505050505050565b6120d86126c6565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6121026126c6565b6001600160a01b0382166121585760405162461bcd60e51b815260206004820152601d60248201527f43616e27742073656e6420746f2061207a65726f20616464726573732e00000060448201526064016109d1565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af11580156121c0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198e9190614625565b6121ec6126c6565b6001600160a01b0381166122685760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109d1565b6113cd816127c7565b6122796126c6565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806108c357506108c382612fd6565b6000818152600260205260409020546001600160a01b03166113cd5760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109d1565b60005b60135460135460145481612356576123566140f8565b0402601260006013546014548161236f5761236f6140f8565b068152602001908152602001600020540190506016600082815260200190815260200160002054600014156123cc576123a78161269f565b6000828152601660205260409020556123c03382613071565b60148054600101905550565b601480546001019055612340565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061240f82611500565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061245483611500565b9050806001600160a01b0316846001600160a01b0316148061249b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806124bf5750836001600160a01b03166124b48461095b565b6001600160a01b0316145b949350505050565b826001600160a01b03166124da82611500565b6001600160a01b0316146125565760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016109d1565b6001600160a01b0382166125d15760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109d1565b6125dc83838361308b565b6125e76000826123da565b6001600160a01b038316600090815260036020526040812080546001929061261090849061406a565b90915550506001600160a01b038216600090815260036020526040812080546001929061263e90849061403c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006126bc6006830660010160fa026126b760085490565b612849565b6102260192915050565b600b546001600160a01b031633146116bc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d1565b600061272b82611500565b90506127398160008461308b565b6127446000836123da565b6001600160a01b038116600090815260036020526040812080546001929061276d90849061406a565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008181526012602052604081205415612840575060009081526012602052604090205490565b5090565b919050565b604080514260208201529081018390526060810182905260009083906080016040516020818303038152906040528051906020012060001c61288b9190614642565b9392505050565b816001600160a01b0316836001600160a01b031614156128f45760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109d1565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61296c8484846124c7565b612978848484846130d8565b61198e5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b6040805180820190915260008082526020820152815183511015612a045750816108c3565b6020808301519084015160019114612a2b5750815160208481015190840151829020919020145b8015612a5c57825184518590612a4290839061406a565b9052508251602085018051612a5890839061403c565b9052505b509192915050565b606081612aa457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612ace5780612ab881614122565b9150612ac79050600a8361410e565b9150612aa8565b60008167ffffffffffffffff811115612ae957612ae9613e3f565b6040519080825280601f01601f191660200182016040528015612b13576020820181803683370190505b5090505b84156124bf57612b2860018361406a565b9150612b35600a86614642565b612b4090603061403c565b60f81b818381518110612b5557612b55614054565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612b8f600a8661410e565b9450612b17565b60606000826000015167ffffffffffffffff811115612bb757612bb7613e3f565b6040519080825280601f01601f191660200182016040528015612be1576020820181803683370190505b5090506000602082019050612bff8185602001518660000151613221565b5092915050565b6000808260000151612c2a856000015186602001518660000151876020015161329b565b612c34919061403c565b90505b83516020850151612c48919061403c565b8111612bff5781612c5881614122565b9250508260000151612c8f856020015183612c73919061406a565b8651612c7f919061406a565b838660000151876020015161329b565b612c99919061403c565b9050612c37565b6040805180820190915260008082526020820152612bff8383836133bc565b604080518082018252600080825260209182015281518083019092528251825280830190820152606090612d28906040518060400160405280600181526020017f6f00000000000000000000000000000000000000000000000000000000000000815250613468565b9050805160001415612d9d57604080518082018252600080825260209182015281518083019092528351825280840190820152612d9a906040518060400160405280600181526020017f6100000000000000000000000000000000000000000000000000000000000000815250613468565b90505b8051612e0c57604080518082018252600080825260209182015281518083019092528351825280840190820152612e09906040518060400160405280600181526020017f6500000000000000000000000000000000000000000000000000000000000000815250613468565b90505b80516128445781604051602001612e239190614656565b6040516020818303038152906040529050919050565b805160609080612e59575050604080516020810190915260008152919050565b60006003612e6883600261403c565b612e72919061410e565b612e7d906004614369565b90506000612e8c82602061403c565b67ffffffffffffffff811115612ea457612ea4613e3f565b6040519080825280601f01601f191660200182016040528015612ece576020820181803683370190505b509050600060405180606001604052806040815260200161493b604091399050600181016020830160005b86811015612f5a576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612ef9565b506003860660018114612f745760028114612fa057612fc8565b7f3d3d000000000000000000000000000000000000000000000000000000000000600119830152612fc8565b7f3d000000000000000000000000000000000000000000000000000000000000006000198301525b505050918152949350505050565b60006001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000148061303957506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806108c357507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146108c3565b6113398282604051806020016040528060008152506135a0565b61309683838361361e565b6015546000828152601660205260409020541015610cf357600081815260166020526040902080546103e8601490930660320261047e01029190910490555050565b60006001600160a01b0384163b1561321657604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061311c903390899088908890600401614697565b6020604051808303816000875af1925050508015613157575060408051601f3d908101601f19168201909252613154918101906146d3565b60015b6131fc573d808015613185576040519150601f19603f3d011682016040523d82523d6000602084013e61318a565b606091505b5080516131f45760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506124bf565b506001949350505050565b60208110613259578151835261323860208461403c565b925061324560208361403c565b915061325260208261406a565b9050613221565b600019811561328857600161326f83602061406a565b61327b906101006147d4565b613285919061406a565b90505b9151835183169219169190911790915250565b600083818685116133a7576020851161335557600085156132e75760016132c387602061406a565b6132ce906008614369565b6132d99060026147d4565b6132e3919061406a565b1990505b845181166000876132f88b8b61403c565b613302919061406a565b855190915083165b8281146133475781861061332f576133228b8b61403c565b96505050505050506124bf565b8561333981614122565b96505083865116905061330a565b8596505050505050506124bf565b508383206000905b613367868961406a565b82116133a5578583208181141561338457839450505050506124bf565b61338f60018561403c565b935050818061339d90614122565b92505061335d565b505b6133b1878761403c565b979650505050505050565b604080518082019091526000808252602082015260006133ee856000015186602001518660000151876020015161329b565b60208087018051918601919091525190915061340a908261406a565b83528451602086015161341d919061403c565b81141561342d576000855261345f565b8351835161343b919061403c565b8551869061344a90839061406a565b9052508351613459908261403c565b60208601525b50909392505050565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061349d9084906136d6565b156134fa576134f76134ae84612b96565b83846040516020016134c2939291906147e0565b60408051601f198184030181528282018252600080845260209384015281518083019092528051825282019181019190915290565b92505b60006135376135308460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b8590612ca0565b9050600061354485613738565b11156135895761355381612b96565b83848561355f88612b96565b604051602001613573959493929190614823565b6040516020818303038152906040529150612bff565b505060408051602081019091526000815292915050565b6135aa8383613811565b6135b760008484846130d8565b610cf35760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016109d1565b6001600160a01b0383166136795761367481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61369c565b816001600160a01b0316836001600160a01b03161461369c5761369c838261395f565b6001600160a01b0382166136b357610cf3816139fc565b826001600160a01b0316826001600160a01b031614610cf357610cf38282613aab565b8051825160009111156136eb575060006108c3565b815183516020850151600092916137019161403c565b61370b919061406a565b905082602001518114156137235760019150506108c3565b82516020840151819020912014905092915050565b600080601f836020015161374c919061406a565b835190915060009061375e908361403c565b9050600092505b8082101561380a57815160ff16608081101561378d5761378660018461403c565b92506137f7565b60e08160ff1610156137a45761378660028461403c565b60f08160ff1610156137bb5761378660038461403c565b60f88160ff1610156137d25761378660048461403c565b60fc8160ff1610156137e95761378660058461403c565b6137f460068461403c565b92505b508261380281614122565b935050613765565b5050919050565b6001600160a01b0382166138675760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109d1565b6000818152600260205260409020546001600160a01b0316156138cc5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109d1565b6138d86000838361308b565b6001600160a01b038216600090815260036020526040812080546001929061390190849061403c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161396c84611610565b613976919061406a565b6000838152600760205260409020549091508082146139c9576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613a0e9060019061406a565b60008381526009602052604081205460088054939450909284908110613a3657613a36614054565b906000526020600020015490508060088381548110613a5757613a57614054565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613a8f57613a8f61488e565b6001900381819060005260206000200160009055905550505050565b6000613ab683611610565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054613afb90613feb565b90600052602060002090601f016020900481019282613b1d5760008555613b63565b82601f10613b365782800160ff19823516178555613b63565b82800160010185558215613b63579182015b82811115613b63578235825591602001919060010190613b48565b50612840929150613b96565b6040518060e001604052806007905b6060815260200190600190039081613b7e5790505090565b5b808211156128405760008155600101613b97565b6001600160e01b0319811681146113cd57600080fd5b600060208284031215613bd357600080fd5b813561288b81613bab565b60005b83811015613bf9578181015183820152602001613be1565b8381111561198e5750506000910152565b60008151808452613c22816020860160208601613bde565b601f01601f19169290920160200192915050565b60208152600061288b6020830184613c0a565b600060208284031215613c5b57600080fd5b5035919050565b6001600160a01b03811681146113cd57600080fd5b60008060408385031215613c8a57600080fd5b8235613c9581613c62565b946020939093013593505050565b600080600060608486031215613cb857600080fd5b8335613cc381613c62565b92506020840135613cd381613c62565b929592945050506040919091013590565b80151581146113cd57600080fd5b600060208284031215613d0457600080fd5b813561288b81613ce4565b60008060408385031215613d2257600080fd5b8235613d2d81613ce4565b91506020830135613d3d81613ce4565b809150509250929050565b600060208284031215613d5a57600080fd5b813561288b81613c62565b60008060208385031215613d7857600080fd5b823567ffffffffffffffff80821115613d9057600080fd5b818501915085601f830112613da457600080fd5b813581811115613db357600080fd5b8660208260051b8501011115613dc857600080fd5b60209290920196919550909350505050565b60008060408385031215613ded57600080fd5b823591506020830135613d3d81613ce4565b60008060408385031215613e1257600080fd5b8235613d2d81613c62565b60008060408385031215613e3057600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613e7e57613e7e613e3f565b604052919050565b600067ffffffffffffffff821115613ea057613ea0613e3f565b50601f01601f191660200190565b60008060008060808587031215613ec457600080fd5b8435613ecf81613c62565b93506020850135613edf81613c62565b925060408501359150606085013567ffffffffffffffff811115613f0257600080fd5b8501601f81018713613f1357600080fd5b8035613f26613f2182613e86565b613e55565b818152886020838501011115613f3b57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060208385031215613f7057600080fd5b823567ffffffffffffffff80821115613f8857600080fd5b818501915085601f830112613f9c57600080fd5b813581811115613fab57600080fd5b866020828501011115613dc857600080fd5b60008060408385031215613fd057600080fd5b8235613fdb81613c62565b91506020830135613d3d81613c62565b600181811c90821680613fff57607f821691505b6020821081141561402057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561404f5761404f614026565b500190565b634e487b7160e01b600052603260045260246000fd5b60008282101561407c5761407c614026565b500390565b60006020828403121561409357600080fd5b815167ffffffffffffffff8111156140aa57600080fd5b8201601f810184136140bb57600080fd5b80516140c9613f2182613e86565b8181528560208385010111156140de57600080fd5b6140ef826020830160208601613bde565b95945050505050565b634e487b7160e01b600052601260045260246000fd5b60008261411d5761411d6140f8565b500490565b600060001982141561413657614136614026565b5060010190565b6000815161414f818560208601613bde565b9290920192915050565b60008851602061416c8285838e01613bde565b89519184019161417f8184848e01613bde565b89519201916141918184848d01613bde565b88519201916141a38184848c01613bde565b87519201916141b58184848b01613bde565b86519201916141c78184848a01613bde565b85519201916141d98184848901613bde565b919091019a9950505050505050505050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2081527f22547979797065222c2276616c7565223a202200000000000000000000000000602082015260008251614249816033850160208701613bde565b61227d60f01b6033939091019283015250603501919050565b60008351614274818460208801613bde565b6142b08184017f2c7b2274726169745f74797065223a202253747575756666222c2276616c7565815263111d101160e11b602082015260240190565b905083516142c2818360208801613bde565b61227d60f01b9101908152600201949350505050565b600083516142ea818460208801613bde565b6143268184017f2c7b2274726169745f74797065223a202253747575756666222c2276616c7565815263111d101160e11b602082015260240190565b90508351614338818360208801613bde565b7f2054696e6773227d0000000000000000000000000000000000000000000000009101908152600801949350505050565b600081600019048311821515161561438357614383614026565b500290565b6000825161439a818460208701613bde565b606960f81b920191825250600101919050565b600083516143bf818460208801613bde565b80830190507f2c7b2274726169745f74797065223a2022546161616c6c222c2276616c75652281527f3a2022487400000000000000000000000000000000000000000000000000000060208201528351614420816025840160208801613bde565b7f6465227d0000000000000000000000000000000000000000000000000000000060259290910191820152602901949350505050565b7f7b226e616d65223a2022546161616c6c20230000000000000000000000000000815260008551602061448f8260128601838b01613bde565b8651918401916144a58160128501848b01613bde565b7f5d2c20226465736372697074696f6e223a202200000000000000000000000000601293909101928301528554602590600090600181811c90808316806144ed57607f831692505b86831081141561450b57634e487b7160e01b85526022600452602485fd5b80801561451f576001811461453457614565565b60ff1985168988015283890187019550614565565b60008d81526020902060005b8581101561455b5781548b82018a0152908401908901614540565b505086848a010195505b50507f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b845250507f6261736536342c000000000000000000000000000000000000000000000000006020830152506145c0602782018861413d565b93505050506145d38161227d60f01b9052565b6002019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161461881601d850160208701613bde565b91909101601d0192915050565b60006020828403121561463757600080fd5b815161288b81613ce4565b600082614651576146516140f8565b500690565b60008251614668818460208701613bde565b7f5252520000000000000000000000000000000000000000000000000000000000920191825250600301919050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526146c96080830184613c0a565b9695505050505050565b6000602082840312156146e557600080fd5b815161288b81613bab565b600181815b8085111561472b57816000190482111561471157614711614026565b8085161561471e57918102915b93841c93908002906146f5565b509250929050565b600082614742575060016108c3565b8161474f575060006108c3565b8160018114614765576002811461476f5761478b565b60019150506108c3565b60ff84111561478057614780614026565b50506001821b6108c3565b5060208310610133831016604e8410600b84101617156147ae575081810a6108c3565b6147b883836146f0565b80600019048211156147cc576147cc614026565b029392505050565b600061288b8383614733565b600084516147f2818460208901613bde565b845190830190614806818360208901613bde565b8451910190614819818360208801613bde565b0195945050505050565b60008651614835818460208b01613bde565b865190830190614849818360208b01613bde565b865191019061485c818360208a01613bde565b855191019061486f818360208901613bde565b8451910190614882818360208801613bde565b01979650505050505050565b634e487b7160e01b600052603160045260246000fdfe3c7376672077696474683d2235303022206865696768743d223530302220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d226e6f6e65223e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2223366138343934222f3e3c73766720793d222d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222077696474683d223130302522207072657365727665417370656374526174696f3d226e6f6e652220a2646970667358221220fd89e0faa34deceba58a571b1f54f8c18b7726df59c8cb32d9ff1ef06691c71064736f6c634300080c0033

Deployed Bytecode Sourcemap

86384:15120:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101268:229;;;;;;;;;;-1:-1:-1;101268:229:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;101268:229:0;;;;;;;;61581:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;63094:171::-;;;;;;;;;;-1:-1:-1;63094:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1760:55:1;;;1742:74;;1730:2;1715:18;63094:171:0;1596:226:1;89085:638:0;;;:::i;:::-;;62611:417;;;;;;;;;;-1:-1:-1;62611:417:0;;;;;:::i;:::-;;:::i;88657:402::-;;;;;;;;;;;;;:::i;76275:113::-;;;;;;;;;;-1:-1:-1;76363:10:0;:17;76275:113;;;2452:25:1;;;2440:2;2425:18;76275:113:0;2306:177:1;63794:336:0;;;;;;;;;;-1:-1:-1;63794:336:0;;;;;:::i;:::-;;:::i;87039:30::-;;;;;;;;;;-1:-1:-1;87039:30:0;;;;-1:-1:-1;;;87039:30:0;;;;;;75943:256;;;;;;;;;;-1:-1:-1;75943:256:0;;;;;:::i;:::-;;:::i;90617:209::-;;;;;;;;;;-1:-1:-1;90617:209:0;;;;;:::i;:::-;;:::i;87335:46::-;;;;;;;;;;-1:-1:-1;87335:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;89747:649;;;:::i;96277:361::-;;;;;;;;;;-1:-1:-1;96277:361:0;;;;;:::i;:::-;;:::i;64201:185::-;;;;;;;;;;-1:-1:-1;64201:185:0;;;;;:::i;:::-;;:::i;74374:243::-;;;;;;;;;;-1:-1:-1;74374:243:0;;;;;:::i;:::-;;:::i;100099:77::-;;;;;;;;;;-1:-1:-1;100099:77:0;;;;;:::i;:::-;;:::i;76465:233::-;;;;;;;;;;-1:-1:-1;76465:233:0;;;;;:::i;:::-;;:::i;99618:159::-;;;;;;;;;;-1:-1:-1;99618:159:0;;;;;:::i;:::-;;:::i;87431:18::-;;;;;;;;;;-1:-1:-1;87431:18:0;;;;;;;;61292:222;;;;;;;;;;-1:-1:-1;61292:222:0;;;;;:::i;:::-;;:::i;99804:185::-;;;;;;;;;;;;;:::i;61023:207::-;;;;;;;;;;-1:-1:-1;61023:207:0;;;;;:::i;:::-;;:::i;40110:103::-;;;;;;;;;;;;;:::i;99283:92::-;;;;;;;;;;-1:-1:-1;99283:92:0;;;;;:::i;:::-;;:::i;98830:188::-;;;;;;;;;;-1:-1:-1;98830:188:0;;;;;:::i;:::-;;:::i;39462:87::-;;;;;;;;;;-1:-1:-1;39535:6:0;;-1:-1:-1;;;;;39535:6:0;39462:87;;99997:94;;;;;;;;;;-1:-1:-1;99997:94:0;;;;;:::i;:::-;;:::i;98112:683::-;;;;;;;;;;-1:-1:-1;98112:683:0;;;;;:::i;:::-;;:::i;61750:104::-;;;;;;;;;;;;;:::i;63337:155::-;;;;;;;;;;-1:-1:-1;63337:155:0;;;;;:::i;:::-;;:::i;96670:412::-;;;;;;;;;;-1:-1:-1;96670:412:0;;;;;:::i;:::-;;:::i;86895:46::-;;;;;;;;;;;;;;;;64457:323;;;;;;;;;;-1:-1:-1;64457:323:0;;;;;:::i;:::-;;:::i;99087:98::-;;;;;;;;;;-1:-1:-1;99087:98:0;;;;;:::i;:::-;;:::i;86830:44::-;;;;;;;;;;;;;;;;92125:3645;;;;;;;;;;-1:-1:-1;92125:3645:0;;;;;:::i;:::-;;:::i;100184:106::-;;;;;;;;;;-1:-1:-1;100184:106:0;;;;;:::i;:::-;;:::i;100361:257::-;;;;;;;;;;-1:-1:-1;100361:257:0;;;;;:::i;:::-;;:::i;87076:31::-;;;;;;;;;;-1:-1:-1;87076:31:0;;;;-1:-1:-1;;;87076:31:0;;;;;;87116:40;;;;;;;;;;;;87152:4;87116:40;;87388:36;;;;;;;;;;-1:-1:-1;87388:36:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;63563:164;;;;;;;;;;-1:-1:-1;63563:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;63684:25:0;;;63660:4;63684:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;63563:164;86967:40;;;;;;;;;;-1:-1:-1;86967:40:0;;;;-1:-1:-1;;;;;86967:40:0;;;40368:201;;;;;;;;;;-1:-1:-1;40368:201:0;;;;;:::i;:::-;;:::i;99412:160::-;;;;;;;;;;-1:-1:-1;99412:160:0;;;;;:::i;:::-;;:::i;101268:229::-;101424:4;101453:36;101477:11;101453:23;:36::i;:::-;101446:43;101268:229;-1:-1:-1;;101268:229:0:o;61581:100::-;61635:13;61668:5;61661:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61581:100;:::o;63094:171::-;63170:7;63190:23;63205:7;63190:14;:23::i;:::-;-1:-1:-1;63233:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;63233:24:0;;63094:171::o;89085:638::-;33890:1;34488:7;;:19;;34480:63;;;;-1:-1:-1;;;34480:63:0;;9822:2:1;34480:63:0;;;9804:21:1;9861:2;9841:18;;;9834:30;9900:33;9880:18;;;9873:61;9951:18;;34480:63:0;;;;;;;;;33890:1;34621:7;:18;87518:9:::1;87531:10;87518:23;87510:66;;;::::0;-1:-1:-1;;;87510:66:0;;10182:2:1;87510:66:0::1;::::0;::::1;10164:21:1::0;10221:2;10201:18;;;10194:30;10260:32;10240:18;;;10233:60;10310:18;;87510:66:0::1;9980:354:1::0;87510:66:0::1;89210:2:::2;89181:21;89191:10;89181:9;:21::i;:::-;:25;::::0;89205:1:::2;89181:25;:::i;:::-;:31;;89159:97;;;::::0;-1:-1:-1;;;89159:97:0;;10863:2:1;89159:97:0::2;::::0;::::2;10845:21:1::0;10902:2;10882:18;;;10875:30;10941:18;10921;;;10914:46;10977:18;;89159:97:0::2;10661:340:1::0;89159:97:0::2;89302:15;;89289:9;:28;;89267:94;;;::::0;-1:-1:-1;;;89267:94:0;;11208:2:1;89267:94:0::2;::::0;::::2;11190:21:1::0;11247:2;11227:18;;;11220:30;11286:18;11266;;;11259:46;11322:18;;89267:94:0::2;11006:340:1::0;89267:94:0::2;89394:10;::::0;-1:-1:-1;;;89394:10:0;::::2;;;89372:76;;;::::0;-1:-1:-1;;;89372:76:0;;11553:2:1;89372:76:0::2;::::0;::::2;11535:21:1::0;11592:2;11572:18;;;11565:30;-1:-1:-1;;;11611:18:1;;;11604:45;11666:18;;89372:76:0::2;11351:339:1::0;89372:76:0::2;87152:4;89481:13;76363:10:::0;:17;;76275:113;89481:13:::2;:17;::::0;89497:1:::2;89481:17;:::i;:::-;:30;;89459:117;;;::::0;-1:-1:-1;;;89459:117:0;;11897:2:1;89459:117:0::2;::::0;::::2;11879:21:1::0;11936:2;11916:18;;;11909:30;11975:34;11955:18;;;11948:62;-1:-1:-1;;;12026:18:1;;;12019:35;12071:19;;89459:117:0::2;11695:401:1::0;89459:117:0::2;89587:9;89607:109;89618:1;89614;:5;89607:109;;;89636:7;:5;:7::i;:::-;89686:3;;89607:109;;;-1:-1:-1::0;33846:1:0;34800:7;:22;89085:638::o;62611:417::-;62692:13;62708:23;62723:7;62708:14;:23::i;:::-;62692:39;;62756:5;-1:-1:-1;;;;;62750:11:0;:2;-1:-1:-1;;;;;62750:11:0;;;62742:57;;;;-1:-1:-1;;;62742:57:0;;12303:2:1;62742:57:0;;;12285:21:1;12342:2;12322:18;;;12315:30;12381:34;12361:18;;;12354:62;12452:3;12432:18;;;12425:31;12473:19;;62742:57:0;12101:397:1;62742:57:0;38093:10;-1:-1:-1;;;;;62834:21:0;;;;:62;;-1:-1:-1;62859:37:0;62876:5;38093:10;63563:164;:::i;62859:37::-;62812:174;;;;-1:-1:-1;;;62812:174:0;;12705:2:1;62812:174:0;;;12687:21:1;12744:2;12724:18;;;12717:30;12783:34;12763:18;;;12756:62;12854:32;12834:18;;;12827:60;12904:19;;62812:174:0;12503:426:1;62812:174:0;62999:21;63008:2;63012:7;62999:8;:21::i;:::-;62681:347;62611:417;;:::o;88657:402::-;33890:1;34488:7;;:19;;34480:63;;;;-1:-1:-1;;;34480:63:0;;9822:2:1;34480:63:0;;;9804:21:1;9861:2;9841:18;;;9834:30;9900:33;9880:18;;;9873:61;9951:18;;34480:63:0;9620:355:1;34480:63:0;33890:1;34621:7;:18;87518:9:::1;87531:10;87518:23;87510:66;;;::::0;-1:-1:-1;;;87510:66:0;;10182:2:1;87510:66:0::1;::::0;::::1;10164:21:1::0;10221:2;10201:18;;;10194:30;10260:32;10240:18;;;10233:60;10310:18;;87510:66:0::1;9980:354:1::0;87510:66:0::1;88742:10:::2;::::0;-1:-1:-1;;;88742:10:0;::::2;;;88720:76;;;::::0;-1:-1:-1;;;88720:76:0;;11553:2:1;88720:76:0::2;::::0;::::2;11535:21:1::0;11592:2;11572:18;;;11565:30;-1:-1:-1;;;11611:18:1;;;11604:45;11666:18;;88720:76:0::2;11351:339:1::0;88720:76:0::2;88858:1;88829:21;88839:10;88829:9;:21::i;:::-;:25;::::0;88853:1:::2;88829:25;:::i;:::-;:30;;88807:98;;;::::0;-1:-1:-1;;;88807:98:0;;13136:2:1;88807:98:0::2;::::0;::::2;13118:21:1::0;13175:2;13155:18;;;13148:30;13214:20;13194:18;;;13187:48;13252:18;;88807:98:0::2;12934:342:1::0;88807:98:0::2;87152:4;88938:13;76363:10:::0;:17;;76275:113;88938:13:::2;:17;::::0;88954:1:::2;88938:17;:::i;:::-;:30;;88916:117;;;::::0;-1:-1:-1;;;88916:117:0;;11897:2:1;88916:117:0::2;::::0;::::2;11879:21:1::0;11936:2;11916:18;;;11909:30;11975:34;11955:18;;;11948:62;-1:-1:-1;;;12026:18:1;;;12019:35;12071:19;;88916:117:0::2;11695:401:1::0;88916:117:0::2;89044:7;:5;:7::i;:::-;33846:1:::0;34800:7;:22;88657:402::o;63794:336::-;63989:41;38093:10;64008:12;64022:7;63989:18;:41::i;:::-;63981:100;;;;-1:-1:-1;;;63981:100:0;;13483:2:1;63981:100:0;;;13465:21:1;13522:2;13502:18;;;13495:30;13561:34;13541:18;;;13534:62;-1:-1:-1;;;13612:18:1;;;13605:44;13666:19;;63981:100:0;13281:410:1;63981:100:0;64094:28;64104:4;64110:2;64114:7;64094:9;:28::i;75943:256::-;76040:7;76076:23;76093:5;76076:16;:23::i;:::-;76068:5;:31;76060:87;;;;-1:-1:-1;;;76060:87:0;;13898:2:1;76060:87:0;;;13880:21:1;13937:2;13917:18;;;13910:30;13976:34;13956:18;;;13949:62;14047:13;14027:18;;;14020:41;14078:19;;76060:87:0;13696:407:1;76060:87:0;-1:-1:-1;;;;;;76165:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;75943:256::o;90617:209::-;90718:10;90703:11;90711:2;90703:7;:11::i;:::-;-1:-1:-1;;;;;90703:25:0;;90681:94;;;;-1:-1:-1;;;90681:94:0;;14310:2:1;90681:94:0;;;14292:21:1;14349:2;14329:18;;;14322:30;14388:17;14368:18;;;14361:45;14423:18;;90681:94:0;14108:339:1;90681:94:0;90804:14;90815:2;90804:10;:14::i;:::-;90786:15;;;;:11;:15;;;;;;:32;90617:209::o;89747:649::-;33890:1;34488:7;;:19;;34480:63;;;;-1:-1:-1;;;34480:63:0;;9822:2:1;34480:63:0;;;9804:21:1;9861:2;9841:18;;;9834:30;9900:33;9880:18;;;9873:61;9951:18;;34480:63:0;9620:355:1;34480:63:0;33890:1;34621:7;:18;87518:9:::1;87531:10;87518:23;87510:66;;;::::0;-1:-1:-1;;;87510:66:0;;10182:2:1;87510:66:0::1;::::0;::::1;10164:21:1::0;10221:2;10201:18;;;10194:30;10260:32;10240:18;;;10233:60;10310:18;;87510:66:0::1;9980:354:1::0;87510:66:0::1;89878:2:::2;89848:21;89858:10;89848:9;:21::i;:::-;:26;::::0;89872:2:::2;89848:26;:::i;:::-;:32;;89826:98;;;::::0;-1:-1:-1;;;89826:98:0;;10863:2:1;89826:98:0::2;::::0;::::2;10845:21:1::0;10902:2;10882:18;;;10875:30;10941:18;10921;;;10914:46;10977:18;;89826:98:0::2;10661:340:1::0;89826:98:0::2;89970:18;;89957:9;:31;;89935:97;;;::::0;-1:-1:-1;;;89935:97:0;;11208:2:1;89935:97:0::2;::::0;::::2;11190:21:1::0;11247:2;11227:18;;;11220:30;11286:18;11266;;;11259:46;11322:18;;89935:97:0::2;11006:340:1::0;89935:97:0::2;90065:10;::::0;-1:-1:-1;;;90065:10:0;::::2;;;90043:76;;;::::0;-1:-1:-1;;;90043:76:0;;11553:2:1;90043:76:0::2;::::0;::::2;11535:21:1::0;11592:2;11572:18;;;11565:30;-1:-1:-1;;;11611:18:1;;;11604:45;11666:18;;90043:76:0::2;11351:339:1::0;90043:76:0::2;87152:4;90152:13;76363:10:::0;:17;;76275:113;90152:13:::2;:18;::::0;90168:2:::2;90152:18;:::i;:::-;:31;;90130:118;;;::::0;-1:-1:-1;;;90130:118:0;;11897:2:1;90130:118:0::2;::::0;::::2;11879:21:1::0;11936:2;11916:18;;;11909:30;11975:34;11955:18;;;11948:62;-1:-1:-1;;;12026:18:1;;;12019:35;12071:19;;90130:118:0::2;11695:401:1::0;90130:118:0::2;90259:9;90279:110;90290:2;90286:1;:6;90279:110;;;90309:7;:5;:7::i;:::-;90359:3;;90279:110;;96277:361:::0;39348:13;:11;:13::i;:::-;87152:4:::1;96388:13;96372;76363:10:::0;:17;;76275:113;96372:13:::1;:29;;;;:::i;:::-;:42;;96350:129;;;::::0;-1:-1:-1;;;96350:129:0;;11897:2:1;96350:129:0::1;::::0;::::1;11879:21:1::0;11936:2;11916:18;;;11909:30;11975:34;11955:18;;;11948:62;-1:-1:-1;;;12026:18:1;;;12019:35;12071:19;;96350:129:0::1;11695:401:1::0;96350:129:0::1;96490:9;96510:121;96521:13;96517:1;:17;96510:121;;;96551:7;:5;:7::i;:::-;96601:3;;96510:121;;;96339:299;96277:361:::0;:::o;64201:185::-;64339:39;64356:4;64362:2;64366:7;64339:39;;;;;;;;;;;;:16;:39::i;74374:243::-;74492:41;38093:10;74511:12;38013:98;74492:41;74484:100;;;;-1:-1:-1;;;74484:100:0;;13483:2:1;74484:100:0;;;13465:21:1;13522:2;13502:18;;;13495:30;13561:34;13541:18;;;13534:62;-1:-1:-1;;;13612:18:1;;;13605:44;13666:19;;74484:100:0;13281:410:1;74484:100:0;74595:14;74601:7;74595:5;:14::i;:::-;74374:243;:::o;100099:77::-;39348:13;:11;:13::i;:::-;100158:6:::1;:10:::0;;-1:-1:-1;;100158:10:0::1;::::0;::::1;;::::0;;;::::1;::::0;;100099:77::o;76465:233::-;76540:7;76576:30;76363:10;:17;;76275:113;76576:30;76568:5;:38;76560:95;;;;-1:-1:-1;;;76560:95:0;;14654:2:1;76560:95:0;;;14636:21:1;14693:2;14673:18;;;14666:30;14732:34;14712:18;;;14705:62;14803:14;14783:18;;;14776:42;14835:19;;76560:95:0;14452:408:1;76560:95:0;76673:10;76684:5;76673:17;;;;;;;;:::i;:::-;;;;;;;;;76666:24;;76465:233;;;:::o;99618:159::-;39348:13;:11;:13::i;:::-;99712:10:::1;:22:::0;;99745:24;;-1:-1:-1;;;99712:22:0;::::1;;::::0;;;::::1;99745:24:::0;;;;;;-1:-1:-1;;;99745:24:0;::::1;;::::0;;;::::1;;::::0;;99618:159::o;61292:222::-;61364:7;61400:16;;;:7;:16;;;;;;-1:-1:-1;;;;;61400:16:0;61435:19;61427:56;;;;-1:-1:-1;;;61427:56:0;;15256:2:1;61427:56:0;;;15238:21:1;15295:2;15275:18;;;15268:30;15334:26;15314:18;;;15307:54;15378:18;;61427:56:0;15054:348:1;99804:185:0;39348:13;:11;:13::i;:::-;99879:17:::1;::::0;:55:::1;::::0;99861:12:::1;::::0;-1:-1:-1;;;;;99879:17:0::1;::::0;99908:21:::1;::::0;99861:12;99879:55;99861:12;99879:55;99908:21;99879:17;:55:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99860:74;;;99953:7;99945:36;;;::::0;-1:-1:-1;;;99945:36:0;;15819:2:1;99945:36:0::1;::::0;::::1;15801:21:1::0;15858:2;15838:18;;;15831:30;15897:18;15877;;;15870:46;15933:18;;99945:36:0::1;15617:340:1::0;61023:207:0;61095:7;-1:-1:-1;;;;;61123:19:0;;61115:73;;;;-1:-1:-1;;;61115:73:0;;16164:2:1;61115:73:0;;;16146:21:1;16203:2;16183:18;;;16176:30;16242:34;16222:18;;;16215:62;16313:11;16293:18;;;16286:39;16342:19;;61115:73:0;15962:405:1;61115:73:0;-1:-1:-1;;;;;;61206:16:0;;;;;:9;:16;;;;;;;61023:207::o;40110:103::-;39348:13;:11;:13::i;:::-;40175:30:::1;40202:1;40175:18;:30::i;:::-;40110:103::o:0;99283:92::-;39348:13;:11;:13::i;:::-;99353:8:::1;:14:::0;99283:92::o;98830:188::-;39348:13;:11;:13::i;:::-;98949:4:::1;;98954:1;98949:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;98917:11;:40:::0;;-1:-1:-1;;;;;;98917:40:0::1;-1:-1:-1::0;;;;;98917:40:0;;;::::1;::::0;;;::::1;::::0;;99002:4;;-1:-1:-1;99002:7:0;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;98968:15;:42:::0;;-1:-1:-1;;;;;;98968:42:0::1;-1:-1:-1::0;;;;;98968:42:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;98830:188:0:o;99997:94::-;39348:13;:11;:13::i;:::-;100070:9:::1;::::0;;;:4:::1;:9;::::0;;;;;:13;;-1:-1:-1;;100070:13:0::1;::::0;::::1;;::::0;;;::::1;::::0;;99997:94::o;98112:683::-;39348:13;:11;:13::i;:::-;98214:15:::1;::::0;:20;98192:98:::1;;;::::0;-1:-1:-1;;;98192:98:0;;16574:2:1;98192:98:0::1;::::0;::::1;16556:21:1::0;16613:2;16593:18;;;16586:30;16652;16632:18;;;16625:58;16700:18;;98192:98:0::1;16372:352:1::0;98192:98:0::1;98301:15;:26:::0;;;98338:9:::1;98350:17;98366:1;98319:8:::0;98350:17:::1;:::i;:::-;98338:29;;98378:9;98398::::0;98418::::1;98438:350;98444:5:::0;;98438:350:::1;;98504:13;98515:1;98504:10;:13::i;:::-;98500:17:::0;-1:-1:-1;98573:11:0::1;98578:3;:1:::0;98580::::1;98578:3;:::i;:::-;98582:1;98573:4;:11::i;:::-;98569:15;;98603:13;98614:1;98603:10;:13::i;:::-;98660;::::0;;;:10:::1;:13;::::0;;;;;:17;;;98692:13;;;;;:17;;;-1:-1:-1;;98756:5:0;;;;98599:17;-1:-1:-1;98438:350:0::1;;;98181:614;;;;98112:683:::0;:::o;61750:104::-;61806:13;61839:7;61832:14;;;;;:::i;63337:155::-;63432:52;38093:10;63465:8;63475;63432:18;:52::i;96670:412::-;39348:13;:11;:13::i;:::-;96825:10:::1;96806:16;:29;96784:90;;;::::0;-1:-1:-1;;;96784:90:0;;17061:2:1;96784:90:0::1;::::0;::::1;17043:21:1::0;17100:2;17080:18;;;17073:30;-1:-1:-1;;;17119:18:1;;;17112:41;17170:18;;96784:90:0::1;16859:335:1::0;96784:90:0::1;96929:10;96907:19;:32;96885:93;;;::::0;-1:-1:-1;;;96885:93:0;;17061:2:1;96885:93:0::1;::::0;::::1;17043:21:1::0;17100:2;17080:18;;;17073:30;-1:-1:-1;;;17119:18:1;;;17112:41;17170:18;;96885:93:0::1;16859:335:1::0;96885:93:0::1;96989:15;:34:::0;;;;97034:18:::1;:40:::0;96670:412::o;64457:323::-;64631:41;38093:10;64664:7;64631:18;:41::i;:::-;64623:100;;;;-1:-1:-1;;;64623:100:0;;13483:2:1;64623:100:0;;;13465:21:1;13522:2;13502:18;;;13495:30;13561:34;13541:18;;;13534:62;-1:-1:-1;;;13612:18:1;;;13605:44;13666:19;;64623:100:0;13281:410:1;64623:100:0;64734:38;64748:4;64754:2;64758:7;64767:4;64734:13;:38::i;:::-;64457:323;;;;:::o;99087:98::-;39348:13;:11;:13::i;:::-;99163:14:::1;:4;99170:7:::0;;99163:14:::1;:::i;92125:3645::-:0;92359:6;;92243:13;;92359:6;;92356:70;;;92388:10;;:26;;;;;;;;2452:25:1;;;-1:-1:-1;;;;;92388:10:0;;;;:17;;2425:18:1;;92388:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92388:26:0;;;;;;;;;;;;:::i;92356:70::-;92439:13;;;;:4;:13;;;;;;;;92436:75;;;92475:10;;:24;;;;;;;;2452:25:1;;;-1:-1:-1;;;;;92475:10:0;;;;:15;;2425:18:1;;92475:24:0;2306:177:1;92436:75:0;92571:15;;:45;;;;;18013:6:1;18001:19;;92571:45:0;;;17983:38:1;92547:21:0;;-1:-1:-1;;;;;92571:15:0;;:28;;17956:18:1;;92571:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92571:45:0;;;;;;;;;;;;:::i;:::-;92547:69;;92627:31;92661:17;:7;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;;;;;5759:216;92661:17;92747:38;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;;;;;92627:51;;-1:-1:-1;92730:58:0;;:9;;:16;:58::i;:::-;-1:-1:-1;92858:15:0;92876:20;;;:11;:20;;;;;;92920:8;;92910:18;;92907:67;;;-1:-1:-1;92954:8:0;;92907:67;92986:22;;:::i;:::-;93112:163;;;;;;;;;;;;;;;;;;;93355:33;93386:1;93373:11;93381:3;93373:7;:11;:::i;:::-;93372:15;;;;:::i;:::-;93355:16;:33::i;:::-;93344:8;;;;:44;;;;93399:23;;;;;;;;;;;;;;;;;;;:8;;:23;93480:25;93497:7;93480:16;:25::i;:::-;93469:8;;;;:36;;;;93516:55;;;;;;;;;;;;;93469:8;93516:55;;;:8;;;:55;93627:20;:9;:18;:20::i;:::-;93616:8;;;:31;93658:19;;;;;;;;;;;;;;93616:8;93658:19;;;93616:5;;93658:8;;;:19;93793:15;;:47;;;;;18013:6:1;18001:19;;93793:47:0;;;17983:38:1;93771:19:0;;-1:-1:-1;;;;;93793:15:0;;:30;;17956:18:1;;93793:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;93793:47:0;;;;;;;;;;;;:::i;:::-;93771:69;;93851:31;93885:15;:5;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;;;;;5759:216;93885:15;93957:12;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;;;;93851:49;;-1:-1:-1;5937:30:0;94099:26;93851:49;5937:30;94099:15;:26::i;:::-;:28;;94126:1;94099:28;:::i;:::-;94086:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94058:70;;94145:6;94140:183;94161:9;:16;94157:1;:20;94140:183;;;94243:37;:26;:9;94259;94243:15;:26::i;:::-;:35;:37::i;:::-;94228:9;94238:1;94228:12;;;;;;;;:::i;:::-;;;;;;:52;;;;94179:3;;;;;:::i;:::-;;;;94140:183;;;-1:-1:-1;94381:8:0;;;94391;;;;94401;;;;;94411;;;;94421;;;;94431;;;;94441;;;;94367:83;;94344:20;;94367:83;;94381:8;;94391;94441;94367:83;;:::i;:::-;;;;;;;;;;;;;94344:106;;94461:19;94552:24;94563:9;94573:1;94563:12;;;;;;;;:::i;:::-;;;;;;;94552:10;:24::i;:::-;94483:101;;;;;;;;:::i;:::-;;;;-1:-1:-1;;94483:101:0;;;;;;;;;;-1:-1:-1;94653:1:0;94637:171;94660:9;:16;94656:1;:20;94637:171;;;94719:5;94765:24;94776:9;94786:1;94776:12;;;;;;;;:::i;94765:24::-;94705:91;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94697:99;;94678:3;;;;;:::i;:::-;;;;94637:171;;;;94869:5;94916:36;94950:1;94933:9;:16;:18;;;;:::i;94916:36::-;94855:112;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;94855:112:0;;;;;;95018:11;;;;;;;;;;-1:-1:-1;;;94855:112:0;95018:11;;;94855:112;;-1:-1:-1;94855:112:0;-1:-1:-1;95068:119:0;95083:11;95091:3;95083:7;:11;:::i;:::-;95082:17;;95096:3;95082:17;:::i;:::-;95074:5;:25;95068:119;;;95137:5;95123:25;;;;;;;;:::i;:::-;;;;-1:-1:-1;;95123:25:0;;;;;;;;;;-1:-1:-1;95163:12:0;95172:3;95163:12;;:::i;:::-;;;95068:119;;;95219:5;95266;95205:76;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95197:84;;95356:18;95377:204;95433:25;95450:7;95433:16;:25::i;:::-;95459:5;95495:4;95544:28;95564:6;95544:13;:28::i;:::-;95397:182;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95377:13;:204::i;:::-;95356:225;;95730:4;95680:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;95680:55:0;;;;;;;;;;92125:3645;-1:-1:-1;;;;;;;;;;;;;;92125:3645:0:o;100184:106::-;39348:13;:11;:13::i;:::-;100253:10:::1;:29:::0;;-1:-1:-1;;;;;;100253:29:0::1;-1:-1:-1::0;;;;;100253:29:0;;;::::1;::::0;;;::::1;::::0;;100184:106::o;100361:257::-;39348:13;:11;:13::i;:::-;-1:-1:-1;;;;;100487:26:0;::::1;100465:105;;;::::0;-1:-1:-1;;;100465:105:0;;27971:2:1;100465:105:0::1;::::0;::::1;27953:21:1::0;28010:2;27990:18;;;27983:30;28049:31;28029:18;;;28022:59;28098:18;;100465:105:0::1;27769:353:1::0;100465:105:0::1;100581:29;::::0;;;;-1:-1:-1;;;;;28319:55:1;;;100581:29:0::1;::::0;::::1;28301:74:1::0;28391:18;;;28384:34;;;100581:15:0;::::1;::::0;::::1;::::0;28274:18:1;;100581:29:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;40368:201::-:0;39348:13;:11;:13::i;:::-;-1:-1:-1;;;;;40457:22:0;::::1;40449:73;;;::::0;-1:-1:-1;;;40449:73:0;;28881:2:1;40449:73:0::1;::::0;::::1;28863:21:1::0;28920:2;28900:18;;;28893:30;28959:34;28939:18;;;28932:62;29030:8;29010:18;;;29003:36;29056:19;;40449:73:0::1;28679:402:1::0;40449:73:0::1;40533:28;40552:8;40533:18;:28::i;99412:160::-:0;39348:13;:11;:13::i;:::-;99522:17:::1;:42:::0;;-1:-1:-1;;;;;;99522:42:0::1;-1:-1:-1::0;;;;;99522:42:0;;;::::1;::::0;;;::::1;::::0;;99412:160::o;75635:224::-;75737:4;-1:-1:-1;;;;;;75761:50:0;;75776:35;75761:50;;:90;;;75815:36;75839:11;75815:23;:36::i;71069:135::-;66352:4;66376:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66376:16:0;71143:53;;;;-1:-1:-1;;;71143:53:0;;15256:2:1;71143:53:0;;;15238:21:1;15295:2;15275:18;;;15268:30;15334:26;15314:18;;;15307:54;15378:18;;71143:53:0;15054:348:1;87885:725:0;87922:19;87952:649;88194:15;;88175;;88163:11;;:27;;;;;:::i;:::-;;88162:47;88120:10;:39;88143:15;;88131:11;;:27;;;;;:::i;:::-;;88120:39;;;;;;;;;;;;:89;88106:103;;88242:11;:24;88254:11;88242:24;;;;;;;;;;;;88270:1;88242:29;88239:279;;;88319:23;88330:11;88319:10;:23::i;:::-;88292:24;;;;:11;:24;;;;;:50;88361:34;88371:10;88304:11;88361:9;:34::i;:::-;88446:11;:13;;;;;;74374:243;:::o;88239:279::-;88561:11;:13;;;;;;87952:649;;70348:174;70423:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;70423:29:0;-1:-1:-1;;;;;70423:29:0;;;;;;;;:24;;70477:23;70423:24;70477:14;:23::i;:::-;-1:-1:-1;;;;;70468:46:0;;;;;;;;;;;70348:174;;:::o;66581:264::-;66674:4;66691:13;66707:23;66722:7;66707:14;:23::i;:::-;66691:39;;66760:5;-1:-1:-1;;;;;66749:16:0;:7;-1:-1:-1;;;;;66749:16:0;;:52;;;-1:-1:-1;;;;;;63684:25:0;;;63660:4;63684:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;66769:32;66749:87;;;;66829:7;-1:-1:-1;;;;;66805:31:0;:20;66817:7;66805:11;:20::i;:::-;-1:-1:-1;;;;;66805:31:0;;66749:87;66741:96;66581:264;-1:-1:-1;;;;66581:264:0:o;69604:625::-;69763:4;-1:-1:-1;;;;;69736:31:0;:23;69751:7;69736:14;:23::i;:::-;-1:-1:-1;;;;;69736:31:0;;69728:81;;;;-1:-1:-1;;;69728:81:0;;29288:2:1;69728:81:0;;;29270:21:1;29327:2;29307:18;;;29300:30;29366:34;29346:18;;;29339:62;29437:7;29417:18;;;29410:35;29462:19;;69728:81:0;29086:401:1;69728:81:0;-1:-1:-1;;;;;69828:16:0;;69820:65;;;;-1:-1:-1;;;69820:65:0;;29694:2:1;69820:65:0;;;29676:21:1;29733:2;29713:18;;;29706:30;29772:34;29752:18;;;29745:62;29843:6;29823:18;;;29816:34;29867:19;;69820:65:0;29492:400:1;69820:65:0;69898:39;69919:4;69925:2;69929:7;69898:20;:39::i;:::-;70002:29;70019:1;70023:7;70002:8;:29::i;:::-;-1:-1:-1;;;;;70044:15:0;;;;;;:9;:15;;;;;:20;;70063:1;;70044:15;:20;;70063:1;;70044:20;:::i;:::-;;;;-1:-1:-1;;;;;;;70075:13:0;;;;;;:9;:13;;;;;:18;;70092:1;;70075:13;:18;;70092:1;;70075:18;:::i;:::-;;;;-1:-1:-1;;70104:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;70104:21:0;-1:-1:-1;;;;;70104:21:0;;;;;;;;;70143:27;;70104:16;;70143:27;;;;;;;62681:347;62611:417;;:::o;95809:166::-;95864:7;95914:35;95925:1;95921:3;:5;95928:1;95920:9;95931:3;95919:15;95935:13;76363:10;:17;;76275:113;95935:13;95914:4;:35::i;:::-;95952:3;95914:41;;95809:166;-1:-1:-1;;95809:166:0:o;39627:132::-;39535:6;;-1:-1:-1;;;;;39535:6:0;38093:10;39691:23;39683:68;;;;-1:-1:-1;;;39683:68:0;;30099:2:1;39683:68:0;;;30081:21:1;;;30118:18;;;30111:30;30177:34;30157:18;;;30150:62;30229:18;;39683:68:0;29897:356:1;68847:420:0;68907:13;68923:23;68938:7;68923:14;:23::i;:::-;68907:39;;68959:48;68980:5;68995:1;68999:7;68959:20;:48::i;:::-;69048:29;69065:1;69069:7;69048:8;:29::i;:::-;-1:-1:-1;;;;;69090:16:0;;;;;;:9;:16;;;;;:21;;69110:1;;69090:16;:21;;69110:1;;69090:21;:::i;:::-;;;;-1:-1:-1;;69129:16:0;;;;:7;:16;;;;;;69122:23;;-1:-1:-1;;;;;;69122:23:0;;;69163:36;69137:7;;69129:16;-1:-1:-1;;;;;69163:36:0;;;;;69129:16;;69163:36;96339:299:::1;96277:361:::0;:::o;40729:191::-;40822:6;;;-1:-1:-1;;;;;40839:17:0;;;-1:-1:-1;;;;;;40839:17:0;;;;;;;40872:40;;40822:6;;;40839:17;40822:6;;40872:40;;40803:16;;40872:40;40792:128;40729:191;:::o;97216:373::-;97270:7;97327:15;;;:10;:15;;;;;;:19;97324:258;;-1:-1:-1;97416:15:0;;;;:10;:15;;;;;;;97216:373::o;97324:258::-;-1:-1:-1;97567:3:0;97216:373::o;97324:258::-;97216:373;;;:::o;96064:175::-;96176:47;;;96194:15;96176:47;;;30443:19:1;30478:12;;;30471:28;;;30515:12;;;30508:28;;;96130:7:0;;96228:3;;30552:12:1;;96176:47:0;;;;;;;;;;;;96166:58;;;;;;96158:67;;:73;;;;:::i;:::-;96150:81;96064:175;-1:-1:-1;;;96064:175:0:o;70665:315::-;70820:8;-1:-1:-1;;;;;70811:17:0;:5;-1:-1:-1;;;;;70811:17:0;;;70803:55;;;;-1:-1:-1;;;70803:55:0;;30894:2:1;70803:55:0;;;30876:21:1;30933:2;30913:18;;;30906:30;30972:27;30952:18;;;30945:55;31017:18;;70803:55:0;30692:349:1;70803:55:0;-1:-1:-1;;;;;70869:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;70869:46:0;;;;;;;;;;70931:41;;586::1;;;70931::0;;559:18:1;70931:41:0;;;;;;;70665:315;;;:::o;65661:313::-;65817:28;65827:4;65833:2;65837:7;65817:9;:28::i;:::-;65864:47;65887:4;65893:2;65897:7;65906:4;65864:22;:47::i;:::-;65856:110;;;;-1:-1:-1;;;65856:110:0;;31248:2:1;65856:110:0;;;31230:21:1;31287:2;31267:18;;;31260:30;31326:34;31306:18;;;31299:62;-1:-1:-1;;;31377:18:1;;;31370:48;31435:19;;65856:110:0;31046:414:1;16137:682:0;-1:-1:-1;;;;;;;;;;;;;;;;;16257:11:0;;16245:9;;:23;16241:67;;;-1:-1:-1;16292:4:0;16285:11;;16241:67;16365:11;;;;;16352:9;;;;16333:4;;16352:24;16348:327;;-1:-1:-1;16435:13:0;;16497:4;16487:15;;;16481:22;16544:17;;;16538:24;16620:28;;;16592:26;;;16589:60;16348:327;16691:5;16687:101;;;16726:11;;16713:24;;:4;;:24;;16726:11;;16713:24;:::i;:::-;;;-1:-1:-1;16765:11:0;;16752:9;;;:24;;;;16765:11;;16752:24;:::i;:::-;;;-1:-1:-1;16687:101:0;-1:-1:-1;16807:4:0;;16137:682;-1:-1:-1;;16137:682:0:o;35267:723::-;35323:13;35544:10;35540:53;;-1:-1:-1;;35571:10:0;;;;;;;;;;;;;;;;;;35267:723::o;35540:53::-;35618:5;35603:12;35659:78;35666:9;;35659:78;;35692:8;;;;:::i;:::-;;-1:-1:-1;35715:10:0;;-1:-1:-1;35723:2:0;35715:10;;:::i;:::-;;;35659:78;;;35747:19;35779:6;35769:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35769:17:0;;35747:39;;35797:154;35804:10;;35797:154;;35831:11;35841:1;35831:11;;:::i;:::-;;-1:-1:-1;35900:10:0;35908:2;35900:5;:10;:::i;:::-;35887:24;;:2;:24;:::i;:::-;35874:39;;35857:6;35864;35857:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;35928:11:0;35937:2;35928:11;;:::i;:::-;;;35797:154;;8212:272;8272:13;8298:17;8329:4;:9;;;8318:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8318:21:0;;8298:41;;8350:11;8402:2;8397:3;8393:12;8383:22;;8419:36;8426:6;8434:4;:9;;;8445:4;:9;;;8419:6;:36::i;:::-;-1:-1:-1;8473:3:0;8212:272;-1:-1:-1;;8212:272:0:o;26639:370::-;26717:8;26738;26807:6;:11;;;26749:55;26757:4;:9;;;26768:4;:9;;;26779:6;:11;;;26792:6;:11;;;26749:7;:55::i;:::-;:69;;;;:::i;:::-;26738:80;;26829:173;26855:9;;26843;;;;:21;;26855:9;26843:21;:::i;:::-;26836:3;:28;26829:173;;26881:5;;;;:::i;:::-;;;;26979:6;:11;;;26907:69;26934:4;:9;;;26928:3;:15;;;;:::i;:::-;26915:9;;:29;;;;:::i;:::-;26946:3;26951:6;:11;;;26964:6;:11;;;26907:7;:69::i;:::-;:83;;;;:::i;:::-;26901:89;;26829:173;;24607:143;-1:-1:-1;;;;;;;;;;;;;;;;;24716:26:0;24722:4;24728:6;24736:5;24716;:26::i;91559:530::-;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;91630:20;;91673:43;;;;;;;;;;;;;;;;;;;:14;:43::i;:::-;91664:52;;91738:6;91732:20;91754:1;91732:23;91729:106;;;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;91780:43;;;;;;;;;;;;;;;;;;;:14;:43::i;:::-;91771:52;;91729:106;91848:20;;91845:106;;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;91896:43;;;;;;;;;;;;;;;;;;;:14;:43::i;:::-;91887:52;;91845:106;91964:20;;91961:97;;92026:13;92012:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;92003:43;;91559:530;;;:::o;101853:1503::-;101951:11;;101911:13;;101977:8;101973:23;;-1:-1:-1;;101987:9:0;;;;;;;;;-1:-1:-1;101987:9:0;;;101853:1503;-1:-1:-1;101853:1503:0:o;101973:23::-;102007:18;102045:1;102034:7;:3;102040:1;102034:7;:::i;:::-;102033:13;;;;:::i;:::-;102028:19;;:1;:19;:::i;:::-;102007:40;-1:-1:-1;102058:19:0;102090:15;102007:40;102103:2;102090:15;:::i;:::-;102080:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102080:26:0;;102058:48;;102117:18;102138:5;;;;;;;;;;;;;;;;;102117:26;;102207:1;102200:5;102196:13;102252:2;102244:6;102240:15;102301:1;102269:771;102324:3;102321:1;102318:10;102269:771;;;102379:1;102422:12;;;;;102416:19;102515:4;102503:2;102499:14;;;;;102481:40;;102475:47;102624:2;102620:14;;;102616:25;;102602:40;;102596:47;102753:1;102749:13;;;102745:24;;102731:39;;102725:46;102873:16;;;;102859:31;;102853:38;102551:1;102547:11;;;102645:4;102592:58;;;102583:68;102676:11;;102721:57;;;102712:67;;;;102804:11;;102849:49;;102840:59;102928:3;102924:13;102955:22;;103023:1;103008:17;;;;102372:9;102269:771;;;102273:44;103070:1;103065:3;103061:11;103091:1;103086:84;;;;103189:1;103184:82;;;;103054:212;;103086:84;103138:16;-1:-1:-1;;103119:17:0;;103112:43;103086:84;;103184:82;103236:14;-1:-1:-1;;103217:17:0;;103210:41;103054:212;-1:-1:-1;;;103280:26:0;;;103287:6;101853:1503;-1:-1:-1;;;;101853:1503:0:o;60654:305::-;60756:4;-1:-1:-1;;;;;;60793:40:0;;60808:25;60793:40;;:105;;-1:-1:-1;;;;;;;60850:48:0;;60865:33;60850:48;60793:105;:158;;;-1:-1:-1;52440:25:0;-1:-1:-1;;;;;;52425:40:0;;;60915:36;52316:157;67187:110;67263:26;67273:2;67277:7;67263:26;;;;;;;;;;;;:9;:26::i;100649:611::-;100819:45;100846:4;100852:2;100856:7;100819:26;:45::i;:::-;100901:8;;100878:20;;;;:11;:20;;;;;;:31;100875:377;;;101172:20;;;;:11;:20;;;;;;;101221:4;101206:2;101196:12;;;101210:2;101195:17;101213:4;101195:22;101172:47;101171:54;;;;101147:78;;-1:-1:-1;;100649:611:0:o;71768:853::-;71922:4;-1:-1:-1;;;;;71943:13:0;;42455:19;:23;71939:675;;71979:71;;-1:-1:-1;;;71979:71:0;;-1:-1:-1;;;;;71979:36:0;;;;;:71;;38093:10;;72030:4;;72036:7;;72045:4;;71979:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71979:71:0;;;;;;;;-1:-1:-1;;71979:71:0;;;;;;;;;;;;:::i;:::-;;;71975:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72220:13:0;;72216:328;;72263:60;;-1:-1:-1;;;72263:60:0;;31248:2:1;72263:60:0;;;31230:21:1;31287:2;31267:18;;;31260:30;31326:34;31306:18;;;31299:62;-1:-1:-1;;;31377:18:1;;;31370:48;31435:19;;72263:60:0;31046:414:1;72216:328:0;72494:6;72488:13;72479:6;72475:2;72471:15;72464:38;71975:584;-1:-1:-1;;;;;;72101:51:0;-1:-1:-1;;;72101:51:0;;-1:-1:-1;72094:58:0;;71939:675;-1:-1:-1;72598:4:0;71768:853;;;;;;:::o;4916:636::-;5051:2;5044:3;:9;5038:170;;5122:10;;5109:24;;5162:10;5170:2;5116:4;5162:10;:::i;:::-;;-1:-1:-1;5187:9:0;5194:2;5187:9;;:::i;:::-;;-1:-1:-1;5055:9:0;5062:2;5055:9;;:::i;:::-;;;5038:170;;;-1:-1:-1;;5294:7:0;;5290:68;;5345:1;5333:8;5338:3;5333:2;:8;:::i;:::-;5325:17;;:3;:17;:::i;:::-;:21;;;;:::i;:::-;5318:28;;5290:68;5411:10;;5467:11;;5463:22;;5423:9;;5407:26;5512:21;;;;5499:35;;;-1:-1:-1;4916:636:0:o;18729:1493::-;18828:4;18856:7;18828:4;18899:20;;;18895:1285;;18953:2;18940:9;:15;18936:1233;;18976:12;19011:13;;19007:112;;19096:1;19077:14;19082:9;19077:2;:14;:::i;:::-;19072:20;;:1;:20;:::i;:::-;19066:27;;:1;:27;:::i;:::-;:31;;;;:::i;:::-;19064:34;;-1:-1:-1;19007:112:0;19205:16;;19201:27;;19139:18;19281:9;19261:17;19271:7;19261;:17;:::i;:::-;:29;;;;:::i;:::-;19369:10;;19250:40;;-1:-1:-1;19365:21:0;;19408:233;19426:10;19415:7;:21;19408:233;;19472:3;19465;:10;19461:65;;19509:17;19519:7;19509;:17;:::i;:::-;19502:24;;;;;;;;;;19461:65;19549:5;;;;:::i;:::-;;;;19615:4;19609:3;19603:10;19599:21;19588:32;;19408:233;;;19666:3;19659:10;;;;;;;;;;18936:1233;-1:-1:-1;19810:31:0;;;19760:12;;19863:291;19884:19;19894:9;19884:7;:19;:::i;:::-;19877:3;:26;19863:291;;19997:25;;;20050:16;;;20046:57;;;20100:3;20093:10;;;;;;;;20046:57;20126:8;20133:1;20126:8;;:::i;:::-;;;19912:242;19905:5;;;;;:::i;:::-;;;;19863:291;;;19691:478;18936:1233;20197:17;20207:7;20197;:17;:::i;:::-;20190:24;18729:1493;-1:-1:-1;;;;;;;18729:1493:0:o;23609:516::-;-1:-1:-1;;;;;;;;;;;;;;;;;23732:8:0;23743:55;23751:4;:9;;;23762:4;:9;;;23773:6;:11;;;23786:6;:11;;;23743:7;:55::i;:::-;23822:9;;;;;;23809:10;;;:22;;;;23861:9;23732:66;;-1:-1:-1;23855:15:0;;23732:66;23855:15;:::i;:::-;23842:28;;23904:9;;23892;;;;:21;;23904:9;23892:21;:::i;:::-;23885:3;:28;23881:214;;;23968:1;23956:13;;23881:214;;;24028:11;;24015:10;;:24;;24028:11;24015:24;:::i;:::-;24002:37;;:4;;:37;;;;;:::i;:::-;;;-1:-1:-1;24072:11:0;;24066:17;;:3;:17;:::i;:::-;24054:9;;;:29;23881:214;-1:-1:-1;24112:5:0;;23609:516;-1:-1:-1;;;23609:516:0:o;90928:553::-;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;91028:20;;91063:36;;:10;;:19;:36::i;:::-;91060:139;;;91128:59;91142:21;:10;:19;:21::i;:::-;91165:5;91171;91128:49;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;91128:49:0;;;;;;-1:-1:-1;;;;;;;;;91128:49:0;-1:-1:-1;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;5937:30;;;;;;;;5759:216;91128:59;91115:72;;91060:139;91209:31;91243:33;91260:15;:5;-1:-1:-1;;;;;;;;;;;;;;;;;5937:30:0;;;;;;;;5943:18;;5937:30;;5894:15;;;5937:30;;;;;;;;5759:216;91260:15;91243:10;;:16;:33::i;:::-;91209:67;;91307:1;91290:16;:10;:14;:16::i;:::-;:18;91287:177;;;91347:20;:9;:18;:20::i;:::-;91368:5;91374;91380;91386:21;:10;:19;:21::i;:::-;91333:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;91324:84;;91287:177;;;-1:-1:-1;;91441:11:0;;;;;;;;;-1:-1:-1;91441:11:0;;;90928:553;-1:-1:-1;;90928:553:0:o;67524:319::-;67653:18;67659:2;67663:7;67653:5;:18::i;:::-;67704:53;67735:1;67739:2;67743:7;67752:4;67704:22;:53::i;:::-;67682:153;;;;-1:-1:-1;;;67682:153:0;;31248:2:1;67682:153:0;;;31230:21:1;31287:2;31267:18;;;31260:30;31326:34;31306:18;;;31299:62;-1:-1:-1;;;31377:18:1;;;31370:48;31435:19;;67682:153:0;31046:414:1;77311:589:0;-1:-1:-1;;;;;77517:18:0;;77513:187;;77552:40;77584:7;78727:10;:17;;78700:24;;;;:15;:24;;;;;:44;;;78755:24;;;;;;;;;;;;78623:164;77552:40;77513:187;;;77622:2;-1:-1:-1;;;;;77614:10:0;:4;-1:-1:-1;;;;;77614:10:0;;77610:90;;77641:47;77674:4;77680:7;77641:32;:47::i;:::-;-1:-1:-1;;;;;77714:16:0;;77710:183;;77747:45;77784:7;77747:36;:45::i;77710:183::-;77820:4;-1:-1:-1;;;;;77814:10:0;:2;-1:-1:-1;;;;;77814:10:0;;77810:83;;77841:40;77869:2;77873:7;77841:27;:40::i;17077:572::-;17191:11;;17179:9;;17158:4;;-1:-1:-1;17175:68:0;;;-1:-1:-1;17226:5:0;17219:12;;17175:68;17294:11;;17282:9;;17270;;;;17255:12;;17294:11;17270:21;;;:::i;:::-;:35;;;;:::i;:::-;17255:50;;17333:6;:11;;;17322:7;:22;17318:66;;;17368:4;17361:11;;;;;17318:66;17455:13;;17517:4;17505:17;;17499:24;17577:28;;;17549:26;;17546:60;;-1:-1:-1;17077:572:0;;;;:::o;8885:713::-;8940:6;9035:8;9058:2;9046:4;:9;;;:14;;;;:::i;:::-;9088:9;;9035:25;;-1:-1:-1;9071:8:0;;9082:15;;9035:25;9082:15;:::i;:::-;9071:26;;9117:1;9113:5;;9108:483;9126:3;9120;:9;9108:483;;;9193:10;;9205:4;9189:21;9234:4;9230:8;;9226:354;;;9259:8;9266:1;9259:8;;:::i;:::-;;;9226:354;;;9296:4;9292:1;:8;;;9289:291;;;9321:8;9328:1;9321:8;;:::i;9289:291::-;9358:4;9354:1;:8;;;9351:229;;;9383:8;9390:1;9383:8;;:::i;9351:229::-;9420:4;9416:1;:8;;;9413:167;;;9445:8;9452:1;9445:8;;:::i;9413:167::-;9482:4;9478:1;:8;;;9475:105;;;9507:8;9514:1;9507:8;;:::i;9475:105::-;9556:8;9563:1;9556:8;;:::i;:::-;;;9475:105;-1:-1:-1;9131:3:0;;;;:::i;:::-;;;;9108:483;;;8948:650;;8885:713;;;:::o;68179:439::-;-1:-1:-1;;;;;68259:16:0;;68251:61;;;;-1:-1:-1;;;68251:61:0;;35984:2:1;68251:61:0;;;35966:21:1;;;36003:18;;;35996:30;36062:34;36042:18;;;36035:62;36114:18;;68251:61:0;35782:356:1;68251:61:0;66352:4;66376:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66376:16:0;:30;68323:58;;;;-1:-1:-1;;;68323:58:0;;36345:2:1;68323:58:0;;;36327:21:1;36384:2;36364:18;;;36357:30;36423;36403:18;;;36396:58;36471:18;;68323:58:0;36143:352:1;68323:58:0;68394:45;68423:1;68427:2;68431:7;68394:20;:45::i;:::-;-1:-1:-1;;;;;68452:13:0;;;;;;:9;:13;;;;;:18;;68469:1;;68452:13;:18;;68469:1;;68452:18;:::i;:::-;;;;-1:-1:-1;;68481:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;68481:21:0;-1:-1:-1;;;;;68481:21:0;;;;;;;;68520:33;;68481:16;;;68520:33;;68481:16;;68520:33;96339:299:::1;96277:361:::0;:::o;79414:988::-;79680:22;79730:1;79705:22;79722:4;79705:16;:22::i;:::-;:26;;;;:::i;:::-;79742:18;79763:26;;;:17;:26;;;;;;79680:51;;-1:-1:-1;79896:28:0;;;79892:328;;-1:-1:-1;;;;;79963:18:0;;79941:19;79963:18;;;:12;:18;;;;;;;;:34;;;;;;;;;80014:30;;;;;;:44;;;80131:30;;:17;:30;;;;;:43;;;79892:328;-1:-1:-1;80316:26:0;;;;:17;:26;;;;;;;;80309:33;;;-1:-1:-1;;;;;80360:18:0;;;;;:12;:18;;;;;:34;;;;;;;80353:41;79414:988::o;80697:1079::-;80975:10;:17;80950:22;;80975:21;;80995:1;;80975:21;:::i;:::-;81007:18;81028:24;;;:15;:24;;;;;;81401:10;:26;;80950:46;;-1:-1:-1;81028:24:0;;80950:46;;81401:26;;;;;;:::i;:::-;;;;;;;;;81379:48;;81465:11;81440:10;81451;81440:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;81545:28;;;:15;:28;;;;;;;:41;;;81717:24;;;;;81710:31;81752:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;80768:1008;;;80697:1079;:::o;78201:221::-;78286:14;78303:20;78320:2;78303:16;:20::i;:::-;-1:-1:-1;;;;;78334:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;78379:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;78201:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:177:1;-1:-1:-1;;;;;;92:5:1;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:258::-;710:1;720:113;734:6;731:1;728:13;720:113;;;810:11;;;804:18;791:11;;;784:39;756:2;749:10;720:113;;;851:6;848:1;845:13;842:48;;;-1:-1:-1;;886:1:1;868:16;;861:27;638:258::o;901:269::-;954:3;992:5;986:12;1019:6;1014:3;1007:19;1035:63;1091:6;1084:4;1079:3;1075:14;1068:4;1061:5;1057:16;1035:63;:::i;:::-;1152:2;1131:15;-1:-1:-1;;1127:29:1;1118:39;;;;1159:4;1114:50;;901:269;-1:-1:-1;;901:269:1:o;1175:231::-;1324:2;1313:9;1306:21;1287:4;1344:56;1396:2;1385:9;1381:18;1373:6;1344:56;:::i;1411:180::-;1470:6;1523:2;1511:9;1502:7;1498:23;1494:32;1491:52;;;1539:1;1536;1529:12;1491:52;-1:-1:-1;1562:23:1;;1411:180;-1:-1:-1;1411:180:1:o;1827:154::-;-1:-1:-1;;;;;1906:5:1;1902:54;1895:5;1892:65;1882:93;;1971:1;1968;1961:12;1986:315;2054:6;2062;2115:2;2103:9;2094:7;2090:23;2086:32;2083:52;;;2131:1;2128;2121:12;2083:52;2170:9;2157:23;2189:31;2214:5;2189:31;:::i;:::-;2239:5;2291:2;2276:18;;;;2263:32;;-1:-1:-1;;;1986:315:1:o;2488:456::-;2565:6;2573;2581;2634:2;2622:9;2613:7;2609:23;2605:32;2602:52;;;2650:1;2647;2640:12;2602:52;2689:9;2676:23;2708:31;2733:5;2708:31;:::i;:::-;2758:5;-1:-1:-1;2815:2:1;2800:18;;2787:32;2828:33;2787:32;2828:33;:::i;:::-;2488:456;;2880:7;;-1:-1:-1;;;2934:2:1;2919:18;;;;2906:32;;2488:456::o;2949:118::-;3035:5;3028:13;3021:21;3014:5;3011:32;3001:60;;3057:1;3054;3047:12;3072:241;3128:6;3181:2;3169:9;3160:7;3156:23;3152:32;3149:52;;;3197:1;3194;3187:12;3149:52;3236:9;3223:23;3255:28;3277:5;3255:28;:::i;3318:376::-;3380:6;3388;3441:2;3429:9;3420:7;3416:23;3412:32;3409:52;;;3457:1;3454;3447:12;3409:52;3496:9;3483:23;3515:28;3537:5;3515:28;:::i;:::-;3562:5;-1:-1:-1;3619:2:1;3604:18;;3591:32;3632:30;3591:32;3632:30;:::i;:::-;3681:7;3671:17;;;3318:376;;;;;:::o;3699:247::-;3758:6;3811:2;3799:9;3790:7;3786:23;3782:32;3779:52;;;3827:1;3824;3817:12;3779:52;3866:9;3853:23;3885:31;3910:5;3885:31;:::i;3951:615::-;4037:6;4045;4098:2;4086:9;4077:7;4073:23;4069:32;4066:52;;;4114:1;4111;4104:12;4066:52;4154:9;4141:23;4183:18;4224:2;4216:6;4213:14;4210:34;;;4240:1;4237;4230:12;4210:34;4278:6;4267:9;4263:22;4253:32;;4323:7;4316:4;4312:2;4308:13;4304:27;4294:55;;4345:1;4342;4335:12;4294:55;4385:2;4372:16;4411:2;4403:6;4400:14;4397:34;;;4427:1;4424;4417:12;4397:34;4480:7;4475:2;4465:6;4462:1;4458:14;4454:2;4450:23;4446:32;4443:45;4440:65;;;4501:1;4498;4491:12;4440:65;4532:2;4524:11;;;;;4554:6;;-1:-1:-1;3951:615:1;;-1:-1:-1;;;;3951:615:1:o;4571:309::-;4636:6;4644;4697:2;4685:9;4676:7;4672:23;4668:32;4665:52;;;4713:1;4710;4703:12;4665:52;4749:9;4736:23;4726:33;;4809:2;4798:9;4794:18;4781:32;4822:28;4844:5;4822:28;:::i;4885:382::-;4950:6;4958;5011:2;4999:9;4990:7;4986:23;4982:32;4979:52;;;5027:1;5024;5017:12;4979:52;5066:9;5053:23;5085:31;5110:5;5085:31;:::i;5272:248::-;5340:6;5348;5401:2;5389:9;5380:7;5376:23;5372:32;5369:52;;;5417:1;5414;5407:12;5369:52;-1:-1:-1;;5440:23:1;;;5510:2;5495:18;;;5482:32;;-1:-1:-1;5272:248:1:o;5525:184::-;-1:-1:-1;;;5574:1:1;5567:88;5674:4;5671:1;5664:15;5698:4;5695:1;5688:15;5714:275;5785:2;5779:9;5850:2;5831:13;;-1:-1:-1;;5827:27:1;5815:40;;5885:18;5870:34;;5906:22;;;5867:62;5864:88;;;5932:18;;:::i;:::-;5968:2;5961:22;5714:275;;-1:-1:-1;5714:275:1:o;5994:186::-;6042:4;6075:18;6067:6;6064:30;6061:56;;;6097:18;;:::i;:::-;-1:-1:-1;6163:2:1;6142:15;-1:-1:-1;;6138:29:1;6169:4;6134:40;;5994:186::o;6185:1016::-;6280:6;6288;6296;6304;6357:3;6345:9;6336:7;6332:23;6328:33;6325:53;;;6374:1;6371;6364:12;6325:53;6413:9;6400:23;6432:31;6457:5;6432:31;:::i;:::-;6482:5;-1:-1:-1;6539:2:1;6524:18;;6511:32;6552:33;6511:32;6552:33;:::i;:::-;6604:7;-1:-1:-1;6658:2:1;6643:18;;6630:32;;-1:-1:-1;6713:2:1;6698:18;;6685:32;6740:18;6729:30;;6726:50;;;6772:1;6769;6762:12;6726:50;6795:22;;6848:4;6840:13;;6836:27;-1:-1:-1;6826:55:1;;6877:1;6874;6867:12;6826:55;6913:2;6900:16;6938:48;6954:31;6982:2;6954:31;:::i;:::-;6938:48;:::i;:::-;7009:2;7002:5;6995:17;7049:7;7044:2;7039;7035;7031:11;7027:20;7024:33;7021:53;;;7070:1;7067;7060:12;7021:53;7125:2;7120;7116;7112:11;7107:2;7100:5;7096:14;7083:45;7169:1;7164:2;7159;7152:5;7148:14;7144:23;7137:34;7190:5;7180:15;;;;;6185:1016;;;;;;;:::o;7206:591::-;7276:6;7284;7337:2;7325:9;7316:7;7312:23;7308:32;7305:52;;;7353:1;7350;7343:12;7305:52;7393:9;7380:23;7422:18;7463:2;7455:6;7452:14;7449:34;;;7479:1;7476;7469:12;7449:34;7517:6;7506:9;7502:22;7492:32;;7562:7;7555:4;7551:2;7547:13;7543:27;7533:55;;7584:1;7581;7574:12;7533:55;7624:2;7611:16;7650:2;7642:6;7639:14;7636:34;;;7666:1;7663;7656:12;7636:34;7711:7;7706:2;7697:6;7693:2;7689:15;7685:24;7682:37;7679:57;;;7732:1;7729;7722:12;8278:388;8346:6;8354;8407:2;8395:9;8386:7;8382:23;8378:32;8375:52;;;8423:1;8420;8413:12;8375:52;8462:9;8449:23;8481:31;8506:5;8481:31;:::i;:::-;8531:5;-1:-1:-1;8588:2:1;8573:18;;8560:32;8601:33;8560:32;8601:33;:::i;9178:437::-;9257:1;9253:12;;;;9300;;;9321:61;;9375:4;9367:6;9363:17;9353:27;;9321:61;9428:2;9420:6;9417:14;9397:18;9394:38;9391:218;;;-1:-1:-1;;;9462:1:1;9455:88;9566:4;9563:1;9556:15;9594:4;9591:1;9584:15;9391:218;;9178:437;;;:::o;10339:184::-;-1:-1:-1;;;10388:1:1;10381:88;10488:4;10485:1;10478:15;10512:4;10509:1;10502:15;10528:128;10568:3;10599:1;10595:6;10592:1;10589:13;10586:39;;;10605:18;;:::i;:::-;-1:-1:-1;10641:9:1;;10528:128::o;14865:184::-;-1:-1:-1;;;14914:1:1;14907:88;15014:4;15011:1;15004:15;15038:4;15035:1;15028:15;16729:125;16769:4;16797:1;16794;16791:8;16788:34;;;16802:18;;:::i;:::-;-1:-1:-1;16839:9:1;;16729:125::o;17199:635::-;17279:6;17332:2;17320:9;17311:7;17307:23;17303:32;17300:52;;;17348:1;17345;17338:12;17300:52;17381:9;17375:16;17414:18;17406:6;17403:30;17400:50;;;17446:1;17443;17436:12;17400:50;17469:22;;17522:4;17514:13;;17510:27;-1:-1:-1;17500:55:1;;17551:1;17548;17541:12;17500:55;17580:2;17574:9;17605:48;17621:31;17649:2;17621:31;:::i;17605:48::-;17676:2;17669:5;17662:17;17716:7;17711:2;17706;17702;17698:11;17694:20;17691:33;17688:53;;;17737:1;17734;17727:12;17688:53;17750:54;17801:2;17796;17789:5;17785:14;17780:2;17776;17772:11;17750:54;:::i;:::-;17823:5;17199:635;-1:-1:-1;;;;;17199:635:1:o;18032:184::-;-1:-1:-1;;;18081:1:1;18074:88;18181:4;18178:1;18171:15;18205:4;18202:1;18195:15;18221:120;18261:1;18287;18277:35;;18292:18;;:::i;:::-;-1:-1:-1;18326:9:1;;18221:120::o;18346:135::-;18385:3;-1:-1:-1;;18406:17:1;;18403:43;;;18426:18;;:::i;:::-;-1:-1:-1;18473:1:1;18462:13;;18346:135::o;18486:185::-;18528:3;18566:5;18560:12;18581:52;18626:6;18621:3;18614:4;18607:5;18603:16;18581:52;:::i;:::-;18649:16;;;;;18486:185;-1:-1:-1;;18486:185:1:o;18676:1449::-;19095:3;19133:6;19127:13;19159:4;19172:51;19216:6;19211:3;19206:2;19198:6;19194:15;19172:51;:::i;:::-;19286:13;;19245:16;;;;19308:55;19286:13;19245:16;19330:15;;;19308:55;:::i;:::-;19430:13;;19385:20;;;19452:55;19430:13;19385:20;19474:15;;;19452:55;:::i;:::-;19574:13;;19529:20;;;19596:55;19574:13;19529:20;19618:15;;;19596:55;:::i;:::-;19718:13;;19673:20;;;19740:55;19718:13;19673:20;19762:15;;;19740:55;:::i;:::-;19862:13;;19817:20;;;19884:55;19862:13;19817:20;19906:15;;;19884:55;:::i;:::-;20006:13;;19961:20;;;20028:55;20006:13;19961:20;20050:15;;;20028:55;:::i;:::-;20099:20;;;;;18676:1449;-1:-1:-1;;;;;;;;;;18676:1449:1:o;20278:785::-;20630:66;20625:3;20618:79;20727:66;20722:2;20717:3;20713:12;20706:88;20600:3;20823:6;20817:13;20839:60;20892:6;20887:2;20882:3;20878:12;20873:2;20865:6;20861:15;20839:60;:::i;:::-;-1:-1:-1;;;20958:2:1;20918:16;;;;20950:11;;;20943:87;-1:-1:-1;21054:2:1;21046:11;;20278:785;-1:-1:-1;20278:785:1:o;21348:808::-;21718:3;21756:6;21750:13;21772:53;21818:6;21813:3;21806:4;21798:6;21794:17;21772:53;:::i;:::-;21844:47;21883:6;21878:3;21874:16;21145:66;21133:79;;-1:-1:-1;;;21237:2:1;21228:12;;21221:88;21334:2;21325:12;;21068:275;21844:47;21834:57;;21922:6;21916:13;21938:54;21983:8;21979:2;21972:4;21964:6;21960:17;21938:54;:::i;:::-;-1:-1:-1;;;22014:17:1;;22040:81;;;22148:1;22137:13;;21348:808;-1:-1:-1;;;;21348:808:1:o;22161:::-;22531:3;22569:6;22563:13;22585:53;22631:6;22626:3;22619:4;22611:6;22607:17;22585:53;:::i;:::-;22657:47;22696:6;22691:3;22687:16;21145:66;21133:79;;-1:-1:-1;;;21237:2:1;21228:12;;21221:88;21334:2;21325:12;;21068:275;22657:47;22647:57;;22735:6;22729:13;22751:54;22796:8;22792:2;22785:4;22777:6;22773:17;22751:54;:::i;:::-;22867:66;22827:17;;22853:81;;;22961:1;22950:13;;22161:808;-1:-1:-1;;;;22161:808:1:o;22974:168::-;23014:7;23080:1;23076;23072:6;23068:14;23065:1;23062:21;23057:1;23050:9;23043:17;23039:45;23036:71;;;23087:18;;:::i;:::-;-1:-1:-1;23127:9:1;;22974:168::o;23147:428::-;23368:3;23406:6;23400:13;23422:53;23468:6;23463:3;23456:4;23448:6;23444:17;23422:53;:::i;:::-;-1:-1:-1;;;23497:16:1;;23522:18;;;-1:-1:-1;23567:1:1;23556:13;;23147:428;-1:-1:-1;23147:428:1:o;23580:987::-;23950:3;23988:6;23982:13;24004:53;24050:6;24045:3;24038:4;24030:6;24026:17;24004:53;:::i;:::-;24088:6;24083:3;24079:16;24066:29;;24118:66;24111:5;24104:81;24219:66;24212:4;24205:5;24201:16;24194:92;24317:6;24311:13;24333:66;24390:8;24385:2;24378:5;24374:14;24367:4;24359:6;24355:17;24333:66;:::i;:::-;24467;24462:2;24418:20;;;;24454:11;;;24447:87;24558:2;24550:11;;23580:987;-1:-1:-1;;;;23580:987:1:o;24925:2386::-;25604:66;25599:3;25592:79;25574:3;25700:6;25694:13;25726:4;25739:60;25792:6;25787:2;25782:3;25778:12;25773:2;25765:6;25761:15;25739:60;:::i;:::-;25859:13;;25818:16;;;;25881:61;25859:13;25928:2;25920:11;;25903:15;;;25881:61;:::i;:::-;26007:66;26002:2;25961:17;;;;25994:11;;;25987:87;26142:13;;26093:2;;26115:1;;26202;26224:18;;;;26277;;;;26304:93;;26382:4;26372:8;26368:19;26356:31;;26304:93;26445:2;26435:8;26432:16;26412:18;26409:40;26406:224;;;-1:-1:-1;;;26479:3:1;26472:90;26585:4;26582:1;26575:15;26615:4;26610:3;26603:17;26406:224;26646:18;26673:122;;;;26809:1;26804:344;;;;26639:509;;26673:122;-1:-1:-1;;26714:24:1;;26701:11;;;26694:45;26763:17;;;26759:26;;;-1:-1:-1;26673:122:1;;26804:344;24649:1;24642:14;;;24686:4;24673:18;;26903:1;26917:175;26931:8;26928:1;26925:15;26917:175;;;27019:14;;27002:10;;;26998:19;;26991:43;27062:16;;;;26948:10;;26917:175;;;26921:3;;27135:2;27124:8;27120:2;27116:17;27112:26;27105:33;;26639:509;-1:-1:-1;;24779:66:1;24767:79;;-1:-1:-1;;24876:9:1;24871:2;24862:12;;24855:31;-1:-1:-1;27170:61:1;24911:2;24902:12;;27188:6;27170:61;:::i;:::-;27157:74;;;;;27240:36;27270:5;-1:-1:-1;;;20188:79:1;;20130:143;27240:36;27303:1;27292:13;;24925:2386;-1:-1:-1;;;;;;24925:2386:1:o;27316:448::-;27578:31;27573:3;27566:44;27548:3;27639:6;27633:13;27655:62;27710:6;27705:2;27700:3;27696:12;27689:4;27681:6;27677:17;27655:62;:::i;:::-;27737:16;;;;27755:2;27733:25;;27316:448;-1:-1:-1;;27316:448:1:o;28429:245::-;28496:6;28549:2;28537:9;28528:7;28524:23;28520:32;28517:52;;;28565:1;28562;28555:12;28517:52;28597:9;28591:16;28616:28;28638:5;28616:28;:::i;30575:112::-;30607:1;30633;30623:35;;30638:18;;:::i;:::-;-1:-1:-1;30672:9:1;;30575:112::o;31465:430::-;31686:3;31724:6;31718:13;31740:53;31786:6;31781:3;31774:4;31766:6;31762:17;31740:53;:::i;:::-;31854:5;31815:16;;31840:20;;;-1:-1:-1;31887:1:1;31876:13;;31465:430;-1:-1:-1;31465:430:1:o;31900:523::-;32094:4;-1:-1:-1;;;;;32204:2:1;32196:6;32192:15;32181:9;32174:34;32256:2;32248:6;32244:15;32239:2;32228:9;32224:18;32217:43;;32296:6;32291:2;32280:9;32276:18;32269:34;32339:3;32334:2;32323:9;32319:18;32312:31;32360:57;32412:3;32401:9;32397:19;32389:6;32360:57;:::i;:::-;32352:65;31900:523;-1:-1:-1;;;;;;31900:523:1:o;32428:249::-;32497:6;32550:2;32538:9;32529:7;32525:23;32521:32;32518:52;;;32566:1;32563;32556:12;32518:52;32598:9;32592:16;32617:30;32641:5;32617:30;:::i;32682:422::-;32771:1;32814:5;32771:1;32828:270;32849:7;32839:8;32836:21;32828:270;;;32908:4;32904:1;32900:6;32896:17;32890:4;32887:27;32884:53;;;32917:18;;:::i;:::-;32967:7;32957:8;32953:22;32950:55;;;32987:16;;;;32950:55;33066:22;;;;33026:15;;;;32828:270;;;32832:3;32682:422;;;;;:::o;33109:806::-;33158:5;33188:8;33178:80;;-1:-1:-1;33229:1:1;33243:5;;33178:80;33277:4;33267:76;;-1:-1:-1;33314:1:1;33328:5;;33267:76;33359:4;33377:1;33372:59;;;;33445:1;33440:130;;;;33352:218;;33372:59;33402:1;33393:10;;33416:5;;;33440:130;33477:3;33467:8;33464:17;33461:43;;;33484:18;;:::i;:::-;-1:-1:-1;;33540:1:1;33526:16;;33555:5;;33352:218;;33654:2;33644:8;33641:16;33635:3;33629:4;33626:13;33622:36;33616:2;33606:8;33603:16;33598:2;33592:4;33589:12;33585:35;33582:77;33579:159;;;-1:-1:-1;33691:19:1;;;33723:5;;33579:159;33770:34;33795:8;33789:4;33770:34;:::i;:::-;33840:6;33836:1;33832:6;33828:19;33819:7;33816:32;33813:58;;;33851:18;;:::i;:::-;33889:20;;33109:806;-1:-1:-1;;;33109:806:1:o;33920:131::-;33980:5;34009:36;34036:8;34030:4;34009:36;:::i;34056:664::-;34283:3;34321:6;34315:13;34337:53;34383:6;34378:3;34371:4;34363:6;34359:17;34337:53;:::i;:::-;34453:13;;34412:16;;;;34475:57;34453:13;34412:16;34509:4;34497:17;;34475:57;:::i;:::-;34599:13;;34554:20;;;34621:57;34599:13;34554:20;34655:4;34643:17;;34621:57;:::i;:::-;34694:20;;34056:664;-1:-1:-1;;;;;34056:664:1:o;34725:1052::-;35048:3;35086:6;35080:13;35102:53;35148:6;35143:3;35136:4;35128:6;35124:17;35102:53;:::i;:::-;35218:13;;35177:16;;;;35240:57;35218:13;35177:16;35274:4;35262:17;;35240:57;:::i;:::-;35364:13;;35319:20;;;35386:57;35364:13;35319:20;35420:4;35408:17;;35386:57;:::i;:::-;35510:13;;35465:20;;;35532:57;35510:13;35465:20;35566:4;35554:17;;35532:57;:::i;:::-;35656:13;;35611:20;;;35678:57;35656:13;35611:20;35712:4;35700:17;;35678:57;:::i;:::-;35751:20;;34725:1052;-1:-1:-1;;;;;;;34725:1052:1:o;36500:184::-;-1:-1:-1;;;36549:1:1;36542:88;36649:4;36646:1;36639:15;36673:4;36670:1;36663:15

Swarm Source

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