ETH Price: $2,624.56 (+1.15%)

Token

Dollars Nakamoto (USDSat)
 

Overview

Max Total Supply

1,064 USDSat

Holders

335

Market

Volume (24H)

0.045 ETH

Min Price (24H)

$118.11 @ 0.045000 ETH

Max Price (24H)

$118.11 @ 0.045000 ETH
Balance
1 USDSat
0x2f0970dbb18731dbf2240274e6353a8bc6f50a8c
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Dollars Nakamoto is a NFT farming protocol By owning a Genesis Edition, user will able to mint nine more NFTs during the next 10 years.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
USDSat

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 5000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 15 of 16: USDSat.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8;

import "./USDSatMetadata.sol";
import "./Ownable.sol";
import "./ERC721.sol";
import "./ReentrancyGuard.sol";
import "./ERC721Enumerable.sol";

///                                            ``..                                                    
///                                    `.` `````.``.-````-``  `.`                                      
///                            ` ``````.`..///.-..----. --..--`.-....`..-.```` ```                     
///                        `` `.`..--...`:::/::-``..``..:-.://///---..-....-----                       
///                   ``-:::/+++:::/-.-///://oso+::++/--:--../+:/:..:-....-://:/:-``                   
///                   `-+/++/+o+://+::-:soo+oosss+s+//o:/:--`--:://://:ooso/-.--.-:-.`                 
///                 ``.+ooso++o+:+:+sosyhsyshhddyo+:/sds/yoo++/+:--/--.--:..--..``.````                
///                ``:++/---:+/::::///oyhhyy+++:hddhhNNho///ohosyhs+/-:/+/---.....-.. `                
///               ``-:-...-/+///++///+o+:-:o+o/oydmNmNNdddhsoyo/oyyyho///:-.--.-.``. ``                
///              ```--`..-:+/:--:::-.-///++++ydsdNNMNdmMNMmNysddyoooosso+//-.-`....````` ..`           
///                .```:-:::/-.-+o++/+:/+/o/hNNNNhmdNMMNNMMdyydNNmdyys+++oo++-`--.:.-.`````...         
///               ..--.`-..`.-`-hh++-/:+shho+hsysyyhhhmNNmmNMMmNNNdmmy+:+sh/o+y/+-`+./::.```` `        
///              -/` ``.-``.//o++y+//ssyh+hhdmmdmmddmhdmNdmdsh+oNNMmmddoodh/s:yss.--+.//+`.` `.        
///             `.`-.` -`..+h+yo++ooyyyyyoyhy+shmNNmmdhhdhyyhymdyyhdmshoohs+y:oy+/+o/:/++.`-   .`      
///             ``.`.``-.-++syyyhhhhhhhhmhysosyyoooosssdhhhdmmdhdmdsy+ss+/+ho/hody-s+-:+::--``  `      
///            .``  ``-//s+:ohmdmddNmNmhhshhddNNNhyyhhhdNNhmNNmNNmmyso+yhhso++hhdy.:/ ::-:--``.`       
///           .```.-`.//shdmNNmddyysohmMmdmNNmmNshdmNhso+-/ohNoyhmmsysosd++hy/osss/.:-o/-.:/--.        
///          ``..:++-+hhy/syhhhdhdNNddNMmNsNMNyyso+//:-.`-/..+hmdsmdy+ossos:+o/h/+..//-s.`.:::o/       
///          `.-.oy//hm+o:-..-+/shdNNNNNNhsNdo/oyoyyhoh+/so//+/mNmyhh+/s+dy/+s::+:`-`-:s--:-.::+`-`    
///           .`:h-`+y+./oyhhdddhyohMMNmmNmdhoo/oyyhddhmNNNmhsoodmdhs+///++:+-:.:/--/-/o/--+//...:`    
///           ``+o``yoodNNNNNMhdyyo+ymhsymyshhyys+sssssNmdmmdmy+oso/++:://+/-`::-:--:/::+.//o:-.--:    
///           `:-:-`oNhyhdNNNmyys+/:://oohy++/+hmmmmNNNNhohydmmyhy++////ooy./----.-:---/::-o+:...-/    
///          ``-.-` yms+mmNmMMmNho/:o++++hhh++:mMmNmmmNMNdhdms+ysyy//:-+o:.-.`.``.-:/::-:-+/y/.- -`    
///            ..:` hh+oNNmMNNNmss/:-+oyhs+o+.-yhdNmdhmmydmms+o///:///+/+--/`-``.o::/:-o//-/y::/.-     
///            `.-``hh+yNdmdohdy:++/./myhds/./shNhhyy++o:oyos/s+:s//+////.:- ...`--`..`-.:--o:+::`     
///              `-/+yyho.`.-+oso///+/Nmddh//y+:s:.../soy+:o+.:sdyo++++o:.-. `.:.:-```:.`:``/o:`:`     
///            ./.`..sMN+:::yh+s+ysyhhddh+ymdsd/:/+o+ysydhohoh/o+/so++o+/o.--..`-:::``:-`+-`:+--.`     
///           ``:``..-NNy++/yyysohmo+NNmy/+:+hMNmy+yydmNMNddhs:yyydmmmso:o///..-.-+-:o:/.o/-/+-``      
///           ``+.`..-mMhsyo+++oo+yoshyyo+/`+hNmhyy+sdmdssssho-MMMNMNh//+/oo+/+:-....`.s+/`..-`        
///             .+  `oNMmdhhsohhmmydmNms/yy.oNmmdy+++/+ss+odNm+mNmdddo-s+:+/++/-:--//`/o+s/.-``        
///             `/`  dNNNhooddNmNymMNNdsoo+y+shhhmyymhss+hddms+hdhmdo+/+-/oo+/.///+sh:-/-s/`           
///              `::`hdNmh+ooNmdohNNMMmsooohh+oysydhdooo/syysodmNmys+/o+//+y/:.+/hmso.-//s-            
///                -+ohdmmhyhdysysyyhmysoyddhhoo+shdhdyddmddmNmmhssds/::/oo/..:/+Nmo+`-:so             
///                 .oyhdmmNNdm+s:/:os/+/ssyyds+/ssdNNyhdmmhdmmdymymy///o:/``/+-dmdoo++:o`             
///                 `ysyMNhhmoo+h-:/+o/+:.:/:/+doo+dNdhddmhmmmy++yhds/+-+::..o/+Nmosyhs+-              
///                  s+dNNyNhsdhNhsy:+:oo/soo+dNmmooyosohMhsymmhyy+++:+:/+/-/o+yNh+hMNs.               
///                  +yhNNMd+dmydmdy/+/sshydmhdNNmNooyhhhhshohmNh+:+oso++ssy+/odyhhNmh`                
///                 `yyhdms+dMh+oyshhyhysdmNd+ohyNN+++mNddmNy+yo//+o/hddddymmyhosNmms`                 
///                  oydos:oMmhoyyhysssysdmMmNmhNmNNh/+mmNmddh+/+o+::+s+hmhmdyNNNNy:                   
///                 `/dNm/+Ndhy+oshdhhdyo::ohmdyhhNysy:smshmdo/o:so//:s++ymhyohdy-`                    
///                 `sNNN/hNm/:do+o:+/++++s:/+shyymmddy/ydmmh/s/+oss//oysy++o+o+`                      
///                  oNNMNmm:/hyy/:/o/+hhsosysoo-ohhhss/hmmhd/dyh++/soyooy++o+:.                       
///                  :/dMNh/smhh+//+s+--:+/so+ohhy/:sydmmmmm+/mdddhy++/ohs//-o/`                       
///                  `/odmhyhsyh++/-:+:::/:/o/:ooddy/+yodNNh+ydhmmmy++/hhyo+://`                       
///                   `:os/+o//oshss/yhs+//:+/-/:soooo/+sso+dddydss+:+sy///+:++                        
///                     ./o/s//hhNho+shyyyoyyso+/ys+/+-:y+:/soooyyh++sNyo++/:/+                        
///                      -/:osmmhyo:++++/+/osshdssooo/:/h//://++oyhsshmdo+//s/-                        
///                       .osmhydh::/+++/o+ohhysddyoo++os+-+++///yhhhmNs+o/://                         
///                        -.++yss//////+/+/+soo++shyhsyy+::/:+y+yhdmdoo//:/:-                         
///                         ``.oss/:////++://+o//:://+oo-:o++/shhhmmh+o+++///-`                        
///                           ..:+++oo/+///ys:///://+::-sy+osh+osdyo+o/::/s:/y-`                       
///                           `odoyhds+/yysyydss+///+/:+oshdmNo+:+/oo/+++++:hy//`                      
///                         `://hyoyy/o/++shhy:+y:/:o/+omNmhsoohhsso+++:+o+sy:/++                      
///                        -/---oddooss+oosy+ohNdo+++oyNhsdo/++shhhoo:s+oydmyo//o+                     
///                       :y.`.``yyd++shoyydhhyymdhyyhyhhs+////+/+s/+:odmmyso.:ohy.                    
///                      .yy/o-..+h/+o/+//++ssoohhhssso+++:/:/yy+//sydmNddo+/./ohy+.                   
///                      .dmmhs+osdoos///o//++/+shdsoshoys+ssss++shmNNNyyds+:-s-//:+.                  
///                      -shmNmyhddsyss++/+ysddhyyydhdmyssNddyydyhNmdNmddso/::s:--`.-.`                
///                     `+dmNhhdmddsooyyooossysshdhmoss+/+mNdyymydMdyMdyoo+/--/:/:`...-.`              
///                    .:smNNMmsMNNmdhyyo/yymmdmdyo+ooooshysyysNNNmmmNyss/+o-`-:-/:```.`` ```          
///                 `.-+o/sdNNNmhdddNmmdsso/sdshyyyyhsdddyohymdmNdmmmmmyoo+/.... -os.`.``-.``          
///               `/-:-/+.hymmmmdhmyNdMNmmhhs+sosoyhddyddmmho/ooymhddhdhyos-.oy..-:o+:..``  ````    `  
///             ..::``--.-hoymmdNNNNNNMmhyNh+oo+soyNdmNmmmysooooymhy+so++yo..:+.--`..:.`.` `-- ``.` `  
///          ```-.-.``..`:ddymmmNNdmNNNNmhN: -/oys/sdmmNdydsydmhhsmdso+/yo:/-..`.``.`  ``:.`.````-.   `
///        ````-:/.```:::syyydmddNhNNdsdMMs`./oddmd./odNdy+yssss++ooo/o+//-`:/:..:`-.```/-:.`.```..`` `
///   ```..-`` --.`.--o+sNhoyMmho+omhmo+Ns::dhdmmdy:.oNoyhhs+/o+o++s+hhoo+.`-:....``.-:-`..-````.-``.``


/// @title  Dollars Nakamoto by Pascal Boyart
/// @author jolan.eth
/// @notice This contract will allow you to yield farm Dollars Nakamoto NFT.
///     	During epoch 0 you will be able to mint a Genesis NFT,
///     	Over time, epoch will increment allowing you to mint more editions.
///     	Minting generations editions is allowed only 1 time per epoch and per Genesis NFT.
///  	    Generations editions do not allow you to mint other generations.
contract USDSat is USDSatMetadata, ERC721, ERC721Enumerable, Ownable, ReentrancyGuard {
    string SYMBOL = "USDSat";
    string NAME = "Dollars Nakamoto";

    string ContractCID;

    /// @notice Address used to sign NFT on mint
    address public ADDRESS_SIGN = 0x1Af70e564847bE46e4bA286c0b0066Da8372F902;

    /// @notice Ether shareholder address
    address public ADDRESS_PBOY = 0x709e17B3Ec505F80eAb064d0F2A71c743cE225B3;

    /// @notice Ether shareholder address
    address public ADDRESS_JOLAN = 0x51BdFa2Cbb25591AF58b202aCdcdB33325a325c2;
    
    /// @notice Equity per shareholder in %
    uint256 public SHARE_PBOY = 90;

    /// @notice Equity per shareholder in %
    uint256 public SHARE_JOLAN = 10;

    /// @notice Mapping used to represent allowed addresses to call { mintGenesis }
    mapping (address => bool) public _allowList;

    /// @notice Represent the current epoch
    uint256 public epoch = 0;

    /// @notice Represent the maximum epoch possible
    uint256 public epochMax = 10;
    
    /// @notice Represent the block length of an epoch
    uint256 public epochLen = 41016;

    /// @notice Index of the NFT
    /// @dev    Start at 1 because var++
    uint256 public tokenId = 1;

    /// @notice Index of the Genesis NFT
    /// @dev    Start at 0 because ++var
    uint256 public genesisId = 0;

    /// @notice Index of the Generation NFT
    /// @dev    Start at 0 because ++var
    uint256 public generationId = 0;

    /// @notice Maximum total supply
    uint256 public maxTokenSupply = 2100;

    /// @notice Maximum Genesis supply
    uint256 public maxGenesisSupply = 210;

    /// @notice Maximum supply per generation
    uint256 public maxGenerationSupply = 210;

    /// @notice Price of the Genesis NFT (Generations NFT are free)
    uint256 public genesisPrice = 0.5 ether;

    /// @notice Define the ending block
    uint256 public blockOmega;

    /// @notice Define the starting block
    uint256 public blockGenesis;

    /// @notice Define in which block the Meta must occur
    uint256 public blockMeta;

    /// @notice Used to inflate blockMeta each epoch incrementation
    uint256 public inflateRatio = 2;

    /// @notice Open Genesis mint when true
    bool public genesisMintAllowed = false;

    /// @notice Open Generation mint when true
    bool public generationMintAllowed = false;

    /// @notice Multi dimensionnal mapping to keep a track of the minting reentrancy over epoch
    mapping(uint256 => mapping(uint256 => bool)) public epochMintingRegistry;

    event Omega(uint256 _blockNumber);
    event Genesis(uint256 indexed _epoch, uint256 _blockNumber);
    event Meta(uint256 indexed _epoch, uint256 _blockNumber);
    
    event Withdraw(uint256 indexed _share, address _shareholder);
    event Shareholder(uint256 indexed _sharePercent, address _shareholder);
    
    event Securized(uint256 indexed _epoch, uint256 _epochLen, uint256 _blockMeta, uint256 _inflateRatio);

    event PermanentURI(string _value, uint256 indexed _id);
    event Minted(uint256 indexed _epoch, uint256 indexed _tokenId, address indexed _owner);
    event Signed(uint256 indexed _epoch, uint256 indexed _tokenId, uint256 indexed _blockNumber);

    constructor() ERC721(NAME, SYMBOL) {}

    // Withdraw functions *************************************************

    /// @notice Allow Pboy to modify ADDRESS_PBOY
    ///         This function is dedicated to the represented shareholder according to require().
    function setPboy(address PBOY)
    public {
        require(msg.sender == ADDRESS_PBOY, "error msg.sender");
        ADDRESS_PBOY = PBOY;
        emit Shareholder(SHARE_PBOY, ADDRESS_PBOY);
    }

    /// @notice Allow Jolan to modify ADDRESS_JOLAN
    ///         This function is dedicated to the represented shareholder according to require().
    function setJolan(address JOLAN)
    public {
        require(msg.sender == ADDRESS_JOLAN, "error msg.sender");
        ADDRESS_JOLAN = JOLAN;
        emit Shareholder(SHARE_JOLAN, ADDRESS_JOLAN);
    }

    /// @notice Used to withdraw ETH balance of the contract, this function is dedicated
    ///         to contract owner according to { onlyOwner } modifier.
    function withdrawEquity()
    public onlyOwner nonReentrant {
        uint256 balance = address(this).balance;

        address[2] memory shareholders = [
            ADDRESS_PBOY,
            ADDRESS_JOLAN
        ];

        uint256[2] memory _shares = [
            SHARE_PBOY * balance / 100,
            SHARE_JOLAN * balance / 100
        ];

        uint i = 0;
        while (i < 2) {
            require(payable(shareholders[i]).send(_shares[i]));
            emit Withdraw(_shares[i], shareholders[i]);
            i++;
        }
    }

    // Epoch functions ****************************************************

    /// @notice Used to manage authorization and reentrancy of the genesis NFT mint
    /// @param  _genesisId Used to increment { genesisId } and write { epochMintingRegistry }
    function genesisController(uint256 _genesisId)
    private {
        require(epoch == 0, "error epoch");
        require(genesisId <= maxGenesisSupply, "error genesisId");
        require(!epochMintingRegistry[epoch][_genesisId], "error epochMintingRegistry");

        /// @dev Set { _genesisId } for { epoch } as true
        epochMintingRegistry[epoch][_genesisId] = true;

        /// @dev When { genesisId } reaches { maxGenesisSupply } the function
        ///      will compute the data to increment the epoch according
        ///
        ///      { blockGenesis } is set only once, at this time
        ///      { blockMeta } is set to { blockGenesis } because epoch=0
        ///      Then it is computed into the function epochRegulator()
        ///
        ///      Once the epoch is regulated, the new generation start
        ///      straight away, { generationMintAllowed } is set to true
        if (genesisId == maxGenesisSupply) {
            blockGenesis = block.number;
            blockMeta = blockGenesis;
            
            emit Genesis(epoch, blockGenesis);
            epochRegulator();
        }
    }

    /// @notice Used to manage authorization and reentrancy of the Generation NFT mint
    /// @param  _genesisId Used to write { epochMintingRegistry } and verify minting allowance
    function generationController(uint256 _genesisId)
    private {
        require(blockGenesis > 0, "error blockGenesis");
        require(blockMeta > 0, "error blockMeta");
        require(blockOmega > 0, "error blockOmega");

        /// @dev If { block.number } >= { blockMeta } the function
        ///      will compute the data to increment the epoch according
        ///
        ///      Once the epoch is regulated, the new generation start
        ///      straight away, { generationMintAllowed } is set to true
        ///
        ///      { generationId } is reset to 1
        if (block.number >= blockMeta) {
            epochRegulator();
            generationId = 1;
        }

        /// @dev Be sure the mint is open if condition are favorable
        if (block.number < blockMeta && generationId <= maxGenerationSupply) {
            generationMintAllowed = true;
        }

        require(maxTokenSupply >= tokenId, "error maxTokenSupply");
        require(epoch > 0 && epoch < epochMax, "error epoch");
        require(ownerOf(_genesisId) == msg.sender, "error ownerOf");
        require(generationMintAllowed, "error generationMintAllowed");
        require(generationId <= maxGenerationSupply, "error generationId");
        require(epochMintingRegistry[0][_genesisId], "error epochMintingRegistry");
        require(!epochMintingRegistry[epoch][_genesisId], "error epochMintingRegistry");

        /// @dev Set { _genesisId } for { epoch } as true
        epochMintingRegistry[epoch][_genesisId] = true;

        /// @dev If { generationId } reaches { maxGenerationSupply } the modifier
        ///      will set { generationMintAllowed } to false to stop the mint
        ///      on this generation
        ///
        ///      { generationId } is reset to 0
        ///
        ///      This condition will not block the function because as long as
        ///      { block.number } >= { blockMeta } minting will reopen
        ///      according and this condition will become obsolete until
        ///      the condition is reached again
        if (generationId == maxGenerationSupply) {
            generationMintAllowed = false;
            generationId = 0;
        }
    }

    /// @notice Used to protect epoch block length from difficulty bomb of the
    ///         Ethereum network. A difficulty bomb heavily increases the difficulty
    ///         on the network, likely also causing an increase in block time.
    ///         If the block time increases too much, the epoch generation could become
    ///         exponentially higher than what is desired, ending with an undesired Ice-Age.
    ///         To protect against this, the emergencySecure() function is allowed to
    ///         manually reconfigure the epoch block length and the block Meta
    ///         to match the network conditions if necessary.
    ///
    ///         It can also be useful if the block time decreases for some reason with consensus change.
    ///
    ///         This function is dedicated to contract owner according to { onlyOwner } modifier
    function emergencySecure(uint256 _epoch, uint256 _epochLen, uint256 _blockMeta, uint256 _inflateRatio)
    public onlyOwner {
        require(epoch > 0, "error epoch");
        require(_epoch > 0, "error _epoch");
        require(maxTokenSupply >= tokenId, "error maxTokenSupply");

        epoch = _epoch;
        epochLen = _epochLen;
        blockMeta = _blockMeta;
        inflateRatio = _inflateRatio;

        computeBlockOmega();
        emit Securized(epoch, epochLen, blockMeta, inflateRatio);
    }

    /// @notice Used to compute blockOmega() function, { blockOmega } represents
    ///         the block when it won't ever be possible to mint another Dollars Nakamoto NFT.
    ///         It is possible to be computed because of the deterministic state of the current protocol
    ///         The following algorithm simulate the 10 epochs of the protocol block computation to result blockOmega
    function computeBlockOmega()
    private {
        uint256 i = 0;
        uint256 _blockMeta = 0;
        uint256 _epochLen = epochLen;

        while (i < epochMax) {
            if (i > 0) _epochLen *= inflateRatio;
            if (i == 9) {
                blockOmega = blockGenesis + _blockMeta;
                emit Omega(blockOmega);
                break;
            }
            _blockMeta += _epochLen;
            i++;
        }
    }

    /// @notice Used to regulate the epoch incrementation and block computation, known as Metas
    /// @dev When epoch=0, the { blockOmega } will be computed
    ///      When epoch!=0 the block length { epochLen } will be multiplied
    ///      by { inflateRatio } thus making the block length required for each
    ///      epoch longer according
    ///
    ///      { blockMeta } += { epochLen } result the exact block of the next Meta
    ///      Allow generation mint after incrementing the epoch
    function epochRegulator()
    private {
        if (epoch == 0) computeBlockOmega();
        if (epoch > 0) epochLen *= inflateRatio;
        
        blockMeta += epochLen;
        emit Meta(epoch, blockMeta);

        epoch++;

        if (block.number >= blockMeta && epoch < epochMax) {
            epochRegulator();
        }
        
        generationMintAllowed = true;
    }

    // Mint functions *****************************************************

    /// @notice Used to add/remove address from { _allowList }
    function setBatchGenesisAllowance(address[] memory batch)
    public onlyOwner {
        uint len = batch.length;
        require(len > 0, "error len");
        
        uint i = 0;
        while (i < len) {
            _allowList[batch[i]] = _allowList[batch[i]] ?
            false : true;
            i++;
        }
    }

    /// @notice Used to transfer { _allowList } slot to another address
    function transferListSlot(address to)
    public {
        require(epoch == 0, "error epoch");
        require(_allowList[msg.sender], "error msg.sender");
        require(!_allowList[to], "error to");
        _allowList[msg.sender] = false;
        _allowList[to] = true;
    }

    /// @notice Used to open the mint of Genesis NFT
    function setGenesisMint()
    public onlyOwner {
        genesisMintAllowed = true;
    }

    /// @notice Used to gift Genesis NFT, this function is dedicated
    ///         to contract owner according to { onlyOwner } modifier
    function giftGenesis(address to)
    public onlyOwner {
        uint256 _genesisId = ++genesisId;
        setMetadata(tokenId, _genesisId, epoch);
        genesisController(_genesisId);
        mintUSDSat(to, tokenId++);
    }

    /// @notice Used to mint Genesis NFT, this function is payable
    ///         the price of this function is equal to { genesisPrice },
    ///         require to be present on { _allowList } to call
    function mintGenesis() 
    public payable {
        uint256 _genesisId = ++genesisId;
        setMetadata(tokenId, _genesisId, epoch);
        genesisController(_genesisId);
        require(genesisMintAllowed, "error genesisMintAllowed");
        require(_allowList[msg.sender], "error allowList");
        require(genesisPrice == msg.value, "error genesisPrice");

        _allowList[msg.sender] = false;
        mintUSDSat(msg.sender, tokenId++);
    }

    /// @notice Used to gift Generation NFT, you need a Genesis NFT to call this function
    function giftGenerations(uint256 _genesisId, address to)
    public {
        ++generationId;
        generationController(_genesisId); 
        setMetadata(tokenId, _genesisId, epoch);
        mintUSDSat(to, tokenId++);
    }

    /// @notice Used to mint Generation NFT, you need a Genesis NFT to call this function
    function mintGenerations(uint256 _genesisId)
    public {
        ++generationId;
        generationController(_genesisId);
        setMetadata(tokenId, _genesisId, epoch);
        mintUSDSat(msg.sender, tokenId++);
    }

    /// @notice Token is minted on { ADDRESS_SIGN } and instantly transferred to { msg.sender } as { to },
    ///         this is to ensure the token creation is signed with { ADDRESS_SIGN }
    ///         This function is private and can be only called by the contract
    function mintUSDSat(address to, uint256 _tokenId)
    private {
        emit PermanentURI(_compileMetadata(_tokenId), _tokenId);
        _safeMint(ADDRESS_SIGN, _tokenId);
        emit Signed(epoch, _tokenId, block.number);
        _safeTransfer(ADDRESS_SIGN, to, _tokenId, "");
        emit Minted(epoch, _tokenId, to);
    }

    // Contract URI functions *********************************************

    /// @notice Used to set the { ContractCID } metadata from ipfs,
    ///         this function is dedicated to contract owner according
    ///         to { onlyOwner } modifier
    function setContractCID(string memory CID)
    public onlyOwner {
        ContractCID = string(abi.encodePacked("ipfs://", CID));
    }

    /// @notice Used to render { ContractCID } as { contractURI } according to
    ///         Opensea contract metadata standard
    function contractURI()
    public view virtual returns (string memory) {
        return ContractCID;
    }

    // Utilitaries functions **********************************************

    /// @notice Used to fetch all entry for { epoch } into { epochMintingRegistry } 
    function getMapRegisteryForEpoch(uint256 _epoch)
    public view returns (bool[210] memory result) {
        uint i = 1;
        while (i <= maxGenesisSupply) {
            result[i] = epochMintingRegistry[_epoch][i];
            i++;
        }
    }
    
    /// @notice Used to fetch all { tokenIds } from { owner }
    function exposeHeldIds(address owner)
    public view returns(uint[] memory) {
        uint tokenCount = balanceOf(owner);
        uint[] memory tokenIds = new uint[](tokenCount);

        uint i = 0;
        while (i < tokenCount) { 
            tokenIds[i] = tokenOfOwnerByIndex(owner, i);
            i++;
        }
        return tokenIds;
    }

    // ERC721 Spec functions **********************************************

    /// @notice Used to render metadata as { tokenURI } according to ERC721 standard
    function tokenURI(uint256 _tokenId)
    public view virtual override returns (string memory) {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
        return _compileMetadata(_tokenId);
    }

    /// @dev ERC721 required override
    function _beforeTokenTransfer(address from, address to, uint256 _tokenId)
    internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, _tokenId);
    }

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

File 1 of 16: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 2 of 16: Base64.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.6;

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

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

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

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

        bytes memory table = TABLE;

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

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

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

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

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

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

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

File 3 of 16: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (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 4 of 16: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 5 of 16: ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _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: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

File 6 of 16: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./IERC721Enumerable.sol";

/**
 * @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 7 of 16: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (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 8 of 16: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 16: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

    /**
     * @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 10 of 16: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 11 of 16: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 12 of 16: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

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

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

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

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

File 13 of 16: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // 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 14 of 16: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

pragma solidity ^0.8;

import "./Base64.sol";
import "./Strings.sol";

contract USDSatMetadata {
    string tokenName = "Dollars Nakamoto";
    string tokenDescription = "Multiple Edition - Dollars Nakamoto by Pascal Boyart is a farming NFT collection based on the original artwork made with hundreds of real USD Bills glued on canvas in 2018.";
    
    string JSON = 'data:application/json;base64,';

    uint256 metadataId = 1;

    string DollarsNakamotoGenesisGifCID = "QmP3asJxMbCMrN6aDKN4iZpcUJw2zEHTfJuV8sh5XhUSAv";
    string DollarsNakamotoGenerationGifCID = "QmZ71ajdHPS7NofbK3rpNAJqnxq29mfdNSPaecy3bHUD9G";

    string DollarsNakamotoGenesisMp4CID = "QmRmvo1wDxSV2uBm1KNqJ9z6UayzickLKhMKJYfdhMGCbf";
    string DollarsNakamotoGenerationMp4CID = "QmWBAS7pmRbWZQ3wkiuw918zVtz9eS6oajpkq9hUVBFiwo";
    
    mapping (uint256 => string) _metadataName;
    mapping (uint256 => string) _metadataAttributes;
    mapping (uint256 => string) _metadataImageCID;
    mapping (uint256 => string) _metadataVideoCID;

    constructor() {}

    function _serialize(uint256 _tokenId)
    private pure returns(string memory result) {
        string memory tmp;
        if (_tokenId < 1000) tmp = string(abi.encodePacked('', Strings.toString(_tokenId)));
        if (_tokenId < 100) tmp = string(abi.encodePacked('0', Strings.toString(_tokenId)));
        if (_tokenId < 10) tmp = string(abi.encodePacked('00', Strings.toString(_tokenId)));
        
        result = string(
            abi.encodePacked(
                '#', tmp
            )
        );
    }

    function setMetadata(uint256 _tokenId, uint256 _epochId, uint256 _epoch)
    internal {
        _setMetadataName(_tokenId, _epoch);
        _setMetadataOrigins(_tokenId, _epochId, _epoch);
        _setMetadataImageCID(_tokenId, _epoch);
        _setMetadataVideoCID(_tokenId, _epoch);
        metadataId++;
    }

    function _setMetadataImageCID(uint256 _tokenId, uint256 _epoch)
    internal {
        _metadataImageCID[_tokenId] = string(
            abi.encodePacked(
                "ipfs://",
                _epoch == 0 ?
                DollarsNakamotoGenesisGifCID :
                DollarsNakamotoGenerationGifCID
            )
        );
    }

    function _setMetadataVideoCID(uint256 _tokenId, uint256 _epoch)
    internal {
        _metadataVideoCID[_tokenId] = string(
            abi.encodePacked(
                "ipfs://",
                _epoch == 0 ?
                DollarsNakamotoGenesisMp4CID :
                DollarsNakamotoGenerationMp4CID
            )
        );
    }

    function _setMetadataName(uint256 _tokenId, uint256 _epoch)
    internal {
        _metadataName[_tokenId] = string(
            abi.encodePacked(
                tokenName, ' - ', _epoch == 0 ? 'Genesis Edition' : string(
                    abi.encodePacked(
                        Strings.toString(_epoch + 1), (
                            (_epoch + 1) == 2 ? 'nd' :
                            (_epoch + 1) == 3 ? 'rd' :
                            (_epoch + 1) > 3 ? 'th' :
                            ''
                        ), ' Edition'
                    )
                )
            )
        );
    }

    function _setMetadataOrigins(uint256 _tokenId, uint256 _epochId, uint256 _epoch)
    internal {
        _metadataAttributes[_tokenId] = string(
            abi.encodePacked(
                _epoch == 0 ?
                '{"trait_type":"Edition","value":"Genesis"},' :
                string(
                    abi.encodePacked(
                        '{"trait_type":"Edition","value":"#', Strings.toString(_epoch + 1),'"},'
                    )
                ),
                _epoch == 0 ?
                '{"trait_type":"NFT Type","value":"Generator"},' : '{"trait_type":"NFT Type","value":"Generated"},',
                '{"trait_type":"Serial","value":"',_serialize(_epochId),'"},',
                '{"trait_type":"Character","value":"Dorian Nakamoto"},',
                '{"trait_type":"Effect","value":"BRRR"},',
                '{"trait_type":"USD Portrait","value":"#1 - Who is Satoshi"},',
                '{"trait_type":"Medium","value":"Dollar bills glued on canvas"}'
            )
        );
    }

    function _tokenData(uint256 _tokenId)
    internal view returns (string memory result) {
        result = string(
            abi.encodePacked(
                '{',
                '"name":"',_metadataName[_tokenId],'",',
                '"description":"',tokenDescription,'",',
                '"attributes":[',_metadataAttributes[_tokenId],'],',
                '"image":"',_metadataImageCID[_tokenId],'",',
                '"animation_url":"',_metadataVideoCID[_tokenId],'"',
                '}'
            )
        );
    }

    function _compileMetadata(uint256 _tokenId)
    internal view returns (
        string memory result) {
            result = string(abi.encodePacked(
                JSON,
                Base64.encode(
                    bytes (
                        string(
                            abi.encodePacked(
                                _tokenData(_tokenId)
                            )
                        )
                    )
                )
            )
        );
    }
}

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":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"Genesis","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"Meta","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_owner","type":"address"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"Omega","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_value","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"PermanentURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_epochLen","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_blockMeta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_inflateRatio","type":"uint256"}],"name":"Securized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_sharePercent","type":"uint256"},{"indexed":false,"internalType":"address","name":"_shareholder","type":"address"}],"name":"Shareholder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"Signed","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_share","type":"uint256"},{"indexed":false,"internalType":"address","name":"_shareholder","type":"address"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"ADDRESS_JOLAN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADDRESS_PBOY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADDRESS_SIGN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARE_JOLAN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARE_PBOY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_allowList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockGenesis","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockMeta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockOmega","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"uint256","name":"_epochLen","type":"uint256"},{"internalType":"uint256","name":"_blockMeta","type":"uint256"},{"internalType":"uint256","name":"_inflateRatio","type":"uint256"}],"name":"emergencySecure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochLen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochMintingRegistry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"exposeHeldIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"generationId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"generationMintAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisMintAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getMapRegisteryForEpoch","outputs":[{"internalType":"bool[210]","name":"result","type":"bool[210]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_genesisId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"giftGenerations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"giftGenesis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inflateRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGenerationSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGenesisSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_genesisId","type":"uint256"}],"name":"mintGenerations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintGenesis","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":"address[]","name":"batch","type":"address[]"}],"name":"setBatchGenesisAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"CID","type":"string"}],"name":"setContractCID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setGenesisMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"JOLAN","type":"address"}],"name":"setJolan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"PBOY","type":"address"}],"name":"setPboy","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":[],"name":"tokenId","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":"_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":"to","type":"address"}],"name":"transferListSlot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEquity","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052601060808190526f446f6c6c617273204e616b616d6f746f60801b60a09081526200003391600091906200047a565b506040518060e0016040528060ac815260200162004fe560ac9139805162000064916001916020909101906200047a565b5060408051808201909152601d8082527f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006020909201918252620000ab916002916200047a565b5060016003556040518060600160405280602e8152602001620050bf602e91398051620000e1916004916020909101906200047a565b506040518060600160405280602e815260200162005091602e9139805162000112916005916020909101906200047a565b506040518060600160405280602e815260200162004f89602e9139805162000143916006916020909101906200047a565b506040518060600160405280602e815260200162004fb7602e9139805162000174916007916020909101906200047a565b50604080518082019091526006808252651554d114d85d60d21b6020909201918252620001a4916018916200047a565b506040805180820190915260108082526f446f6c6c617273204e616b616d6f746f60801b6020909201918252620001de916019916200047a565b50601b80546001600160a01b0319908116731af70e564847be46e4ba286c0b0066da8372f90217909155601c8054821673709e17b3ec505f80eab064d0f2a71c743ce225b3179055601d80549091167351bdfa2cbb25591af58b202acdcdb33325a325c2179055605a601e55600a601f8190556000602181905560229190915561a0386023556001602455602581905560265561083460275560d260288190556029556706f05b59d3b20000602a556002602e55602f805461ffff19169055348015620002aa57600080fd5b5060198054620002ba9062000520565b80601f0160208091040260200160405190810160405280929190818152602001828054620002e89062000520565b8015620003395780601f106200030d5761010080835404028352916020019162000339565b820191906000526020600020905b8154815290600101906020018083116200031b57829003601f168201915b5050505050601880546200034d9062000520565b80601f01602080910402602001604051908101604052809291908181526020018280546200037b9062000520565b8015620003cc5780601f10620003a057610100808354040283529160200191620003cc565b820191906000526020600020905b815481529060010190602001808311620003ae57829003601f168201915b50508451620003e69350600c92506020860191506200047a565b508051620003fc90600d9060208401906200047a565b50505062000419620004136200042460201b60201c565b62000428565b60016017556200055d565b3390565b601680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620004889062000520565b90600052602060002090601f016020900481019282620004ac5760008555620004f7565b82601f10620004c757805160ff1916838001178555620004f7565b82800160010185558215620004f7579182015b82811115620004f7578251825591602001919060010190620004da565b506200050592915062000509565b5090565b5b808211156200050557600081556001016200050a565b600181811c908216806200053557607f821691505b602082108114156200055757634e487b7160e01b600052602260045260246000fd5b50919050565b614a1c806200056d6000396000f3fe6080604052600436106103765760003560e01c8063728cce7c116101d1578063a348f57011610102578063d20bc0a5116100a0578063e985e9c51161006f578063e985e9c51461099b578063ed750f45146109e4578063eed8367d14610a04578063f2fde38b14610a2457600080fd5b8063d20bc0a51461093b578063d258941f1461095a578063d2b3996f14610970578063e8a3d4851461098657600080fd5b8063b88d4fde116100dc578063b88d4fde146108c5578063c0220347146108e5578063c87b56dd14610905578063cd08bdf71461092557600080fd5b8063a348f5701461085e578063a660ab6414610874578063b10e1c6c146108af57600080fd5b806385e11dfc1161016f578063900cf0cf11610149578063900cf0cf146107f357806395d89b4114610809578063a1470e1a1461081e578063a22cb4651461083e57600080fd5b806385e11dfc1461079f578063899486e1146107b55780638da5cb5b146107d557600080fd5b80637b2469fd116101ab5780637b2469fd1461072f57806382f785321461074957806383c1c69f14610769578063842b83fa1461078957600080fd5b8063728cce7c146106fc57806374da546b1461071257806378c3a6921461072757600080fd5b806337496f40116102ab5780635ccba0521161024957806364ca6e201161022357806364ca6e201461068457806369013efa1461069a57806370a08231146106c7578063715018a6146106e757600080fd5b80635ccba052146106155780635dce15a9146106445780636352211e1461066457600080fd5b806348a7e4661161028557806348a7e466146105aa5780634b423d02146105ca5780634f6ccce7146105df57806350f7c204146105ff57600080fd5b806337496f401461054757806342842e0e1461057457806346e46e2a1461059457600080fd5b80631dc2fd6d116103185780632445391a116102f25780632445391a146104db5780632685fd14146104fb57806327827ae8146105115780632f745c591461052757600080fd5b80631dc2fd6d1461048557806323b872dd1461049b57806323bb02f1146104bb57600080fd5b8063081812fc11610354578063081812fc1461040a578063095ea7b31461042a57806317d70f7c1461044c57806318160ddd1461047057600080fd5b806301ffc9a71461037b578063060bd1d4146103b057806306fdde03146103e8575b600080fd5b34801561038757600080fd5b5061039b610396366004613c1c565b610a44565b60405190151581526020015b60405180910390f35b3480156103bc57600080fd5b50601c546103d0906001600160a01b031681565b6040516001600160a01b0390911681526020016103a7565b3480156103f457600080fd5b506103fd610a55565b6040516103a79190613c98565b34801561041657600080fd5b506103d0610425366004613cab565b610ae7565b34801561043657600080fd5b5061044a610445366004613ce0565b610b92565b005b34801561045857600080fd5b5061046260245481565b6040519081526020016103a7565b34801561047c57600080fd5b50601454610462565b34801561049157600080fd5b50610462602b5481565b3480156104a757600080fd5b5061044a6104b6366004613d0a565b610cc4565b3480156104c757600080fd5b5061044a6104d6366004613cab565b610d4b565b3480156104e757600080fd5b5061044a6104f6366004613d46565b610d98565b34801561050757600080fd5b50610462601e5481565b34801561051d57600080fd5b50610462601f5481565b34801561053357600080fd5b50610462610542366004613ce0565b610ee4565b34801561055357600080fd5b50610567610562366004613cab565b610f8c565b6040516103a79190613d61565b34801561058057600080fd5b5061044a61058f366004613d0a565b610ff1565b3480156105a057600080fd5b50610462602c5481565b3480156105b657600080fd5b5061044a6105c5366004613e34565b61100c565b3480156105d657600080fd5b5061044a61109f565b3480156105eb57600080fd5b506104626105fa366004613cab565b6112b6565b34801561060b57600080fd5b5061046260275481565b34801561062157600080fd5b5061039b610630366004613d46565b602080526000908152604090205460ff1681565b34801561065057600080fd5b5061044a61065f366004613d46565b61135a565b34801561067057600080fd5b506103d061067f366004613cab565b611425565b34801561069057600080fd5b5061046260265481565b3480156106a657600080fd5b506106ba6106b5366004613d46565b6114b0565b6040516103a79190613e7d565b3480156106d357600080fd5b506104626106e2366004613d46565b611552565b3480156106f357600080fd5b5061044a6115ec565b34801561070857600080fd5b50610462602a5481565b34801561071e57600080fd5b5061044a611652565b61044a6116bb565b34801561073b57600080fd5b50602f5461039b9060ff1681565b34801561075557600080fd5b5061044a610764366004613ec1565b611818565b34801561077557600080fd5b5061044a610784366004613d46565b611971565b34801561079557600080fd5b5061046260285481565b3480156107ab57600080fd5b5061046260255481565b3480156107c157600080fd5b5061044a6107d0366004613f6e565b611a12565b3480156107e157600080fd5b506016546001600160a01b03166103d0565b3480156107ff57600080fd5b5061046260215481565b34801561081557600080fd5b506103fd611a53565b34801561082a57600080fd5b5061044a610839366004613d46565b611a62565b34801561084a57600080fd5b5061044a610859366004613f9a565b611b26565b34801561086a57600080fd5b5061046260225481565b34801561088057600080fd5b5061039b61088f366004613fd6565b603060209081526000928352604080842090915290825290205460ff1681565b3480156108bb57600080fd5b50610462602d5481565b3480156108d157600080fd5b5061044a6108e0366004613ff8565b611b31565b3480156108f157600080fd5b50601d546103d0906001600160a01b031681565b34801561091157600080fd5b506103fd610920366004613cab565b611bbf565b34801561093157600080fd5b50610462602e5481565b34801561094757600080fd5b50602f5461039b90610100900460ff1681565b34801561096657600080fd5b5061046260295481565b34801561097c57600080fd5b5061046260235481565b34801561099257600080fd5b506103fd611c55565b3480156109a757600080fd5b5061039b6109b6366004614074565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205460ff1690565b3480156109f057600080fd5b50601b546103d0906001600160a01b031681565b348015610a1057600080fd5b5061044a610a1f36600461409e565b611c64565b348015610a3057600080fd5b5061044a610a3f366004613d46565b611e20565b6000610a4f82611eff565b92915050565b6060600c8054610a64906140d0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a90906140d0565b8015610add5780601f10610ab257610100808354040283529160200191610add565b820191906000526020600020905b815481529060010190602001808311610ac057829003601f168201915b5050505050905090565b6000818152600e60205260408120546001600160a01b0316610b765760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152601060205260409020546001600160a01b031690565b6000610b9d82611425565b9050806001600160a01b0316836001600160a01b03161415610c275760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610b6d565b336001600160a01b0382161480610c435750610c4381336109b6565b610cb55760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b6d565b610cbf8383611f55565b505050565b610cce3382611fdb565b610d405760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b6d565b610cbf8383836120e3565b602660008154610d5a9061411b565b90915550610d67816122d3565b610d76602454826021546126fa565b60248054610d95913391906000610d8c8361411b565b9190505561273d565b50565b60215415610de85760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b33600090815260208052604090205460ff16610e465760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b6001600160a01b038116600090815260208052604090205460ff1615610eae5760405162461bcd60e51b815260206004820152600860248201527f6572726f7220746f0000000000000000000000000000000000000000000000006044820152606401610b6d565b336000908152602080526040808220805460ff199081169091556001600160a01b03939093168252902080549091166001179055565b6000610eef83611552565b8210610f635760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610b6d565b506001600160a01b03919091166000908152601260209081526040808320938352929052205490565b610f94613b36565b60015b6028548111610feb57600083815260306020908152604080832084845290915290205460ff16828260d28110610fcf57610fcf614136565b9115156020909202015280610fe38161411b565b915050610f97565b50919050565b610cbf83838360405180602001604052806000815250611b31565b6016546001600160a01b031633146110665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b80604051602001611077919061414c565b604051602081830303815290604052601a908051906020019061109b929190613b55565b5050565b6016546001600160a01b031633146110f95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6002601754141561114c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b6d565b6002601755604080518082018252601c546001600160a01b039081168252601d541660208201528151808301909252601e5447926000918190606490611193908790614191565b61119d91906141c6565b8152602001606485601f546111b29190614191565b6111bc91906141c6565b9052905060005b60028110156112ab578281600281106111de576111de614136565b60200201516001600160a01b03166108fc83836002811061120157611201614136565b60200201516040518115909202916000818181858888f1935050505061122657600080fd5b81816002811061123857611238614136565b60200201517f8353ffcac0876ad14e226d9783c04540bfebf13871e868157d2a391cad98e91884836002811061127057611270614136565b602002015160405161129191906001600160a01b0391909116815260200190565b60405180910390a2806112a38161411b565b9150506111c3565b505060016017555050565b60006112c160145490565b82106113355760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610b6d565b6014828154811061134857611348614136565b90600052602060002001549050919050565b601d546001600160a01b031633146113b45760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b601d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155601f54604051918252907fd55c67f866c4c04a58b4b7e9e1cf11af5f87afbc2530cfde3c580d675cac8191906020015b60405180910390a250565b6000818152600e60205260408120546001600160a01b031680610a4f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610b6d565b606060006114bd83611552565b905060008167ffffffffffffffff8111156114da576114da613d95565b604051908082528060200260200182016040528015611503578160200160208202803683370190505b50905060005b8281101561154a5761151b8582610ee4565b82828151811061152d5761152d614136565b6020908102919091010152806115428161411b565b915050611509565b509392505050565b60006001600160a01b0382166115d05760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610b6d565b506001600160a01b03166000908152600f602052604090205490565b6016546001600160a01b031633146116465760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6116506000612829565b565b6016546001600160a01b031633146116ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b602f805460ff19166001179055565b60006025600081546116cc9061411b565b91905081905590506116e3602454826021546126fa565b6116ec81612893565b602f5460ff1661173e5760405162461bcd60e51b815260206004820152601860248201527f6572726f722067656e657369734d696e74416c6c6f77656400000000000000006044820152606401610b6d565b33600090815260208052604090205460ff1661179c5760405162461bcd60e51b815260206004820152600f60248201527f6572726f7220616c6c6f774c69737400000000000000000000000000000000006044820152606401610b6d565b34602a54146117ed5760405162461bcd60e51b815260206004820152601260248201527f6572726f722067656e65736973507269636500000000000000000000000000006044820152606401610b6d565b3360008181526020805260408120805460ff1916905560248054610d959392909190610d8c8361411b565b6016546001600160a01b031633146118725760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b8051806118c15760405162461bcd60e51b815260206004820152600960248201527f6572726f72206c656e00000000000000000000000000000000000000000000006044820152606401610b6d565b60005b81811015610cbf57602060008483815181106118e2576118e2614136565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611914576001611917565b60005b6020600085848151811061192d5761192d614136565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806119698161411b565b9150506118c4565b6016546001600160a01b031633146119cb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b60006025600081546119dc9061411b565b91905081905590506119f3602454826021546126fa565b6119fc81612893565b6024805461109b918491906000610d8c8361411b565b602660008154611a219061411b565b90915550611a2e826122d3565b611a3d602454836021546126fa565b6024805461109b918391906000610d8c8361411b565b6060600d8054610a64906140d0565b601c546001600160a01b03163314611abc5760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b601c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155601e54604051918252907fd55c67f866c4c04a58b4b7e9e1cf11af5f87afbc2530cfde3c580d675cac81919060200161141a565b61109b338383612a21565b611b3b3383611fdb565b611bad5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b6d565b611bb984848484612af0565b50505050565b6000818152600e60205260409020546060906001600160a01b0316611c4c5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610b6d565b610a4f82612b79565b6060601a8054610a64906140d0565b6016546001600160a01b03163314611cbe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b600060215411611d105760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b60008411611d605760405162461bcd60e51b815260206004820152600c60248201527f6572726f72205f65706f636800000000000000000000000000000000000000006044820152606401610b6d565b6024546027541015611db45760405162461bcd60e51b815260206004820152601460248201527f6572726f72206d6178546f6b656e537570706c790000000000000000000000006044820152606401610b6d565b60218490556023839055602d829055602e819055611dd0612bd4565b602154602354602d54602e5460408051938452602084019290925282820152517fe429a061e726c5f893806d65f0737ea93687ff05658c3a5d3ec6b23a04d3c9419181900360600190a250505050565b6016546001600160a01b03163314611e7a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6001600160a01b038116611ef65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b6d565b610d9581612829565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a4f5750610a4f82612c6f565b600081815260106020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091558190611fa282611425565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600e60205260408120546001600160a01b03166120655760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610b6d565b600061207083611425565b9050806001600160a01b0316846001600160a01b031614806120ab5750836001600160a01b03166120a084610ae7565b6001600160a01b0316145b806120db57506001600160a01b0380821660009081526011602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166120f682611425565b6001600160a01b0316146121725760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610b6d565b6001600160a01b0382166121ed5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b6d565b6121f8838383612d52565b612203600082611f55565b6001600160a01b0383166000908152600f6020526040812080546001929061222c9084906141da565b90915550506001600160a01b0382166000908152600f6020526040812080546001929061225a9084906141f1565b90915550506000818152600e602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000602c54116123255760405162461bcd60e51b815260206004820152601260248201527f6572726f7220626c6f636b47656e6573697300000000000000000000000000006044820152606401610b6d565b6000602d54116123775760405162461bcd60e51b815260206004820152600f60248201527f6572726f7220626c6f636b4d65746100000000000000000000000000000000006044820152606401610b6d565b6000602b54116123c95760405162461bcd60e51b815260206004820152601060248201527f6572726f7220626c6f636b4f6d656761000000000000000000000000000000006044820152606401610b6d565b602d5443106123e0576123da612d5d565b60016026555b602d54431080156123f5575060295460265411155b1561240a57602f805461ff0019166101001790555b602454602754101561245e5760405162461bcd60e51b815260206004820152601460248201527f6572726f72206d6178546f6b656e537570706c790000000000000000000000006044820152606401610b6d565b60006021541180156124735750602254602154105b6124bf5760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b336124c982611425565b6001600160a01b03161461251f5760405162461bcd60e51b815260206004820152600d60248201527f6572726f72206f776e65724f66000000000000000000000000000000000000006044820152606401610b6d565b602f54610100900460ff166125765760405162461bcd60e51b815260206004820152601b60248201527f6572726f722067656e65726174696f6e4d696e74416c6c6f77656400000000006044820152606401610b6d565b60295460265411156125ca5760405162461bcd60e51b815260206004820152601260248201527f6572726f722067656e65726174696f6e496400000000000000000000000000006044820152606401610b6d565b60008181527f686dc217b182b1fe88c7defdc5cd77807fc691ce05a160638669d7322051eee0602052604090205460ff166126475760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b602154600090815260306020908152604080832084845290915290205460ff16156126b45760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b60215460009081526030602090815260408083208484529091529020805460ff191660011790556029546026541415610d9557602f805461ff0019169055600060265550565b6127048382612e28565b61270f838383612fd8565b61271983826130b3565b6127238382613103565b600380549060006127338361411b565b9190505550505050565b807fa109ba539900bf1b633f956d63c96fc89b814c7287f7aa50a9216d0b5565720761276883612b79565b6040516127759190613c98565b60405180910390a2601b54612793906001600160a01b031682613153565b602154604051439183917f5d2845c74a4574297574ee578da4d65786a4dbf9463ea1804b22b2c2c64fb4f790600090a4601b546040805160208101909152600081526127ec916001600160a01b03169084908490612af0565b6021546040516001600160a01b0384169183917f259eb7b480b3d449f506927269e4665c83c69e4cd797143eaa8f84632dc7a02b90600090a45050565b601680546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b602154156128e35760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b60285460255411156129375760405162461bcd60e51b815260206004820152600f60248201527f6572726f722067656e65736973496400000000000000000000000000000000006044820152606401610b6d565b602154600090815260306020908152604080832084845290915290205460ff16156129a45760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b60215460009081526030602090815260408083208484529091529020805460ff191660011790556028546025541415610d955743602c819055602d819055602154604051918252907fe559639e5f0abd25b32a111f3613319a30983ce2b2e20856119686a35fdbd0a69060200160405180910390a2610d95612d5d565b816001600160a01b0316836001600160a01b03161415612a835760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b6d565b6001600160a01b03838116600081815260116020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612afb8484846120e3565b612b078484848461316d565b611bb95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b60606002612bad612b898461330b565b604051602001612b999190614209565b60405160208183030381529060405261334a565b604051602001612bbe9291906142be565b6040516020818303038152906040529050919050565b60235460009081905b602254831015610cbf578215612bfd57602e54612bfa9082614191565b90505b8260091415612c515781602c54612c1491906141f1565b602b8190556040519081527f149f31bf4e26f1f31339fab90ed780caa2d00b9f06c89ac475776a5bd3c7d58e9060200160405180910390a1505050565b612c5b81836141f1565b915082612c678161411b565b935050612bdd565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612d0257507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a4f57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a4f565b610cbf838383613505565b602154612d6c57612d6c612bd4565b60215415612d8e57602e5460236000828254612d889190614191565b90915550505b602354602d6000828254612da291906141f1565b9091555050602154602d546040519081527f3bd829f14cf58e594b8eeb192fb124cbac882efaf36deb370a4d14174f6206d39060200160405180910390a260218054906000612df08361411b565b9190505550602d544310158015612e0a5750602254602154105b15612e1757612e17612d5d565b602f805461ff001916610100179055565b60008115612f6057612e43612e3e8360016141f1565b6135bd565b612e4e8360016141f1565b600214612f0457612e608360016141f1565b600314612ec9576003612e748460016141f1565b11612e8e5760405180602001604052806000815250612f3b565b6040518060400160405280600281526020017f7468000000000000000000000000000000000000000000000000000000000000815250612f3b565b6040518060400160405280600281526020017f7264000000000000000000000000000000000000000000000000000000000000815250612f3b565b6040518060400160405280600281526020017f6e640000000000000000000000000000000000000000000000000000000000008152505b604051602001612f4c9291906142e3565b604051602081830303815290604052612f97565b6040518060400160405280600f81526020017f47656e657369732045646974696f6e00000000000000000000000000000000008152505b604051602001612fa892919061433a565b60408051601f198184030181529181526000848152600860209081529190208251610cbf93919290910190613b55565b801561301057612fec612e3e8260016141f1565b604051602001612ffc9190614388565b60405160208183030381529060405261302a565b6040518060600160405280602b815260200161494e602b91395b811561304e576040518060600160405280602e81526020016149b9602e9139613068565b6040518060600160405280602e8152602001614920602e91395b613071846136ef565b6040516020016130839392919061441a565b60408051601f198184030181529181526000858152600960209081529190208251611bb993919290910190613b55565b80156130c05760056130c3565b60045b6040516020016130d391906145e3565b60408051601f198184030181529181526000848152600a60209081529190208251610cbf93919290910190613b55565b8015613110576007613113565b60065b60405160200161312391906145e3565b60408051601f198184030181529181526000848152600b60209081529190208251610cbf93919290910190613b55565b61109b8282604051806020016040528060008152506137b7565b60006001600160a01b0384163b15613300576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906131ca903390899088908890600401614615565b6020604051808303816000875af1925050508015613205575060408051601f3d908101601f1916820190925261320291810190614647565b60015b6132b5573d808015613233576040519150601f19603f3d011682016040523d82523d6000602084013e613238565b606091505b5080516132ad5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506120db565b506001949350505050565b600081815260086020908152604080832060098352818420600a8452828520600b8552948390209251606095612bbe9593946001949192909101614664565b80516060908061336a575050604080516020810190915260008152919050565b600060036133798360026141f1565b61338391906141c6565b61338e906004614191565b9050600061339d8260206141f1565b67ffffffffffffffff8111156133b5576133b5613d95565b6040519080825280601f01601f1916602001820160405280156133df576020820181803683370190505b5090506000604051806060016040528060408152602001614979604091399050600181016020830160005b8681101561346b576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b83526004909201910161340a565b50600386066001811461348557600281146134cf576134f7565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8301526134f7565b7f3d000000000000000000000000000000000000000000000000000000000000006000198301525b505050918152949350505050565b6001600160a01b0383166135605761355b81601480546000838152601560205260408120829055600182018355919091527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0155565b613583565b816001600160a01b0316836001600160a01b031614613583576135838382613840565b6001600160a01b03821661359a57610cbf816138dd565b826001600160a01b0316826001600160a01b031614610cbf57610cbf828261398c565b6060816135fd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561362757806136118161411b565b91506136209050600a836141c6565b9150613601565b60008167ffffffffffffffff81111561364257613642613d95565b6040519080825280601f01601f19166020018201604052801561366c576020820181803683370190505b5090505b84156120db576136816001836141da565b915061368e600a86614833565b6136999060306141f1565b60f81b8183815181106136ae576136ae614136565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506136e8600a866141c6565b9450613670565b6060806103e883101561372757613705836135bd565b6040516020016137159190614209565b60405160208183030381529060405290505b606483101561375b57613739836135bd565b6040516020016137499190614847565b60405160208183030381529060405290505b600a83101561378f5761376d836135bd565b60405160200161377d919061488c565b60405160208183030381529060405290505b806040516020016137a091906148d1565b604051602081830303815290604052915050919050565b6137c183836139d0565b6137ce600084848461316d565b610cbf5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b6000600161384d84611552565b61385791906141da565b6000838152601360205260409020549091508082146138aa576001600160a01b03841660009081526012602090815260408083208584528252808320548484528184208190558352601390915290208190555b5060009182526013602090815260408084208490556001600160a01b039094168352601281528383209183525290812055565b6014546000906138ef906001906141da565b6000838152601560205260408120546014805493945090928490811061391757613917614136565b90600052602060002001549050806014838154811061393857613938614136565b600091825260208083209091019290925582815260159091526040808220849055858252812055601480548061397057613970614909565b6001900381819060005260206000200160009055905550505050565b600061399783611552565b6001600160a01b039093166000908152601260209081526040808320868452825280832085905593825260139052919091209190915550565b6001600160a01b038216613a265760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b6d565b6000818152600e60205260409020546001600160a01b031615613a8b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b6d565b613a9760008383612d52565b6001600160a01b0382166000908152600f60205260408120805460019290613ac09084906141f1565b90915550506000818152600e602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60405180611a40016040528060d2906020820280368337509192915050565b828054613b61906140d0565b90600052602060002090601f016020900481019282613b835760008555613bc9565b82601f10613b9c57805160ff1916838001178555613bc9565b82800160010185558215613bc9579182015b82811115613bc9578251825591602001919060010190613bae565b50613bd5929150613bd9565b5090565b5b80821115613bd55760008155600101613bda565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d9557600080fd5b600060208284031215613c2e57600080fd5b8135613c3981613bee565b9392505050565b60005b83811015613c5b578181015183820152602001613c43565b83811115611bb95750506000910152565b60008151808452613c84816020860160208601613c40565b601f01601f19169290920160200192915050565b602081526000613c396020830184613c6c565b600060208284031215613cbd57600080fd5b5035919050565b80356001600160a01b0381168114613cdb57600080fd5b919050565b60008060408385031215613cf357600080fd5b613cfc83613cc4565b946020939093013593505050565b600080600060608486031215613d1f57600080fd5b613d2884613cc4565b9250613d3660208501613cc4565b9150604084013590509250925092565b600060208284031215613d5857600080fd5b613c3982613cc4565b611a408101818360005b60d2811015613d8c5781511515835260209283019290910190600101613d6b565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613dd457613dd4613d95565b604052919050565b600067ffffffffffffffff831115613df657613df6613d95565b613e096020601f19601f86011601613dab565b9050828152838383011115613e1d57600080fd5b828260208301376000602084830101529392505050565b600060208284031215613e4657600080fd5b813567ffffffffffffffff811115613e5d57600080fd5b8201601f81018413613e6e57600080fd5b6120db84823560208401613ddc565b6020808252825182820181905260009190848201906040850190845b81811015613eb557835183529284019291840191600101613e99565b50909695505050505050565b60006020808385031215613ed457600080fd5b823567ffffffffffffffff80821115613eec57600080fd5b818501915085601f830112613f0057600080fd5b813581811115613f1257613f12613d95565b8060051b9150613f23848301613dab565b8181529183018401918481019088841115613f3d57600080fd5b938501935b83851015613f6257613f5385613cc4565b82529385019390850190613f42565b98975050505050505050565b60008060408385031215613f8157600080fd5b82359150613f9160208401613cc4565b90509250929050565b60008060408385031215613fad57600080fd5b613fb683613cc4565b915060208301358015158114613fcb57600080fd5b809150509250929050565b60008060408385031215613fe957600080fd5b50508035926020909101359150565b6000806000806080858703121561400e57600080fd5b61401785613cc4565b935061402560208601613cc4565b925060408501359150606085013567ffffffffffffffff81111561404857600080fd5b8501601f8101871361405957600080fd5b61406887823560208401613ddc565b91505092959194509250565b6000806040838503121561408757600080fd5b61409083613cc4565b9150613f9160208401613cc4565b600080600080608085870312156140b457600080fd5b5050823594602084013594506040840135936060013592509050565b600181811c908216806140e457607f821691505b60208210811415610feb57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561412f5761412f614105565b5060010190565b634e487b7160e01b600052603260045260246000fd5b7f697066733a2f2f00000000000000000000000000000000000000000000000000815260008251614184816007850160208701613c40565b9190910160070192915050565b60008160001904831182151516156141ab576141ab614105565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826141d5576141d56141b0565b500490565b6000828210156141ec576141ec614105565b500390565b6000821982111561420457614204614105565b500190565b6000825161421b818460208701613c40565b9190910192915050565b8054600090600181811c908083168061423f57607f831692505b602080841082141561426157634e487b7160e01b600052602260045260246000fd5b8180156142755760018114614286576142b2565b60ff198616895284890196506142b2565b876000528160002060005b868110156142aa5781548b820152908501908301614291565b505084890196505b50505050505092915050565b60006142ca8285614225565b83516142da818360208801613c40565b01949350505050565b600083516142f5818460208801613c40565b835190830190614309818360208801613c40565b7f2045646974696f6e0000000000000000000000000000000000000000000000009101908152600801949350505050565b60006143468285614225565b7f202d2000000000000000000000000000000000000000000000000000000000008152835161437c816003840160208801613c40565b01600301949350505050565b7f7b2274726169745f74797065223a2245646974696f6e222c2276616c7565223a81527f22230000000000000000000000000000000000000000000000000000000000006020820152600082516143e6816022850160208701613c40565b7f227d2c00000000000000000000000000000000000000000000000000000000006022939091019283015250602501919050565b6000845161442c818460208901613c40565b845190830190614440818360208901613c40565b7f7b2274726169745f74797065223a2253657269616c222c2276616c7565223a2291019081528351614479816020808501908801613c40565b7f227d2c0000000000000000000000000000000000000000000000000000000000910160208101919091527f7b2274726169745f74797065223a22436861726163746572222c2276616c756560238201527f223a22446f7269616e204e616b616d6f746f227d2c000000000000000000000060438201527f7b2274726169745f74797065223a22456666656374222c2276616c7565223a2260588201527f42525252227d2c0000000000000000000000000000000000000000000000000060788201527f7b2274726169745f74797065223a2255534420506f727472616974222c227661607f8201527f6c7565223a222331202d2057686f206973205361746f736869227d2c00000000609f8201527f7b2274726169745f74797065223a224d656469756d222c2276616c7565223a2260bb8201527f446f6c6c61722062696c6c7320676c756564206f6e2063616e766173227d000060db82015260f981015b9695505050505050565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000613c396007830184614225565b60006001600160a01b038087168352808616602084015250836040830152608060608301526145d96080830184613c6c565b60006020828403121561465957600080fd5b8151613c3981613bee565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226e616d65223a22000000000000000000000000000000000000000000000000600182015260006146bc6009830188614225565b7f222c0000000000000000000000000000000000000000000000000000000000008082527f226465736372697074696f6e223a22000000000000000000000000000000000060028301526147136011830189614225565b91508082527f2261747472696275746573223a5b000000000000000000000000000000000000600283015261474b6010830188614225565b91507f5d2c00000000000000000000000000000000000000000000000000000000000082527f22696d616765223a22000000000000000000000000000000000000000000000060028301526147a3600b830187614225565b9081527f22616e696d6174696f6e5f75726c223a22000000000000000000000000000000600282015290506147db6013820185614225565b7f220000000000000000000000000000000000000000000000000000000000000081527f7d00000000000000000000000000000000000000000000000000000000000000600182015260020198975050505050505050565b600082614842576148426141b0565b500690565b7f300000000000000000000000000000000000000000000000000000000000000081526000825161487f816001850160208701613c40565b9190910160010192915050565b7f30300000000000000000000000000000000000000000000000000000000000008152600082516148c4816002850160208701613c40565b9190910160020192915050565b7f230000000000000000000000000000000000000000000000000000000000000081526000825161487f816001850160208701613c40565b634e487b7160e01b600052603160045260246000fdfe7b2274726169745f74797065223a224e46542054797065222c2276616c7565223a2247656e657261746f72227d2c7b2274726169745f74797065223a2245646974696f6e222c2276616c7565223a2247656e65736973227d2c4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f7b2274726169745f74797065223a224e46542054797065222c2276616c7565223a2247656e657261746564227d2ca2646970667358221220627efb7c58e0f1a820013031c32ab417b2b86eb0e16948f99bf7e29ad6e5040764736f6c634300080a0033516d526d766f3177447853563275426d314b4e714a397a365561797a69636b4c4b684d4b4a596664684d47436266516d5742415337706d5262575a5133776b6975773931387a56747a396553366f616a706b7139685556424669776f4d756c7469706c652045646974696f6e202d20446f6c6c617273204e616b616d6f746f2062792050617363616c20426f796172742069732061206661726d696e67204e465420636f6c6c656374696f6e206261736564206f6e20746865206f726967696e616c20617274776f726b206d61646520776974682068756e6472656473206f66207265616c205553442042696c6c7320676c756564206f6e2063616e76617320696e20323031382e516d5a3731616a64485053374e6f66624b3372704e414a716e787132396d66644e53506165637933624855443947516d503361734a784d62434d724e3661444b4e34695a7063554a77327a454854664a755638736835586855534176

Deployed Bytecode

0x6080604052600436106103765760003560e01c8063728cce7c116101d1578063a348f57011610102578063d20bc0a5116100a0578063e985e9c51161006f578063e985e9c51461099b578063ed750f45146109e4578063eed8367d14610a04578063f2fde38b14610a2457600080fd5b8063d20bc0a51461093b578063d258941f1461095a578063d2b3996f14610970578063e8a3d4851461098657600080fd5b8063b88d4fde116100dc578063b88d4fde146108c5578063c0220347146108e5578063c87b56dd14610905578063cd08bdf71461092557600080fd5b8063a348f5701461085e578063a660ab6414610874578063b10e1c6c146108af57600080fd5b806385e11dfc1161016f578063900cf0cf11610149578063900cf0cf146107f357806395d89b4114610809578063a1470e1a1461081e578063a22cb4651461083e57600080fd5b806385e11dfc1461079f578063899486e1146107b55780638da5cb5b146107d557600080fd5b80637b2469fd116101ab5780637b2469fd1461072f57806382f785321461074957806383c1c69f14610769578063842b83fa1461078957600080fd5b8063728cce7c146106fc57806374da546b1461071257806378c3a6921461072757600080fd5b806337496f40116102ab5780635ccba0521161024957806364ca6e201161022357806364ca6e201461068457806369013efa1461069a57806370a08231146106c7578063715018a6146106e757600080fd5b80635ccba052146106155780635dce15a9146106445780636352211e1461066457600080fd5b806348a7e4661161028557806348a7e466146105aa5780634b423d02146105ca5780634f6ccce7146105df57806350f7c204146105ff57600080fd5b806337496f401461054757806342842e0e1461057457806346e46e2a1461059457600080fd5b80631dc2fd6d116103185780632445391a116102f25780632445391a146104db5780632685fd14146104fb57806327827ae8146105115780632f745c591461052757600080fd5b80631dc2fd6d1461048557806323b872dd1461049b57806323bb02f1146104bb57600080fd5b8063081812fc11610354578063081812fc1461040a578063095ea7b31461042a57806317d70f7c1461044c57806318160ddd1461047057600080fd5b806301ffc9a71461037b578063060bd1d4146103b057806306fdde03146103e8575b600080fd5b34801561038757600080fd5b5061039b610396366004613c1c565b610a44565b60405190151581526020015b60405180910390f35b3480156103bc57600080fd5b50601c546103d0906001600160a01b031681565b6040516001600160a01b0390911681526020016103a7565b3480156103f457600080fd5b506103fd610a55565b6040516103a79190613c98565b34801561041657600080fd5b506103d0610425366004613cab565b610ae7565b34801561043657600080fd5b5061044a610445366004613ce0565b610b92565b005b34801561045857600080fd5b5061046260245481565b6040519081526020016103a7565b34801561047c57600080fd5b50601454610462565b34801561049157600080fd5b50610462602b5481565b3480156104a757600080fd5b5061044a6104b6366004613d0a565b610cc4565b3480156104c757600080fd5b5061044a6104d6366004613cab565b610d4b565b3480156104e757600080fd5b5061044a6104f6366004613d46565b610d98565b34801561050757600080fd5b50610462601e5481565b34801561051d57600080fd5b50610462601f5481565b34801561053357600080fd5b50610462610542366004613ce0565b610ee4565b34801561055357600080fd5b50610567610562366004613cab565b610f8c565b6040516103a79190613d61565b34801561058057600080fd5b5061044a61058f366004613d0a565b610ff1565b3480156105a057600080fd5b50610462602c5481565b3480156105b657600080fd5b5061044a6105c5366004613e34565b61100c565b3480156105d657600080fd5b5061044a61109f565b3480156105eb57600080fd5b506104626105fa366004613cab565b6112b6565b34801561060b57600080fd5b5061046260275481565b34801561062157600080fd5b5061039b610630366004613d46565b602080526000908152604090205460ff1681565b34801561065057600080fd5b5061044a61065f366004613d46565b61135a565b34801561067057600080fd5b506103d061067f366004613cab565b611425565b34801561069057600080fd5b5061046260265481565b3480156106a657600080fd5b506106ba6106b5366004613d46565b6114b0565b6040516103a79190613e7d565b3480156106d357600080fd5b506104626106e2366004613d46565b611552565b3480156106f357600080fd5b5061044a6115ec565b34801561070857600080fd5b50610462602a5481565b34801561071e57600080fd5b5061044a611652565b61044a6116bb565b34801561073b57600080fd5b50602f5461039b9060ff1681565b34801561075557600080fd5b5061044a610764366004613ec1565b611818565b34801561077557600080fd5b5061044a610784366004613d46565b611971565b34801561079557600080fd5b5061046260285481565b3480156107ab57600080fd5b5061046260255481565b3480156107c157600080fd5b5061044a6107d0366004613f6e565b611a12565b3480156107e157600080fd5b506016546001600160a01b03166103d0565b3480156107ff57600080fd5b5061046260215481565b34801561081557600080fd5b506103fd611a53565b34801561082a57600080fd5b5061044a610839366004613d46565b611a62565b34801561084a57600080fd5b5061044a610859366004613f9a565b611b26565b34801561086a57600080fd5b5061046260225481565b34801561088057600080fd5b5061039b61088f366004613fd6565b603060209081526000928352604080842090915290825290205460ff1681565b3480156108bb57600080fd5b50610462602d5481565b3480156108d157600080fd5b5061044a6108e0366004613ff8565b611b31565b3480156108f157600080fd5b50601d546103d0906001600160a01b031681565b34801561091157600080fd5b506103fd610920366004613cab565b611bbf565b34801561093157600080fd5b50610462602e5481565b34801561094757600080fd5b50602f5461039b90610100900460ff1681565b34801561096657600080fd5b5061046260295481565b34801561097c57600080fd5b5061046260235481565b34801561099257600080fd5b506103fd611c55565b3480156109a757600080fd5b5061039b6109b6366004614074565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205460ff1690565b3480156109f057600080fd5b50601b546103d0906001600160a01b031681565b348015610a1057600080fd5b5061044a610a1f36600461409e565b611c64565b348015610a3057600080fd5b5061044a610a3f366004613d46565b611e20565b6000610a4f82611eff565b92915050565b6060600c8054610a64906140d0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a90906140d0565b8015610add5780601f10610ab257610100808354040283529160200191610add565b820191906000526020600020905b815481529060010190602001808311610ac057829003601f168201915b5050505050905090565b6000818152600e60205260408120546001600160a01b0316610b765760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152601060205260409020546001600160a01b031690565b6000610b9d82611425565b9050806001600160a01b0316836001600160a01b03161415610c275760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610b6d565b336001600160a01b0382161480610c435750610c4381336109b6565b610cb55760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b6d565b610cbf8383611f55565b505050565b610cce3382611fdb565b610d405760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b6d565b610cbf8383836120e3565b602660008154610d5a9061411b565b90915550610d67816122d3565b610d76602454826021546126fa565b60248054610d95913391906000610d8c8361411b565b9190505561273d565b50565b60215415610de85760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b33600090815260208052604090205460ff16610e465760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b6001600160a01b038116600090815260208052604090205460ff1615610eae5760405162461bcd60e51b815260206004820152600860248201527f6572726f7220746f0000000000000000000000000000000000000000000000006044820152606401610b6d565b336000908152602080526040808220805460ff199081169091556001600160a01b03939093168252902080549091166001179055565b6000610eef83611552565b8210610f635760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610b6d565b506001600160a01b03919091166000908152601260209081526040808320938352929052205490565b610f94613b36565b60015b6028548111610feb57600083815260306020908152604080832084845290915290205460ff16828260d28110610fcf57610fcf614136565b9115156020909202015280610fe38161411b565b915050610f97565b50919050565b610cbf83838360405180602001604052806000815250611b31565b6016546001600160a01b031633146110665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b80604051602001611077919061414c565b604051602081830303815290604052601a908051906020019061109b929190613b55565b5050565b6016546001600160a01b031633146110f95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6002601754141561114c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b6d565b6002601755604080518082018252601c546001600160a01b039081168252601d541660208201528151808301909252601e5447926000918190606490611193908790614191565b61119d91906141c6565b8152602001606485601f546111b29190614191565b6111bc91906141c6565b9052905060005b60028110156112ab578281600281106111de576111de614136565b60200201516001600160a01b03166108fc83836002811061120157611201614136565b60200201516040518115909202916000818181858888f1935050505061122657600080fd5b81816002811061123857611238614136565b60200201517f8353ffcac0876ad14e226d9783c04540bfebf13871e868157d2a391cad98e91884836002811061127057611270614136565b602002015160405161129191906001600160a01b0391909116815260200190565b60405180910390a2806112a38161411b565b9150506111c3565b505060016017555050565b60006112c160145490565b82106113355760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610b6d565b6014828154811061134857611348614136565b90600052602060002001549050919050565b601d546001600160a01b031633146113b45760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b601d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155601f54604051918252907fd55c67f866c4c04a58b4b7e9e1cf11af5f87afbc2530cfde3c580d675cac8191906020015b60405180910390a250565b6000818152600e60205260408120546001600160a01b031680610a4f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610b6d565b606060006114bd83611552565b905060008167ffffffffffffffff8111156114da576114da613d95565b604051908082528060200260200182016040528015611503578160200160208202803683370190505b50905060005b8281101561154a5761151b8582610ee4565b82828151811061152d5761152d614136565b6020908102919091010152806115428161411b565b915050611509565b509392505050565b60006001600160a01b0382166115d05760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610b6d565b506001600160a01b03166000908152600f602052604090205490565b6016546001600160a01b031633146116465760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6116506000612829565b565b6016546001600160a01b031633146116ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b602f805460ff19166001179055565b60006025600081546116cc9061411b565b91905081905590506116e3602454826021546126fa565b6116ec81612893565b602f5460ff1661173e5760405162461bcd60e51b815260206004820152601860248201527f6572726f722067656e657369734d696e74416c6c6f77656400000000000000006044820152606401610b6d565b33600090815260208052604090205460ff1661179c5760405162461bcd60e51b815260206004820152600f60248201527f6572726f7220616c6c6f774c69737400000000000000000000000000000000006044820152606401610b6d565b34602a54146117ed5760405162461bcd60e51b815260206004820152601260248201527f6572726f722067656e65736973507269636500000000000000000000000000006044820152606401610b6d565b3360008181526020805260408120805460ff1916905560248054610d959392909190610d8c8361411b565b6016546001600160a01b031633146118725760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b8051806118c15760405162461bcd60e51b815260206004820152600960248201527f6572726f72206c656e00000000000000000000000000000000000000000000006044820152606401610b6d565b60005b81811015610cbf57602060008483815181106118e2576118e2614136565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611914576001611917565b60005b6020600085848151811061192d5761192d614136565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806119698161411b565b9150506118c4565b6016546001600160a01b031633146119cb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b60006025600081546119dc9061411b565b91905081905590506119f3602454826021546126fa565b6119fc81612893565b6024805461109b918491906000610d8c8361411b565b602660008154611a219061411b565b90915550611a2e826122d3565b611a3d602454836021546126fa565b6024805461109b918391906000610d8c8361411b565b6060600d8054610a64906140d0565b601c546001600160a01b03163314611abc5760405162461bcd60e51b815260206004820152601060248201527f6572726f72206d73672e73656e646572000000000000000000000000000000006044820152606401610b6d565b601c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117909155601e54604051918252907fd55c67f866c4c04a58b4b7e9e1cf11af5f87afbc2530cfde3c580d675cac81919060200161141a565b61109b338383612a21565b611b3b3383611fdb565b611bad5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b6d565b611bb984848484612af0565b50505050565b6000818152600e60205260409020546060906001600160a01b0316611c4c5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610b6d565b610a4f82612b79565b6060601a8054610a64906140d0565b6016546001600160a01b03163314611cbe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b600060215411611d105760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b60008411611d605760405162461bcd60e51b815260206004820152600c60248201527f6572726f72205f65706f636800000000000000000000000000000000000000006044820152606401610b6d565b6024546027541015611db45760405162461bcd60e51b815260206004820152601460248201527f6572726f72206d6178546f6b656e537570706c790000000000000000000000006044820152606401610b6d565b60218490556023839055602d829055602e819055611dd0612bd4565b602154602354602d54602e5460408051938452602084019290925282820152517fe429a061e726c5f893806d65f0737ea93687ff05658c3a5d3ec6b23a04d3c9419181900360600190a250505050565b6016546001600160a01b03163314611e7a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b6d565b6001600160a01b038116611ef65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b6d565b610d9581612829565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a4f5750610a4f82612c6f565b600081815260106020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091558190611fa282611425565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600e60205260408120546001600160a01b03166120655760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610b6d565b600061207083611425565b9050806001600160a01b0316846001600160a01b031614806120ab5750836001600160a01b03166120a084610ae7565b6001600160a01b0316145b806120db57506001600160a01b0380821660009081526011602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166120f682611425565b6001600160a01b0316146121725760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610b6d565b6001600160a01b0382166121ed5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b6d565b6121f8838383612d52565b612203600082611f55565b6001600160a01b0383166000908152600f6020526040812080546001929061222c9084906141da565b90915550506001600160a01b0382166000908152600f6020526040812080546001929061225a9084906141f1565b90915550506000818152600e602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000602c54116123255760405162461bcd60e51b815260206004820152601260248201527f6572726f7220626c6f636b47656e6573697300000000000000000000000000006044820152606401610b6d565b6000602d54116123775760405162461bcd60e51b815260206004820152600f60248201527f6572726f7220626c6f636b4d65746100000000000000000000000000000000006044820152606401610b6d565b6000602b54116123c95760405162461bcd60e51b815260206004820152601060248201527f6572726f7220626c6f636b4f6d656761000000000000000000000000000000006044820152606401610b6d565b602d5443106123e0576123da612d5d565b60016026555b602d54431080156123f5575060295460265411155b1561240a57602f805461ff0019166101001790555b602454602754101561245e5760405162461bcd60e51b815260206004820152601460248201527f6572726f72206d6178546f6b656e537570706c790000000000000000000000006044820152606401610b6d565b60006021541180156124735750602254602154105b6124bf5760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b336124c982611425565b6001600160a01b03161461251f5760405162461bcd60e51b815260206004820152600d60248201527f6572726f72206f776e65724f66000000000000000000000000000000000000006044820152606401610b6d565b602f54610100900460ff166125765760405162461bcd60e51b815260206004820152601b60248201527f6572726f722067656e65726174696f6e4d696e74416c6c6f77656400000000006044820152606401610b6d565b60295460265411156125ca5760405162461bcd60e51b815260206004820152601260248201527f6572726f722067656e65726174696f6e496400000000000000000000000000006044820152606401610b6d565b60008181527f686dc217b182b1fe88c7defdc5cd77807fc691ce05a160638669d7322051eee0602052604090205460ff166126475760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b602154600090815260306020908152604080832084845290915290205460ff16156126b45760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b60215460009081526030602090815260408083208484529091529020805460ff191660011790556029546026541415610d9557602f805461ff0019169055600060265550565b6127048382612e28565b61270f838383612fd8565b61271983826130b3565b6127238382613103565b600380549060006127338361411b565b9190505550505050565b807fa109ba539900bf1b633f956d63c96fc89b814c7287f7aa50a9216d0b5565720761276883612b79565b6040516127759190613c98565b60405180910390a2601b54612793906001600160a01b031682613153565b602154604051439183917f5d2845c74a4574297574ee578da4d65786a4dbf9463ea1804b22b2c2c64fb4f790600090a4601b546040805160208101909152600081526127ec916001600160a01b03169084908490612af0565b6021546040516001600160a01b0384169183917f259eb7b480b3d449f506927269e4665c83c69e4cd797143eaa8f84632dc7a02b90600090a45050565b601680546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b602154156128e35760405162461bcd60e51b815260206004820152600b60248201527f6572726f722065706f63680000000000000000000000000000000000000000006044820152606401610b6d565b60285460255411156129375760405162461bcd60e51b815260206004820152600f60248201527f6572726f722067656e65736973496400000000000000000000000000000000006044820152606401610b6d565b602154600090815260306020908152604080832084845290915290205460ff16156129a45760405162461bcd60e51b815260206004820152601a60248201527f6572726f722065706f63684d696e74696e6752656769737472790000000000006044820152606401610b6d565b60215460009081526030602090815260408083208484529091529020805460ff191660011790556028546025541415610d955743602c819055602d819055602154604051918252907fe559639e5f0abd25b32a111f3613319a30983ce2b2e20856119686a35fdbd0a69060200160405180910390a2610d95612d5d565b816001600160a01b0316836001600160a01b03161415612a835760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b6d565b6001600160a01b03838116600081815260116020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612afb8484846120e3565b612b078484848461316d565b611bb95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b60606002612bad612b898461330b565b604051602001612b999190614209565b60405160208183030381529060405261334a565b604051602001612bbe9291906142be565b6040516020818303038152906040529050919050565b60235460009081905b602254831015610cbf578215612bfd57602e54612bfa9082614191565b90505b8260091415612c515781602c54612c1491906141f1565b602b8190556040519081527f149f31bf4e26f1f31339fab90ed780caa2d00b9f06c89ac475776a5bd3c7d58e9060200160405180910390a1505050565b612c5b81836141f1565b915082612c678161411b565b935050612bdd565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612d0257507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a4f57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a4f565b610cbf838383613505565b602154612d6c57612d6c612bd4565b60215415612d8e57602e5460236000828254612d889190614191565b90915550505b602354602d6000828254612da291906141f1565b9091555050602154602d546040519081527f3bd829f14cf58e594b8eeb192fb124cbac882efaf36deb370a4d14174f6206d39060200160405180910390a260218054906000612df08361411b565b9190505550602d544310158015612e0a5750602254602154105b15612e1757612e17612d5d565b602f805461ff001916610100179055565b60008115612f6057612e43612e3e8360016141f1565b6135bd565b612e4e8360016141f1565b600214612f0457612e608360016141f1565b600314612ec9576003612e748460016141f1565b11612e8e5760405180602001604052806000815250612f3b565b6040518060400160405280600281526020017f7468000000000000000000000000000000000000000000000000000000000000815250612f3b565b6040518060400160405280600281526020017f7264000000000000000000000000000000000000000000000000000000000000815250612f3b565b6040518060400160405280600281526020017f6e640000000000000000000000000000000000000000000000000000000000008152505b604051602001612f4c9291906142e3565b604051602081830303815290604052612f97565b6040518060400160405280600f81526020017f47656e657369732045646974696f6e00000000000000000000000000000000008152505b604051602001612fa892919061433a565b60408051601f198184030181529181526000848152600860209081529190208251610cbf93919290910190613b55565b801561301057612fec612e3e8260016141f1565b604051602001612ffc9190614388565b60405160208183030381529060405261302a565b6040518060600160405280602b815260200161494e602b91395b811561304e576040518060600160405280602e81526020016149b9602e9139613068565b6040518060600160405280602e8152602001614920602e91395b613071846136ef565b6040516020016130839392919061441a565b60408051601f198184030181529181526000858152600960209081529190208251611bb993919290910190613b55565b80156130c05760056130c3565b60045b6040516020016130d391906145e3565b60408051601f198184030181529181526000848152600a60209081529190208251610cbf93919290910190613b55565b8015613110576007613113565b60065b60405160200161312391906145e3565b60408051601f198184030181529181526000848152600b60209081529190208251610cbf93919290910190613b55565b61109b8282604051806020016040528060008152506137b7565b60006001600160a01b0384163b15613300576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906131ca903390899088908890600401614615565b6020604051808303816000875af1925050508015613205575060408051601f3d908101601f1916820190925261320291810190614647565b60015b6132b5573d808015613233576040519150601f19603f3d011682016040523d82523d6000602084013e613238565b606091505b5080516132ad5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506120db565b506001949350505050565b600081815260086020908152604080832060098352818420600a8452828520600b8552948390209251606095612bbe9593946001949192909101614664565b80516060908061336a575050604080516020810190915260008152919050565b600060036133798360026141f1565b61338391906141c6565b61338e906004614191565b9050600061339d8260206141f1565b67ffffffffffffffff8111156133b5576133b5613d95565b6040519080825280601f01601f1916602001820160405280156133df576020820181803683370190505b5090506000604051806060016040528060408152602001614979604091399050600181016020830160005b8681101561346b576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b83526004909201910161340a565b50600386066001811461348557600281146134cf576134f7565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8301526134f7565b7f3d000000000000000000000000000000000000000000000000000000000000006000198301525b505050918152949350505050565b6001600160a01b0383166135605761355b81601480546000838152601560205260408120829055600182018355919091527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0155565b613583565b816001600160a01b0316836001600160a01b031614613583576135838382613840565b6001600160a01b03821661359a57610cbf816138dd565b826001600160a01b0316826001600160a01b031614610cbf57610cbf828261398c565b6060816135fd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561362757806136118161411b565b91506136209050600a836141c6565b9150613601565b60008167ffffffffffffffff81111561364257613642613d95565b6040519080825280601f01601f19166020018201604052801561366c576020820181803683370190505b5090505b84156120db576136816001836141da565b915061368e600a86614833565b6136999060306141f1565b60f81b8183815181106136ae576136ae614136565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506136e8600a866141c6565b9450613670565b6060806103e883101561372757613705836135bd565b6040516020016137159190614209565b60405160208183030381529060405290505b606483101561375b57613739836135bd565b6040516020016137499190614847565b60405160208183030381529060405290505b600a83101561378f5761376d836135bd565b60405160200161377d919061488c565b60405160208183030381529060405290505b806040516020016137a091906148d1565b604051602081830303815290604052915050919050565b6137c183836139d0565b6137ce600084848461316d565b610cbf5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b6d565b6000600161384d84611552565b61385791906141da565b6000838152601360205260409020549091508082146138aa576001600160a01b03841660009081526012602090815260408083208584528252808320548484528184208190558352601390915290208190555b5060009182526013602090815260408084208490556001600160a01b039094168352601281528383209183525290812055565b6014546000906138ef906001906141da565b6000838152601560205260408120546014805493945090928490811061391757613917614136565b90600052602060002001549050806014838154811061393857613938614136565b600091825260208083209091019290925582815260159091526040808220849055858252812055601480548061397057613970614909565b6001900381819060005260206000200160009055905550505050565b600061399783611552565b6001600160a01b039093166000908152601260209081526040808320868452825280832085905593825260139052919091209190915550565b6001600160a01b038216613a265760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b6d565b6000818152600e60205260409020546001600160a01b031615613a8b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b6d565b613a9760008383612d52565b6001600160a01b0382166000908152600f60205260408120805460019290613ac09084906141f1565b90915550506000818152600e602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60405180611a40016040528060d2906020820280368337509192915050565b828054613b61906140d0565b90600052602060002090601f016020900481019282613b835760008555613bc9565b82601f10613b9c57805160ff1916838001178555613bc9565b82800160010185558215613bc9579182015b82811115613bc9578251825591602001919060010190613bae565b50613bd5929150613bd9565b5090565b5b80821115613bd55760008155600101613bda565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d9557600080fd5b600060208284031215613c2e57600080fd5b8135613c3981613bee565b9392505050565b60005b83811015613c5b578181015183820152602001613c43565b83811115611bb95750506000910152565b60008151808452613c84816020860160208601613c40565b601f01601f19169290920160200192915050565b602081526000613c396020830184613c6c565b600060208284031215613cbd57600080fd5b5035919050565b80356001600160a01b0381168114613cdb57600080fd5b919050565b60008060408385031215613cf357600080fd5b613cfc83613cc4565b946020939093013593505050565b600080600060608486031215613d1f57600080fd5b613d2884613cc4565b9250613d3660208501613cc4565b9150604084013590509250925092565b600060208284031215613d5857600080fd5b613c3982613cc4565b611a408101818360005b60d2811015613d8c5781511515835260209283019290910190600101613d6b565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613dd457613dd4613d95565b604052919050565b600067ffffffffffffffff831115613df657613df6613d95565b613e096020601f19601f86011601613dab565b9050828152838383011115613e1d57600080fd5b828260208301376000602084830101529392505050565b600060208284031215613e4657600080fd5b813567ffffffffffffffff811115613e5d57600080fd5b8201601f81018413613e6e57600080fd5b6120db84823560208401613ddc565b6020808252825182820181905260009190848201906040850190845b81811015613eb557835183529284019291840191600101613e99565b50909695505050505050565b60006020808385031215613ed457600080fd5b823567ffffffffffffffff80821115613eec57600080fd5b818501915085601f830112613f0057600080fd5b813581811115613f1257613f12613d95565b8060051b9150613f23848301613dab565b8181529183018401918481019088841115613f3d57600080fd5b938501935b83851015613f6257613f5385613cc4565b82529385019390850190613f42565b98975050505050505050565b60008060408385031215613f8157600080fd5b82359150613f9160208401613cc4565b90509250929050565b60008060408385031215613fad57600080fd5b613fb683613cc4565b915060208301358015158114613fcb57600080fd5b809150509250929050565b60008060408385031215613fe957600080fd5b50508035926020909101359150565b6000806000806080858703121561400e57600080fd5b61401785613cc4565b935061402560208601613cc4565b925060408501359150606085013567ffffffffffffffff81111561404857600080fd5b8501601f8101871361405957600080fd5b61406887823560208401613ddc565b91505092959194509250565b6000806040838503121561408757600080fd5b61409083613cc4565b9150613f9160208401613cc4565b600080600080608085870312156140b457600080fd5b5050823594602084013594506040840135936060013592509050565b600181811c908216806140e457607f821691505b60208210811415610feb57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561412f5761412f614105565b5060010190565b634e487b7160e01b600052603260045260246000fd5b7f697066733a2f2f00000000000000000000000000000000000000000000000000815260008251614184816007850160208701613c40565b9190910160070192915050565b60008160001904831182151516156141ab576141ab614105565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826141d5576141d56141b0565b500490565b6000828210156141ec576141ec614105565b500390565b6000821982111561420457614204614105565b500190565b6000825161421b818460208701613c40565b9190910192915050565b8054600090600181811c908083168061423f57607f831692505b602080841082141561426157634e487b7160e01b600052602260045260246000fd5b8180156142755760018114614286576142b2565b60ff198616895284890196506142b2565b876000528160002060005b868110156142aa5781548b820152908501908301614291565b505084890196505b50505050505092915050565b60006142ca8285614225565b83516142da818360208801613c40565b01949350505050565b600083516142f5818460208801613c40565b835190830190614309818360208801613c40565b7f2045646974696f6e0000000000000000000000000000000000000000000000009101908152600801949350505050565b60006143468285614225565b7f202d2000000000000000000000000000000000000000000000000000000000008152835161437c816003840160208801613c40565b01600301949350505050565b7f7b2274726169745f74797065223a2245646974696f6e222c2276616c7565223a81527f22230000000000000000000000000000000000000000000000000000000000006020820152600082516143e6816022850160208701613c40565b7f227d2c00000000000000000000000000000000000000000000000000000000006022939091019283015250602501919050565b6000845161442c818460208901613c40565b845190830190614440818360208901613c40565b7f7b2274726169745f74797065223a2253657269616c222c2276616c7565223a2291019081528351614479816020808501908801613c40565b7f227d2c0000000000000000000000000000000000000000000000000000000000910160208101919091527f7b2274726169745f74797065223a22436861726163746572222c2276616c756560238201527f223a22446f7269616e204e616b616d6f746f227d2c000000000000000000000060438201527f7b2274726169745f74797065223a22456666656374222c2276616c7565223a2260588201527f42525252227d2c0000000000000000000000000000000000000000000000000060788201527f7b2274726169745f74797065223a2255534420506f727472616974222c227661607f8201527f6c7565223a222331202d2057686f206973205361746f736869227d2c00000000609f8201527f7b2274726169745f74797065223a224d656469756d222c2276616c7565223a2260bb8201527f446f6c6c61722062696c6c7320676c756564206f6e2063616e766173227d000060db82015260f981015b9695505050505050565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000613c396007830184614225565b60006001600160a01b038087168352808616602084015250836040830152608060608301526145d96080830184613c6c565b60006020828403121561465957600080fd5b8151613c3981613bee565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226e616d65223a22000000000000000000000000000000000000000000000000600182015260006146bc6009830188614225565b7f222c0000000000000000000000000000000000000000000000000000000000008082527f226465736372697074696f6e223a22000000000000000000000000000000000060028301526147136011830189614225565b91508082527f2261747472696275746573223a5b000000000000000000000000000000000000600283015261474b6010830188614225565b91507f5d2c00000000000000000000000000000000000000000000000000000000000082527f22696d616765223a22000000000000000000000000000000000000000000000060028301526147a3600b830187614225565b9081527f22616e696d6174696f6e5f75726c223a22000000000000000000000000000000600282015290506147db6013820185614225565b7f220000000000000000000000000000000000000000000000000000000000000081527f7d00000000000000000000000000000000000000000000000000000000000000600182015260020198975050505050505050565b600082614842576148426141b0565b500690565b7f300000000000000000000000000000000000000000000000000000000000000081526000825161487f816001850160208701613c40565b9190910160010192915050565b7f30300000000000000000000000000000000000000000000000000000000000008152600082516148c4816002850160208701613c40565b9190910160020192915050565b7f230000000000000000000000000000000000000000000000000000000000000081526000825161487f816001850160208701613c40565b634e487b7160e01b600052603160045260246000fdfe7b2274726169745f74797065223a224e46542054797065222c2276616c7565223a2247656e657261746f72227d2c7b2274726169745f74797065223a2245646974696f6e222c2276616c7565223a2247656e65736973227d2c4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f7b2274726169745f74797065223a224e46542054797065222c2276616c7565223a2247656e657261746564227d2ca2646970667358221220627efb7c58e0f1a820013031c32ab417b2b86eb0e16948f99bf7e29ad6e5040764736f6c634300080a0033

Deployed Bytecode Sourcemap

7604:17691:14:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25116:176;;;;;;;;;;-1:-1:-1;25116:176:14;;;;;:::i;:::-;;:::i;:::-;;;611:14:16;;604:22;586:41;;574:2;559:18;25116:176:14;;;;;;;;7970:72;;;;;;;;;;-1:-1:-1;7970:72:14;;;;-1:-1:-1;;;;;7970:72:14;;;;;;-1:-1:-1;;;;;802:55:16;;;784:74;;772:2;757:18;7970:72:14;638:226:16;2408:98:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3919:217::-;;;;;;;;;;-1:-1:-1;3919:217:4;;;;;:::i;:::-;;:::i;3457:401::-;;;;;;;;;;-1:-1:-1;3457:401:4;;;;;:::i;:::-;;:::i;:::-;;8831:26:14;;;;;;;;;;;;;;;;;;;2470:25:16;;;2458:2;2443:18;8831:26:14;2324:177:16;1614:111:5;;;;;;;;;;-1:-1:-1;1701:10:5;:17;1614:111;;9537:25:14;;;;;;;;;;;;;;;;4646:330:4;;;;;;;;;;-1:-1:-1;4646:330:4;;;;;:::i;:::-;;:::i;22061:227:14:-;;;;;;;;;;-1:-1:-1;22061:227:14;;;;;:::i;:::-;;:::i;20130:285::-;;;;;;;;;;-1:-1:-1;20130:285:14;;;;;:::i;:::-;;:::i;8225:30::-;;;;;;;;;;;;;;;;8309:31;;;;;;;;;;;;;;;;1290:253:5;;;;;;;;;;-1:-1:-1;1290:253:5;;;;;:::i;:::-;;:::i;23735:257:14:-;;;;;;;;;;-1:-1:-1;23735:257:14;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5042:179:4:-;;;;;;;;;;-1:-1:-1;5042:179:4;;;;;:::i;:::-;;:::i;9614:27:14:-;;;;;;;;;;;;;;;;23175:138;;;;;;;;;;-1:-1:-1;23175:138:14;;;;;:::i;:::-;;:::i;11920:565::-;;;;;;;;;;;;;:::i;1797:230:5:-;;;;;;;;;;-1:-1:-1;1797:230:5;;;;;:::i;:::-;;:::i;9152:36:14:-;;;;;;;;;;;;;;;;8434:43;;;;;;;;;;-1:-1:-1;8434:43:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;11543:207;;;;;;;;;;-1:-1:-1;11543:207:14;;;;;:::i;:::-;;:::i;2111:235:4:-;;;;;;;;;;-1:-1:-1;2111:235:4;;;;;:::i;:::-;;:::i;9074:31:14:-;;;;;;;;;;;;;;;;24067:360;;;;;;;;;;-1:-1:-1;24067:360:14;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1849:205:4:-;;;;;;;;;;-1:-1:-1;1849:205:4;;;;;:::i;:::-;;:::i;1661:101:11:-;;;;;;;;;;;;;:::i;9448:39:14:-;;;;;;;;;;;;;;;;20477:92;;;;;;;;;;;;;:::i;21165:466::-;;;:::i;9896:38::-;;;;;;;;;;-1:-1:-1;9896:38:14;;;;;;;;19714:335;;;;;;;;;;-1:-1:-1;19714:335:14;;;;;:::i;:::-;;:::i;20718:232::-;;;;;;;;;;-1:-1:-1;20718:232:14;;;;;:::i;:::-;;:::i;9237:37::-;;;;;;;;;;;;;;;;8950:28;;;;;;;;;;;;;;;;21730:232;;;;;;;;;;-1:-1:-1;21730:232:14;;;;;:::i;:::-;;:::i;1029:85:11:-;;;;;;;;;;-1:-1:-1;1101:6:11;;-1:-1:-1;;;;;1101:6:11;1029:85;;8531:24:14;;;;;;;;;;;;;;;;2570:102:4;;;;;;;;;;;;;:::i;11183:200:14:-;;;;;;;;;;-1:-1:-1;11183:200:14;;;;;:::i;:::-;;:::i;4203:153:4:-;;;;;;;;;;-1:-1:-1;4203:153:4;;;;;:::i;:::-;;:::i;8618:28:14:-;;;;;;;;;;;;;;;;10138:72;;;;;;;;;;-1:-1:-1;10138:72:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;9709:24;;;;;;;;;;;;;;;;5287:320:4;;;;;;;;;;-1:-1:-1;5287:320:4;;;;;:::i;:::-;;:::i;8094:73:14:-;;;;;;;;;;-1:-1:-1;8094:73:14;;;;-1:-1:-1;;;;;8094:73:14;;;24600:234;;;;;;;;;;-1:-1:-1;24600:234:14;;;;;:::i;:::-;;:::i;9811:31::-;;;;;;;;;;;;;;;;9991:41;;;;;;;;;;-1:-1:-1;9991:41:14;;;;;;;;;;;9330:40;;;;;;;;;;;;;;;;8715:31;;;;;;;;;;;;;;;;23453:109;;;;;;;;;;;;;:::i;4422:162:4:-;;;;;;;;;;-1:-1:-1;4422:162:4;;;;;:::i;:::-;-1:-1:-1;;;;;4542:25:4;;;4519:4;4542:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4422:162;7846:72:14;;;;;;;;;;-1:-1:-1;7846:72:14;;;;-1:-1:-1;;;;;7846:72:14;;;17249:521;;;;;;;;;;-1:-1:-1;17249:521:14;;;;;:::i;:::-;;:::i;1911:198:11:-;;;;;;;;;;-1:-1:-1;1911:198:11;;;;;:::i;:::-;;:::i;25116:176:14:-;25224:4;25248:36;25272:11;25248:23;:36::i;:::-;25241:43;25116:176;-1:-1:-1;;25116:176:14:o;2408:98:4:-;2462:13;2494:5;2487:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2408:98;:::o;3919:217::-;3995:7;7167:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7167:16:4;4014:73;;;;-1:-1:-1;;;4014:73:4;;9429:2:16;4014:73:4;;;9411:21:16;9468:2;9448:18;;;9441:30;9507:34;9487:18;;;9480:62;9578:14;9558:18;;;9551:42;9610:19;;4014:73:4;;;;;;;;;-1:-1:-1;4105:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;4105:24:4;;3919:217::o;3457:401::-;3537:13;3553:23;3568:7;3553:14;:23::i;:::-;3537:39;;3600:5;-1:-1:-1;;;;;3594:11:4;:2;-1:-1:-1;;;;;3594:11:4;;;3586:57;;;;-1:-1:-1;;;3586:57:4;;9842:2:16;3586:57:4;;;9824:21:16;9881:2;9861:18;;;9854:30;9920:34;9900:18;;;9893:62;9991:3;9971:18;;;9964:31;10012:19;;3586:57:4;9640:397:16;3586:57:4;719:10:2;-1:-1:-1;;;;;3675:21:4;;;;:62;;-1:-1:-1;3700:37:4;3717:5;719:10:2;4422:162:4;:::i;3700:37::-;3654:165;;;;-1:-1:-1;;;3654:165:4;;10244:2:16;3654:165:4;;;10226:21:16;10283:2;10263:18;;;10256:30;10322:34;10302:18;;;10295:62;10393:26;10373:18;;;10366:54;10437:19;;3654:165:4;10042:420:16;3654:165:4;3830:21;3839:2;3843:7;3830:8;:21::i;:::-;3527:331;3457:401;;:::o;4646:330::-;4835:41;719:10:2;4868:7:4;4835:18;:41::i;:::-;4827:103;;;;-1:-1:-1;;;4827:103:4;;10669:2:16;4827:103:4;;;10651:21:16;10708:2;10688:18;;;10681:30;10747:34;10727:18;;;10720:62;10818:19;10798:18;;;10791:47;10855:19;;4827:103:4;10467:413:16;4827:103:4;4941:28;4951:4;4957:2;4961:7;4941:9;:28::i;22061:227:14:-;22131:12;;22129:14;;;;;:::i;:::-;;;;-1:-1:-1;22154:32:14;22175:10;22154:20;:32::i;:::-;22197:39;22209:7;;22218:10;22230:5;;22197:11;:39::i;:::-;22270:7;:9;;22247:33;;22258:10;;22270:9;:7;:9;;;:::i;:::-;;;;;22247:10;:33::i;:::-;22061:227;:::o;20130:285::-;20199:5;;:10;20191:34;;;;-1:-1:-1;;;20191:34:14;;11476:2:16;20191:34:14;;;11458:21:16;11515:2;11495:18;;;11488:30;11554:13;11534:18;;;11527:41;11585:18;;20191:34:14;11274:335:16;20191:34:14;20255:10;20244:22;;;;:10;:22;;;;;;;;20236:51;;;;-1:-1:-1;;;20236:51:14;;11816:2:16;20236:51:14;;;11798:21:16;11855:2;11835:18;;;11828:30;11894:18;11874;;;11867:46;11930:18;;20236:51:14;11614:340:16;20236:51:14;-1:-1:-1;;;;;20307:14:14;;;;;;:10;:14;;;;;;;;20306:15;20298:36;;;;-1:-1:-1;;;20298:36:14;;12161:2:16;20298:36:14;;;12143:21:16;12200:1;12180:18;;;12173:29;12238:10;12218:18;;;12211:38;12266:18;;20298:36:14;11959:331:16;20298:36:14;20356:10;20370:5;20345:22;;;:10;:22;;;;;;:30;;-1:-1:-1;;20345:30:14;;;;;;-1:-1:-1;;;;;20386:14:14;;;;;;;;:21;;;;;20345:30;20386:21;;;20130:285::o;1290:253:5:-;1387:7;1422:23;1439:5;1422:16;:23::i;:::-;1414:5;:31;1406:87;;;;-1:-1:-1;;;1406:87:5;;12497:2:16;1406:87:5;;;12479:21:16;12536:2;12516:18;;;12509:30;12575:34;12555:18;;;12548:62;12646:13;12626:18;;;12619:41;12677:19;;1406:87:5;12295:407:16;1406:87:5;-1:-1:-1;;;;;;1510:19:5;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1290:253::o;23735:257:14:-;23810:23;;:::i;:::-;23855:1;23867:118;23879:16;;23874:1;:21;23867:118;;23924:28;;;;:20;:28;;;;;;;;:31;;;;;;;;;;;23912:6;23953:1;23912:9;;;;;;;:::i;:::-;:43;;;:9;;;;;:43;23970:3;;;;:::i;:::-;;;;23867:118;;;23835:157;23735:257;;;:::o;5042:179:4:-;5175:39;5192:4;5198:2;5202:7;5175:39;;;;;;;;;;;;:16;:39::i;23175:138:14:-;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;23300:3:14::1;23272:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;23251:11;:54;;;;;;;;;;;;:::i;:::-;;23175:138:::0;:::o;11920:565::-;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;1744:1:12::1;2325:7;;:19;;2317:63;;;::::0;-1:-1:-1;;;2317:63:12;;13888:2:16;2317:63:12::1;::::0;::::1;13870:21:16::0;13927:2;13907:18;;;13900:30;13966:33;13946:18;;;13939:61;14017:18;;2317:63:12::1;13686:355:16::0;2317:63:12::1;1744:1;2455:7;:18:::0;12044:99:14::2;::::0;;;;::::2;::::0;;12092:12:::2;::::0;-1:-1:-1;;;;;12092:12:14;;::::2;12044:99:::0;;12119:13:::2;::::0;::::2;12044:99;::::0;::::2;::::0;12156:122;;;;::::2;::::0;;;12199:10:::2;::::0;12010:21:::2;::::0;11992:15:::2;::::0;12156:122;;12222:3:::2;::::0;12199:20:::2;::::0;12010:21;;12199:20:::2;:::i;:::-;:26;;;;:::i;:::-;12156:122;;;;12264:3;12254:7;12240:11;;:21;;;;:::i;:::-;:27;;;;:::i;:::-;12156:122:::0;;;-1:-1:-1;12291:6:14::2;12312:166;12323:1;12319;:5;12312:166;;;12357:12;12370:1;12357:15;;;;;;;:::i;:::-;;;;;-1:-1:-1::0;;;;;12349:29:14::2;:41;12379:7;12387:1;12379:10;;;;;;;:::i;:::-;;;;::::0;12349:41:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;::::0;;;12379:10;12349:41;;::::2;;;;;;12341:50;;;::::0;::::2;;12420:7;12428:1;12420:10;;;;;;;:::i;:::-;;;;;12411:37;12432:12;12445:1;12432:15;;;;;;;:::i;:::-;;;;;12411:37;;;;;-1:-1:-1::0;;;;;802:55:16;;;;784:74;;772:2;757:18;;638:226;12411:37:14::2;;;;;;;;12463:3:::0;::::2;::::0;::::2;:::i;:::-;;;;12312:166;;;-1:-1:-1::0;;1701:1:12::1;2628:7;:22:::0;-1:-1:-1;;11920:565:14:o;1797:230:5:-;1872:7;1907:30;1701:10;:17;;1614:111;1907:30;1899:5;:38;1891:95;;;;-1:-1:-1;;;1891:95:5;;14795:2:16;1891:95:5;;;14777:21:16;14834:2;14814:18;;;14807:30;14873:34;14853:18;;;14846:62;14944:14;14924:18;;;14917:42;14976:19;;1891:95:5;14593:408:16;1891:95:5;2003:10;2014:5;2003:17;;;;;;;;:::i;:::-;;;;;;;;;1996:24;;1797:230;;;:::o;11543:207:14:-;11621:13;;-1:-1:-1;;;;;11621:13:14;11607:10;:27;11599:56;;;;-1:-1:-1;;;11599:56:14;;11816:2:16;11599:56:14;;;11798:21:16;11855:2;11835:18;;;11828:30;11894:18;11874;;;11867:46;11930:18;;11599:56:14;11614:340:16;11599:56:14;11666:13;:21;;;;-1:-1:-1;;;;;11666:21:14;;;;;;;;11715:11;;11703:39;;784:74:16;;;11715:11:14;11703:39;;772:2:16;757:18;11703:39:14;;;;;;;;11543:207;:::o;2111:235:4:-;2183:7;2218:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2218:16:4;2252:19;2244:73;;;;-1:-1:-1;;;2244:73:4;;15208:2:16;2244:73:4;;;15190:21:16;15247:2;15227:18;;;15220:30;15286:34;15266:18;;;15259:62;15357:11;15337:18;;;15330:39;15386:19;;2244:73:4;15006:405:16;24067:360:14;24130:13;24156:15;24174:16;24184:5;24174:9;:16::i;:::-;24156:34;;24201:22;24237:10;24226:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24226:22:14;;24201:47;;24261:6;24282:112;24293:10;24289:1;:14;24282:112;;;24335:29;24355:5;24362:1;24335:19;:29::i;:::-;24321:8;24330:1;24321:11;;;;;;;;:::i;:::-;;;;;;;;;;:43;24379:3;;;;:::i;:::-;;;;24282:112;;;-1:-1:-1;24411:8:14;24067:360;-1:-1:-1;;;24067:360:14:o;1849:205:4:-;1921:7;-1:-1:-1;;;;;1948:19:4;;1940:74;;;;-1:-1:-1;;;1940:74:4;;15618:2:16;1940:74:4;;;15600:21:16;15657:2;15637:18;;;15630:30;15696:34;15676:18;;;15669:62;15767:12;15747:18;;;15740:40;15797:19;;1940:74:4;15416:406:16;1940:74:4;-1:-1:-1;;;;;;2031:16:4;;;;;:9;:16;;;;;;;1849:205::o;1661:101:11:-;1101:6;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;20477:92:14:-;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;20536:18:14::1;:25:::0;;-1:-1:-1;;20536:25:14::1;20557:4;20536:25;::::0;;20477:92::o;21165:466::-;21220:18;21243:9;;21241:11;;;;;:::i;:::-;;;;;;;21220:32;;21263:39;21275:7;;21284:10;21296:5;;21263:11;:39::i;:::-;21313:29;21331:10;21313:17;:29::i;:::-;21361:18;;;;21353:55;;;;-1:-1:-1;;;21353:55:14;;16029:2:16;21353:55:14;;;16011:21:16;16068:2;16048:18;;;16041:30;16107:26;16087:18;;;16080:54;16151:18;;21353:55:14;15827:348:16;21353:55:14;21438:10;21427:22;;;;:10;:22;;;;;;;;21419:50;;;;-1:-1:-1;;;21419:50:14;;16382:2:16;21419:50:14;;;16364:21:16;16421:2;16401:18;;;16394:30;16460:17;16440:18;;;16433:45;16495:18;;21419:50:14;16180:339:16;21419:50:14;21504:9;21488:12;;:25;21480:56;;;;-1:-1:-1;;;21480:56:14;;16726:2:16;21480:56:14;;;16708:21:16;16765:2;16745:18;;;16738:30;16804:20;16784:18;;;16777:48;16842:18;;21480:56:14;16524:342:16;21480:56:14;21560:10;21574:5;21549:22;;;:10;:22;;;;;:30;;-1:-1:-1;;21549:30:14;;;21613:7;:9;;21590:33;;21560:10;21613:9;;:7;:9;;;:::i;19714:335::-;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;19816:12:14;;19847:7;19839:29:::1;;;::::0;-1:-1:-1;;;19839:29:14;;17073:2:16;19839:29:14::1;::::0;::::1;17055:21:16::0;17112:1;17092:18;;;17085:29;17150:11;17130:18;;;17123:39;17179:18;;19839:29:14::1;16871:332:16::0;19839:29:14::1;19889:6;19910:132;19921:3;19917:1;:7;19910:132;;;19964:10;:20;19975:5;19981:1;19975:8;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;19964:20:14::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;19964:20:14;;::::1;;:48;;20008:4;19964:48;;;20000:5;19964:48;19941:10;:20;19952:5;19958:1;19952:8;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;19941:20:14::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;19941:20:14;:71;;-1:-1:-1;;19941:71:14::1;::::0;::::1;;::::0;;;::::1;::::0;;20027:3;::::1;::::0;::::1;:::i;:::-;;;;19910:132;;20718:232:::0;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;20784:18:14::1;20807:9;;20805:11;;;;;:::i;:::-;;;;;;;20784:32;;20827:39;20839:7;;20848:10;20860:5;;20827:11;:39::i;:::-;20877:29;20895:10;20877:17;:29::i;:::-;20932:7;:9:::0;;20917:25:::1;::::0;20928:2;;20932:9;:7:::1;:9;::::0;::::1;:::i;21730:232::-:0;21812:12;;21810:14;;;;;:::i;:::-;;;;-1:-1:-1;21835:32:14;21856:10;21835:20;:32::i;:::-;21879:39;21891:7;;21900:10;21912:5;;21879:11;:39::i;:::-;21944:7;:9;;21929:25;;21940:2;;21944:9;:7;:9;;;:::i;2570:102:4:-;2626:13;2658:7;2651:14;;;;;:::i;11183:200:14:-;11259:12;;-1:-1:-1;;;;;11259:12:14;11245:10;:26;11237:55;;;;-1:-1:-1;;;11237:55:14;;11816:2:16;11237:55:14;;;11798:21:16;11855:2;11835:18;;;11828:30;11894:18;11874;;;11867:46;11930:18;;11237:55:14;11614:340:16;11237:55:14;11303:12;:19;;;;-1:-1:-1;;;;;11303:19:14;;;;;;;;11350:10;;11338:37;;784:74:16;;;11350:10:14;11338:37;;772:2:16;757:18;11338:37:14;638:226:16;4203:153:4;4297:52;719:10:2;4330:8:4;4340;4297:18;:52::i;5287:320::-;5456:41;719:10:2;5489:7:4;5456:18;:41::i;:::-;5448:103;;;;-1:-1:-1;;;5448:103:4;;10669:2:16;5448:103:4;;;10651:21:16;10708:2;10688:18;;;10681:30;10747:34;10727:18;;;10720:62;10818:19;10798:18;;;10791:47;10855:19;;5448:103:4;10467:413:16;5448:103:4;5561:39;5575:4;5581:2;5585:7;5594:5;5561:13;:39::i;:::-;5287:320;;;;:::o;24600:234:14:-;7144:4:4;7167:16;;;:7;:16;;;;;;24679:13:14;;-1:-1:-1;;;;;7167:16:4;24705:77:14;;;;-1:-1:-1;;;24705:77:14;;17410:2:16;24705:77:14;;;17392:21:16;17449:2;17429:18;;;17422:30;17488:34;17468:18;;;17461:62;17559:17;17539:18;;;17532:45;17594:19;;24705:77:14;17208:411:16;24705:77:14;24800:26;24817:8;24800:16;:26::i;23453:109::-;23510:13;23543:11;23536:18;;;;;:::i;17249:521::-;1101:6:11;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;17401:1:14::1;17393:5;;:9;17385:33;;;::::0;-1:-1:-1;;;17385:33:14;;11476:2:16;17385:33:14::1;::::0;::::1;11458:21:16::0;11515:2;11495:18;;;11488:30;11554:13;11534:18;;;11527:41;11585:18;;17385:33:14::1;11274:335:16::0;17385:33:14::1;17446:1;17437:6;:10;17429:35;;;::::0;-1:-1:-1;;;17429:35:14;;17826:2:16;17429:35:14::1;::::0;::::1;17808:21:16::0;17865:2;17845:18;;;17838:30;17904:14;17884:18;;;17877:42;17936:18;;17429:35:14::1;17624:336:16::0;17429:35:14::1;17501:7;;17483:14;;:25;;17475:58;;;::::0;-1:-1:-1;;;17475:58:14;;18167:2:16;17475:58:14::1;::::0;::::1;18149:21:16::0;18206:2;18186:18;;;18179:30;18245:22;18225:18;;;18218:50;18285:18;;17475:58:14::1;17965:344:16::0;17475:58:14::1;17546:5;:14:::0;;;17571:8:::1;:20:::0;;;17602:9:::1;:22:::0;;;17635:12:::1;:28:::0;;;17676:19:::1;:17;:19::i;:::-;17721:5;::::0;17728:8:::1;::::0;17738:9:::1;::::0;17749:12:::1;::::0;17711:51:::1;::::0;;18516:25:16;;;18572:2;18557:18;;18550:34;;;;18600:18;;;18593:34;17711:51:14;::::1;::::0;;;;18504:2:16;17711:51:14;;::::1;17249:521:::0;;;;:::o;1911:198:11:-;1101:6;;-1:-1:-1;;;;;1101:6:11;719:10:2;1241:23:11;1233:68;;;;-1:-1:-1;;;1233:68:11;;13098:2:16;1233:68:11;;;13080:21:16;;;13117:18;;;13110:30;13176:34;13156:18;;;13149:62;13228:18;;1233:68:11;12896:356:16;1233:68:11;-1:-1:-1;;;;;1999:22:11;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:11;;18840:2:16;1991:73:11::1;::::0;::::1;18822:21:16::0;18879:2;18859:18;;;18852:30;18918:34;18898:18;;;18891:62;18989:8;18969:18;;;18962:36;19015:19;;1991:73:11::1;18638:402:16::0;1991:73:11::1;2074:28;2093:8;2074:18;:28::i;989:222:5:-:0;1091:4;1114:50;;;1129:35;1114:50;;:90;;;1168:36;1192:11;1168:23;:36::i;10930:171:4:-;11004:24;;;;:15;:24;;;;;:29;;;;-1:-1:-1;;;;;11004:29:4;;;;;;;;:24;;11057:23;11004:24;11057:14;:23::i;:::-;-1:-1:-1;;;;;11048:46:4;;;;;;;;;;;10930:171;;:::o;7362:344::-;7455:4;7167:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7167:16:4;7471:73;;;;-1:-1:-1;;;7471:73:4;;19247:2:16;7471:73:4;;;19229:21:16;19286:2;19266:18;;;19259:30;19325:34;19305:18;;;19298:62;19396:14;19376:18;;;19369:42;19428:19;;7471:73:4;19045:408:16;7471:73:4;7554:13;7570:23;7585:7;7570:14;:23::i;:::-;7554:39;;7622:5;-1:-1:-1;;;;;7611:16:4;:7;-1:-1:-1;;;;;7611:16:4;;:51;;;;7655:7;-1:-1:-1;;;;;7631:31:4;:20;7643:7;7631:11;:20::i;:::-;-1:-1:-1;;;;;7631:31:4;;7611:51;:87;;;-1:-1:-1;;;;;;4542:25:4;;;4519:4;4542:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7666:32;7603:96;7362:344;-1:-1:-1;;;;7362:344:4:o;10259:560::-;10413:4;-1:-1:-1;;;;;10386:31:4;:23;10401:7;10386:14;:23::i;:::-;-1:-1:-1;;;;;10386:31:4;;10378:85;;;;-1:-1:-1;;;10378:85:4;;19660:2:16;10378:85:4;;;19642:21:16;19699:2;19679:18;;;19672:30;19738:34;19718:18;;;19711:62;19809:11;19789:18;;;19782:39;19838:19;;10378:85:4;19458:405:16;10378:85:4;-1:-1:-1;;;;;10481:16:4;;10473:65;;;;-1:-1:-1;;;10473:65:4;;20070:2:16;10473:65:4;;;20052:21:16;20109:2;20089:18;;;20082:30;20148:34;20128:18;;;20121:62;20219:6;20199:18;;;20192:34;20243:19;;10473:65:4;19868:400:16;10473:65:4;10549:39;10570:4;10576:2;10580:7;10549:20;:39::i;:::-;10650:29;10667:1;10671:7;10650:8;:29::i;:::-;-1:-1:-1;;;;;10690:15:4;;;;;;:9;:15;;;;;:20;;10709:1;;10690:15;:20;;10709:1;;10690:20;:::i;:::-;;;;-1:-1:-1;;;;;;;10720:13:4;;;;;;:9;:13;;;;;:18;;10737:1;;10720:13;:18;;10737:1;;10720:18;:::i;:::-;;;;-1:-1:-1;;10748:16:4;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;10748:21:4;;;;;;;;;10785:27;;10748:16;;10785:27;;;;;;;10259:560;;;:::o;14104:2256:14:-;14201:1;14186:12;;:16;14178:47;;;;-1:-1:-1;;;14178:47:14;;20738:2:16;14178:47:14;;;20720:21:16;20777:2;20757:18;;;20750:30;20816:20;20796:18;;;20789:48;20854:18;;14178:47:14;20536:342:16;14178:47:14;14256:1;14244:9;;:13;14236:41;;;;-1:-1:-1;;;14236:41:14;;21085:2:16;14236:41:14;;;21067:21:16;21124:2;21104:18;;;21097:30;21163:17;21143:18;;;21136:45;21198:18;;14236:41:14;20883:339:16;14236:41:14;14309:1;14296:10;;:14;14288:43;;;;-1:-1:-1;;;14288:43:14;;21429:2:16;14288:43:14;;;21411:21:16;21468:2;21448:18;;;21441:30;21507:18;21487;;;21480:46;21543:18;;14288:43:14;21227:340:16;14288:43:14;14726:9;;14710:12;:25;14706:105;;14752:16;:14;:16::i;:::-;14798:1;14783:12;:16;14706:105;14912:9;;14897:12;:24;:63;;;;;14941:19;;14925:12;;:35;;14897:63;14893:124;;;14977:21;:28;;-1:-1:-1;;14977:28:14;;;;;14893:124;15055:7;;15037:14;;:25;;15029:58;;;;-1:-1:-1;;;15029:58:14;;18167:2:16;15029:58:14;;;18149:21:16;18206:2;18186:18;;;18179:30;18245:22;18225:18;;;18218:50;18285:18;;15029:58:14;17965:344:16;15029:58:14;15114:1;15106:5;;:9;:29;;;;;15127:8;;15119:5;;:16;15106:29;15098:53;;;;-1:-1:-1;;;15098:53:14;;11476:2:16;15098:53:14;;;11458:21:16;11515:2;11495:18;;;11488:30;11554:13;11534:18;;;11527:41;11585:18;;15098:53:14;11274:335:16;15098:53:14;15193:10;15170:19;15178:10;15170:7;:19::i;:::-;-1:-1:-1;;;;;15170:33:14;;15162:59;;;;-1:-1:-1;;;15162:59:14;;21774:2:16;15162:59:14;;;21756:21:16;21813:2;21793:18;;;21786:30;21852:15;21832:18;;;21825:43;21885:18;;15162:59:14;21572:337:16;15162:59:14;15240:21;;;;;;;15232:61;;;;-1:-1:-1;;;15232:61:14;;22116:2:16;15232:61:14;;;22098:21:16;22155:2;22135:18;;;22128:30;22194:29;22174:18;;;22167:57;22241:18;;15232:61:14;21914:351:16;15232:61:14;15328:19;;15312:12;;:35;;15304:66;;;;-1:-1:-1;;;15304:66:14;;22472:2:16;15304:66:14;;;22454:21:16;22511:2;22491:18;;;22484:30;22550:20;22530:18;;;22523:48;22588:18;;15304:66:14;22270:342:16;15304:66:14;15389:23;:35;;;:23;;:35;:23;:35;;;;;15381:74;;;;-1:-1:-1;;;15381:74:14;;22819:2:16;15381:74:14;;;22801:21:16;22858:2;22838:18;;;22831:30;22897:28;22877:18;;;22870:56;22943:18;;15381:74:14;22617:350:16;15381:74:14;15496:5;;15475:27;;;;:20;:27;;;;;;;;:39;;;;;;;;;;;15474:40;15466:79;;;;-1:-1:-1;;;15466:79:14;;22819:2:16;15466:79:14;;;22801:21:16;22858:2;22838:18;;;22831:30;22897:28;22877:18;;;22870:56;22943:18;;15466:79:14;22617:350:16;15466:79:14;15638:5;;15617:27;;;;:20;:27;;;;;;;;:39;;;;;;;;:46;;-1:-1:-1;;15617:46:14;15659:4;15617:46;;;16245:19;;16229:12;;:35;16225:128;;;16281:21;:29;;-1:-1:-1;;16281:29:14;;;16305:5;16325:12;:16;14104:2256;:::o;1634:319:15:-;1732:34;1749:8;1759:6;1732:16;:34::i;:::-;1777:47;1797:8;1807;1817:6;1777:19;:47::i;:::-;1835:38;1856:8;1866:6;1835:20;:38::i;:::-;1884;1905:8;1915:6;1884:20;:38::i;:::-;1933:10;:12;;;:10;:12;;;:::i;:::-;;;;;;1634:319;;;:::o;22571:333:14:-;22691:8;22650:50;22663:26;22680:8;22663:16;:26::i;:::-;22650:50;;;;;;:::i;:::-;;;;;;;;22721:12;;22711:33;;-1:-1:-1;;;;;22721:12:14;22735:8;22711:9;:33::i;:::-;22767:5;;22760:37;;22784:12;;22774:8;;22760:37;;;;;22822:12;;22808:45;;;;;;;;;22822:12;22808:45;;;;-1:-1:-1;;;;;22822:12:14;;22836:2;;22840:8;;22808:13;:45::i;:::-;22876:5;;22869:27;;-1:-1:-1;;;;;22869:27:14;;;22883:8;;22869:27;;;;;22571:333;;:::o;2263:187:11:-;2355:6;;;-1:-1:-1;;;;;2371:17:11;;;;;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;12752:1160:14:-;12831:5;;:10;12823:34;;;;-1:-1:-1;;;12823:34:14;;11476:2:16;12823:34:14;;;11458:21:16;11515:2;11495:18;;;11488:30;11554:13;11534:18;;;11527:41;11585:18;;12823:34:14;11274:335:16;12823:34:14;12889:16;;12876:9;;:29;;12868:57;;;;-1:-1:-1;;;12868:57:14;;23174:2:16;12868:57:14;;;23156:21:16;23213:2;23193:18;;;23186:30;23252:17;23232:18;;;23225:45;23287:18;;12868:57:14;22972:339:16;12868:57:14;12966:5;;12945:27;;;;:20;:27;;;;;;;;:39;;;;;;;;;;;12944:40;12936:79;;;;-1:-1:-1;;;12936:79:14;;22819:2:16;12936:79:14;;;22801:21:16;22858:2;22838:18;;;22831:30;22897:28;22877:18;;;22870:56;22943:18;;12936:79:14;22617:350:16;12936:79:14;13108:5;;13087:27;;;;:20;:27;;;;;;;;:39;;;;;;;;:46;;-1:-1:-1;;13087:46:14;13129:4;13087:46;;;13701:16;;13688:9;;:29;13684:221;;;13749:12;13734;:27;;;13776:9;:24;;;13842:5;;13834:28;;2470:25:16;;;13842:5:14;13834:28;;2458:2:16;2443:18;13834:28:14;;;;;;;13877:16;:14;:16::i;11236:307:4:-;11386:8;-1:-1:-1;;;;;11377:17:4;:5;-1:-1:-1;;;;;11377:17:4;;;11369:55;;;;-1:-1:-1;;;11369:55:4;;23518:2:16;11369:55:4;;;23500:21:16;23557:2;23537:18;;;23530:30;23596:27;23576:18;;;23569:55;23641:18;;11369:55:4;23316:349:16;11369:55:4;-1:-1:-1;;;;;11434:25:4;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;11434:46:4;;;;;;;;;;11495:41;;586::16;;;11495::4;;559:18:16;11495:41:4;;;;;;;11236:307;;;:::o;6469:::-;6620:28;6630:4;6636:2;6640:7;6620:9;:28::i;:::-;6666:48;6689:4;6695:2;6699:7;6708:5;6666:22;:48::i;:::-;6658:111;;;;-1:-1:-1;;;6658:111:4;;23872:2:16;6658:111:4;;;23854:21:16;23911:2;23891:18;;;23884:30;23950:34;23930:18;;;23923:62;24021:20;24001:18;;;23994:48;24059:19;;6658:111:4;23670:414:16;4910:504:15;4992:20;5080:4;5103:277;5260:20;5271:8;5260:10;:20::i;:::-;5209:102;;;;;;;;:::i;:::-;;;;;;;;;;;;;5103:13;:277::i;:::-;5045:350;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5029:377;;4910:504;;;:::o;18181:462:14:-;18311:8;;18234:9;;;;18332:304;18343:8;;18339:1;:12;18332:304;;;18372:5;;18368:36;;18392:12;;18379:25;;;;:::i;:::-;;;18368:36;18423:1;18428;18423:6;18419:150;;;18478:10;18463:12;;:25;;;;:::i;:::-;18450:10;:38;;;18512:17;;2470:25:16;;;18512:17:14;;2458:2:16;2443:18;18512:17:14;;;;;;;3527:331:4;3457:401;;:::o;18419:150:14:-;18583:23;18597:9;18583:23;;:::i;:::-;;-1:-1:-1;18621:3:14;;;;:::i;:::-;;;;18332:304;;1490:300:4;1592:4;1627:40;;;1642:25;1627:40;;:104;;-1:-1:-1;1683:48:4;;;1698:33;1683:48;1627:104;:156;;;-1:-1:-1;952:25:3;937:40;;;;1747:36:4;829:155:3;24881:188:14;25015:46;25042:4;25048:2;25052:8;25015:26;:46::i;19165:398::-;19219:5;;19215:35;;19231:19;:17;:19::i;:::-;19265:5;;:9;19261:39;;19288:12;;19276:8;;:24;;;;;;;:::i;:::-;;;;-1:-1:-1;;19261:39:14;19334:8;;19321:9;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;19363:5:14;;19370:9;;19358:22;;2470:25:16;;;19358:22:14;;2458:2:16;2443:18;19358:22:14;;;;;;;19393:5;:7;;;:5;:7;;;:::i;:::-;;;;;;19433:9;;19417:12;:25;;:45;;;;;19454:8;;19446:5;;:16;19417:45;19413:94;;;19479:16;:14;:16::i;:::-;19527:21;:28;;-1:-1:-1;;19527:28:14;;;;;19165:398::o;2671:636:15:-;2838:9;2856:11;;:417;;2962:28;2979:10;:6;2988:1;2979:10;:::i;:::-;2962:16;:28::i;:::-;3024:10;:6;3033:1;3024:10;:::i;:::-;3039:1;3023:17;:169;;3080:10;:6;3089:1;3080:10;:::i;:::-;3095:1;3079:17;:113;;3150:1;3136:10;:6;3145:1;3136:10;:::i;:::-;3135:16;:57;;;;;;;;;;;;;;3023:169;;3135:57;;;;;;;;;;;;;;;;;;3023:169;;3079:113;;;;;;;;;;;;;;;;;;3023:169;;;;;;;;;;;;;;;;;;;;;2919:335;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2856:417;;;;;;;;;;;;;;;;;;;;;2803:485;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2803:485:15;;;;;;;;;2756:23;;;;:13;2803:485;2756:23;;;;;;:543;;;;:23;;:543;;;;;:::i;3315:1037::-;3509:11;;:282;;3715:28;3732:10;:6;3741:1;3732:10;:::i;3715:28::-;3634:138;;;;;;;;:::i;:::-;;;;;;;;;;;;;3509:282;;;;;;;;;;;;;;;;;;;;;3810:11;;:130;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3994:20;4005:8;3994:10;:20::i;:::-;3474:859;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3474:859:15;;;;;;;;;3421:29;;;;:19;3474:859;3421:29;;;;;;:923;;;;:29;;:923;;;;;:::i;1961:347::-;2164:11;;:110;;2243:31;2164:110;;;2195:28;2164:110;2101:188;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2101:188:15;;;;;;;;;2050:27;;;;:17;2101:188;2050:27;;;;;;:250;;;;:27;;:250;;;;;:::i;2316:347::-;2519:11;;:110;;2598:31;2519:110;;;2550:28;2519:110;2456:188;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2456:188:15;;;;;;;;;2405:27;;;;:17;2456:188;2405:27;;;;;;:250;;;;:27;;:250;;;;;:::i;8036:108:4:-;8111:26;8121:2;8125:7;8111:26;;;;;;;;;;;;:9;:26::i;12096:778::-;12246:4;-1:-1:-1;;;;;12266:13:4;;1087:20:0;1133:8;12262:606:4;;12301:72;;;;;-1:-1:-1;;;;;12301:36:4;;;;;:72;;719:10:2;;12352:4:4;;12358:7;;12367:5;;12301:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12301:72:4;;;;;;;;-1:-1:-1;;12301:72:4;;;;;;;;;;;;:::i;:::-;;;12297:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12540:13:4;;12536:266;;12582:60;;-1:-1:-1;;;12582:60:4;;23872:2:16;12582:60:4;;;23854:21:16;23911:2;23891:18;;;23884:30;23950:34;23930:18;;;23923:62;24021:20;24001:18;;;23994:48;24059:19;;12582:60:4;23670:414:16;12536:266:4;12754:6;12748:13;12739:6;12735:2;12731:15;12724:38;12297:519;12423:51;;12433:41;12423:51;;-1:-1:-1;12416:58:4;;12262:606;-1:-1:-1;12853:4:4;12096:778;;;;;;:::o;4360:542:15:-;4557:23;;;;:13;:23;;;;;;;;4679:19;:29;;;;;4744:17;:27;;;;;4815:17;:27;;;;;;4489:394;;4426:20;;4489:394;;4557:23;;4622:16;;4744:27;;4815;;4489:394;;:::i;379:1557:1:-;476:11;;437:13;;501:8;497:23;;-1:-1:-1;;511:9:1;;;;;;;;;-1:-1:-1;511:9:1;;;379:1557;-1:-1:-1;379:1557:1:o;497:23::-;569:18;607:1;596:7;:3;602:1;596:7;:::i;:::-;595:13;;;;:::i;:::-;590:19;;:1;:19;:::i;:::-;569:40;-1:-1:-1;664:19:1;696:15;569:40;709:2;696:15;:::i;:::-;686:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;686:26:1;;664:48;;723:18;744:5;;;;;;;;;;;;;;;;;723:26;;810:1;803:5;799:13;854:2;846:6;842:15;902:1;871:757;924:3;921:1;918:10;871:757;;;976:1;1018:12;;;;;1012:19;1111:4;1099:2;1095:14;;;;;1077:40;;1071:47;1218:2;1214:14;;;1210:25;;1196:40;;1190:47;1345:1;1341:13;;;1337:24;;1323:39;;1317:46;1463:16;;;;1449:31;;1443:38;1146:1;1142:11;;;1239:4;1186:58;;;1177:68;1269:11;;1313:57;;;1304:67;;;;1395:11;;1439:49;;1430:59;1517:3;1513:13;1544:22;;1612:1;1597:17;;;;969:9;871:757;;;875:42;1658:1;1653:3;1649:11;1678:1;1673:82;;;;1773:1;1768:80;;;;1642:206;;1673:82;1724:16;1705:17;;;1698:43;1673:82;;1768:80;1819:14;-1:-1:-1;;1800:17:1;;1793:41;1642:206;-1:-1:-1;;;1862:26:1;;;1869:6;379:1557;-1:-1:-1;;;;379:1557:1:o;2623:572:5:-;-1:-1:-1;;;;;2822:18:5;;2818:183;;2856:40;2888:7;4004:10;:17;;3977:24;;;;:15;:24;;;;;:44;;;4031:24;;;;;;;;;;;;3901:161;2856:40;2818:183;;;2925:2;-1:-1:-1;;;;;2917:10:5;:4;-1:-1:-1;;;;;2917:10:5;;2913:88;;2943:47;2976:4;2982:7;2943:32;:47::i;:::-;-1:-1:-1;;;;;3014:16:5;;3010:179;;3046:45;3083:7;3046:36;:45::i;3010:179::-;3118:4;-1:-1:-1;;;;;3112:10:5;:2;-1:-1:-1;;;;;3112:10:5;;3108:81;;3138:40;3166:2;3170:7;3138:27;:40::i;328:703:13:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:13;;;;;;;;;;;;;;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:13;;-1:-1:-1;773:2:13;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:13;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:13;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;972:11:13;981:2;972:11;;:::i;:::-;;;844:150;;1102:524:15;1166:20;1199:17;1242:4;1231:8;:15;1227:83;;;1282:26;1299:8;1282:16;:26::i;:::-;1261:48;;;;;;;;:::i;:::-;;;;;;;;;;;;;1248:62;;1227:83;1336:3;1325:8;:14;1321:83;;;1376:26;1393:8;1376:16;:26::i;:::-;1354:49;;;;;;;;:::i;:::-;;;;;;;;;;;;;1341:63;;1321:83;1430:2;1419:8;:13;1415:83;;;1470:26;1487:8;1470:16;:26::i;:::-;1447:50;;;;;;;;:::i;:::-;;;;;;;;;;;;;1434:64;;1415:83;1589:3;1549:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;1519:99;;1188:438;1102:524;;;:::o;8365:311:4:-;8490:18;8496:2;8500:7;8490:5;:18::i;:::-;8539:54;8570:1;8574:2;8578:7;8587:5;8539:22;:54::i;:::-;8518:151;;;;-1:-1:-1;;;8518:151:4;;23872:2:16;8518:151:4;;;23854:21:16;23911:2;23891:18;;;23884:30;23950:34;23930:18;;;23923:62;24021:20;24001:18;;;23994:48;24059:19;;8518:151:4;23670:414:16;4679:970:5;4941:22;4991:1;4966:22;4983:4;4966:16;:22::i;:::-;:26;;;;:::i;:::-;5002:18;5023:26;;;:17;:26;;;;;;4941:51;;-1:-1:-1;5153:28:5;;;5149:323;;-1:-1:-1;;;;;5219:18:5;;5197:19;5219:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5268:30;;;;;;:44;;;5384:30;;:17;:30;;;;;:43;;;5149:323;-1:-1:-1;5565:26:5;;;;:17;:26;;;;;;;;5558:33;;;-1:-1:-1;;;;;5608:18:5;;;;;:12;:18;;;;;:34;;;;;;;5601:41;4679:970::o;5937:1061::-;6211:10;:17;6186:22;;6211:21;;6231:1;;6211:21;:::i;:::-;6242:18;6263:24;;;:15;:24;;;;;;6631:10;:26;;6186:46;;-1:-1:-1;6263:24:5;;6186:46;;6631:26;;;;;;:::i;:::-;;;;;;;;;6609:48;;6693:11;6668:10;6679;6668:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6772:28;;;:15;:28;;;;;;;:41;;;6941:24;;;;;6934:31;6975:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6008:990;;;5937:1061;:::o;3489:217::-;3573:14;3590:20;3607:2;3590:16;:20::i;:::-;-1:-1:-1;;;;;3620:16:5;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3664:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3489:217:5:o;8998:372:4:-;-1:-1:-1;;;;;9077:16:4;;9069:61;;;;-1:-1:-1;;;9069:61:4;;36185:2:16;9069:61:4;;;36167:21:16;;;36204:18;;;36197:30;36263:34;36243:18;;;36236:62;36315:18;;9069:61:4;35983:356:16;9069:61:4;7144:4;7167:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7167:16:4;:30;9140:58;;;;-1:-1:-1;;;9140:58:4;;36546:2:16;9140:58:4;;;36528:21:16;36585:2;36565:18;;;36558:30;36624;36604:18;;;36597:58;36672:18;;9140:58:4;36344:352:16;9140:58:4;9209:45;9238:1;9242:2;9246:7;9209:20;:45::i;:::-;-1:-1:-1;;;;;9265:13:4;;;;;;:9;:13;;;;;:18;;9282:1;;9265:13;:18;;9282:1;;9265:18;:::i;:::-;;;;-1:-1:-1;;9293:16:4;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;9293:21:4;;;;;;;;9330:33;;9293:16;;;9330:33;;9293:16;;9330:33;8998:372;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:16;99:66;92:5;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;:::-;430:5;196:245;-1:-1:-1;;;196:245:16:o;869:258::-;941:1;951:113;965:6;962:1;959:13;951:113;;;1041:11;;;1035:18;1022:11;;;1015:39;987:2;980:10;951:113;;;1082:6;1079:1;1076:13;1073:48;;;-1:-1:-1;;1117:1:16;1099:16;;1092:27;869:258::o;1132:317::-;1174:3;1212:5;1206:12;1239:6;1234:3;1227:19;1255:63;1311:6;1304:4;1299:3;1295:14;1288:4;1281:5;1277:16;1255:63;:::i;:::-;1363:2;1351:15;-1:-1:-1;;1347:88:16;1338:98;;;;1438:4;1334:109;;1132:317;-1:-1:-1;;1132:317:16:o;1454:220::-;1603:2;1592:9;1585:21;1566:4;1623:45;1664:2;1653:9;1649:18;1641:6;1623:45;:::i;1679:180::-;1738:6;1791:2;1779:9;1770:7;1766:23;1762:32;1759:52;;;1807:1;1804;1797:12;1759:52;-1:-1:-1;1830:23:16;;1679:180;-1:-1:-1;1679:180:16:o;1864:196::-;1932:20;;-1:-1:-1;;;;;1981:54:16;;1971:65;;1961:93;;2050:1;2047;2040:12;1961:93;1864:196;;;:::o;2065:254::-;2133:6;2141;2194:2;2182:9;2173:7;2169:23;2165:32;2162:52;;;2210:1;2207;2200:12;2162:52;2233:29;2252:9;2233:29;:::i;:::-;2223:39;2309:2;2294:18;;;;2281:32;;-1:-1:-1;;;2065:254:16:o;2506:328::-;2583:6;2591;2599;2652:2;2640:9;2631:7;2627:23;2623:32;2620:52;;;2668:1;2665;2658:12;2620:52;2691:29;2710:9;2691:29;:::i;:::-;2681:39;;2739:38;2773:2;2762:9;2758:18;2739:38;:::i;:::-;2729:48;;2824:2;2813:9;2809:18;2796:32;2786:42;;2506:328;;;;;:::o;2839:186::-;2898:6;2951:2;2939:9;2930:7;2926:23;2922:32;2919:52;;;2967:1;2964;2957:12;2919:52;2990:29;3009:9;2990:29;:::i;3030:510::-;3208:4;3193:20;;3197:9;3290:6;3166:4;3324:210;3338:4;3335:1;3332:11;3324:210;;;3411:13;;3404:21;3397:29;3385:42;;3450:4;3474:12;;;;3509:15;;;;3358:1;3351:9;3324:210;;;3328:3;;;3030:510;;;;:::o;3545:184::-;-1:-1:-1;;;3594:1:16;3587:88;3694:4;3691:1;3684:15;3718:4;3715:1;3708:15;3734:334;3805:2;3799:9;3861:2;3851:13;;-1:-1:-1;;3847:86:16;3835:99;;3964:18;3949:34;;3985:22;;;3946:62;3943:88;;;4011:18;;:::i;:::-;4047:2;4040:22;3734:334;;-1:-1:-1;3734:334:16:o;4073:466::-;4138:5;4172:18;4164:6;4161:30;4158:56;;;4194:18;;:::i;:::-;4232:116;4342:4;-1:-1:-1;;4268:2:16;4260:6;4256:15;4252:88;4248:99;4232:116;:::i;:::-;4223:125;;4371:6;4364:5;4357:21;4411:3;4402:6;4397:3;4393:16;4390:25;4387:45;;;4428:1;4425;4418:12;4387:45;4477:6;4472:3;4465:4;4458:5;4454:16;4441:43;4531:1;4524:4;4515:6;4508:5;4504:18;4500:29;4493:40;4073:466;;;;;:::o;4544:451::-;4613:6;4666:2;4654:9;4645:7;4641:23;4637:32;4634:52;;;4682:1;4679;4672:12;4634:52;4722:9;4709:23;4755:18;4747:6;4744:30;4741:50;;;4787:1;4784;4777:12;4741:50;4810:22;;4863:4;4855:13;;4851:27;-1:-1:-1;4841:55:16;;4892:1;4889;4882:12;4841:55;4915:74;4981:7;4976:2;4963:16;4958:2;4954;4950:11;4915:74;:::i;5000:632::-;5171:2;5223:21;;;5293:13;;5196:18;;;5315:22;;;5142:4;;5171:2;5394:15;;;;5368:2;5353:18;;;5142:4;5437:169;5451:6;5448:1;5445:13;5437:169;;;5512:13;;5500:26;;5581:15;;;;5546:12;;;;5473:1;5466:9;5437:169;;;-1:-1:-1;5623:3:16;;5000:632;-1:-1:-1;;;;;;5000:632:16:o;5637:952::-;5721:6;5752:2;5795;5783:9;5774:7;5770:23;5766:32;5763:52;;;5811:1;5808;5801:12;5763:52;5851:9;5838:23;5880:18;5921:2;5913:6;5910:14;5907:34;;;5937:1;5934;5927:12;5907:34;5975:6;5964:9;5960:22;5950:32;;6020:7;6013:4;6009:2;6005:13;6001:27;5991:55;;6042:1;6039;6032:12;5991:55;6078:2;6065:16;6100:2;6096;6093:10;6090:36;;;6106:18;;:::i;:::-;6152:2;6149:1;6145:10;6135:20;;6175:28;6199:2;6195;6191:11;6175:28;:::i;:::-;6237:15;;;6307:11;;;6303:20;;;6268:12;;;;6335:19;;;6332:39;;;6367:1;6364;6357:12;6332:39;6391:11;;;;6411:148;6427:6;6422:3;6419:15;6411:148;;;6493:23;6512:3;6493:23;:::i;:::-;6481:36;;6444:12;;;;6537;;;;6411:148;;;6578:5;5637:952;-1:-1:-1;;;;;;;;5637:952:16:o;6594:254::-;6662:6;6670;6723:2;6711:9;6702:7;6698:23;6694:32;6691:52;;;6739:1;6736;6729:12;6691:52;6775:9;6762:23;6752:33;;6804:38;6838:2;6827:9;6823:18;6804:38;:::i;:::-;6794:48;;6594:254;;;;;:::o;6853:347::-;6918:6;6926;6979:2;6967:9;6958:7;6954:23;6950:32;6947:52;;;6995:1;6992;6985:12;6947:52;7018:29;7037:9;7018:29;:::i;:::-;7008:39;;7097:2;7086:9;7082:18;7069:32;7144:5;7137:13;7130:21;7123:5;7120:32;7110:60;;7166:1;7163;7156:12;7110:60;7189:5;7179:15;;;6853:347;;;;;:::o;7205:248::-;7273:6;7281;7334:2;7322:9;7313:7;7309:23;7305:32;7302:52;;;7350:1;7347;7340:12;7302:52;-1:-1:-1;;7373:23:16;;;7443:2;7428:18;;;7415:32;;-1:-1:-1;7205:248:16:o;7458:667::-;7553:6;7561;7569;7577;7630:3;7618:9;7609:7;7605:23;7601:33;7598:53;;;7647:1;7644;7637:12;7598:53;7670:29;7689:9;7670:29;:::i;:::-;7660:39;;7718:38;7752:2;7741:9;7737:18;7718:38;:::i;:::-;7708:48;;7803:2;7792:9;7788:18;7775:32;7765:42;;7858:2;7847:9;7843:18;7830:32;7885:18;7877:6;7874:30;7871:50;;;7917:1;7914;7907:12;7871:50;7940:22;;7993:4;7985:13;;7981:27;-1:-1:-1;7971:55:16;;8022:1;8019;8012:12;7971:55;8045:74;8111:7;8106:2;8093:16;8088:2;8084;8080:11;8045:74;:::i;:::-;8035:84;;;7458:667;;;;;;;:::o;8130:260::-;8198:6;8206;8259:2;8247:9;8238:7;8234:23;8230:32;8227:52;;;8275:1;8272;8265:12;8227:52;8298:29;8317:9;8298:29;:::i;:::-;8288:39;;8346:38;8380:2;8369:9;8365:18;8346:38;:::i;8395:385::-;8481:6;8489;8497;8505;8558:3;8546:9;8537:7;8533:23;8529:33;8526:53;;;8575:1;8572;8565:12;8526:53;-1:-1:-1;;8598:23:16;;;8668:2;8653:18;;8640:32;;-1:-1:-1;8719:2:16;8704:18;;8691:32;;8770:2;8755:18;8742:32;;-1:-1:-1;8395:385:16;-1:-1:-1;8395:385:16:o;8785:437::-;8864:1;8860:12;;;;8907;;;8928:61;;8982:4;8974:6;8970:17;8960:27;;8928:61;9035:2;9027:6;9024:14;9004:18;9001:38;8998:218;;;-1:-1:-1;;;9069:1:16;9062:88;9173:4;9170:1;9163:15;9201:4;9198:1;9191:15;10885:184;-1:-1:-1;;;10934:1:16;10927:88;11034:4;11031:1;11024:15;11058:4;11055:1;11048:15;11074:195;11113:3;-1:-1:-1;;11137:5:16;11134:77;11131:103;;;11214:18;;:::i;:::-;-1:-1:-1;11261:1:16;11250:13;;11074:195::o;12707:184::-;-1:-1:-1;;;12756:1:16;12749:88;12856:4;12853:1;12846:15;12880:4;12877:1;12870:15;13257:424;13519:9;13514:3;13507:22;13489:3;13558:6;13552:13;13574:61;13628:6;13624:1;13619:3;13615:11;13608:4;13600:6;13596:17;13574:61;:::i;:::-;13655:16;;;;13673:1;13651:24;;13257:424;-1:-1:-1;;13257:424:16:o;14046:228::-;14086:7;14212:1;-1:-1:-1;;14140:74:16;14137:1;14134:81;14129:1;14122:9;14115:17;14111:105;14108:131;;;14219:18;;:::i;:::-;-1:-1:-1;14259:9:16;;14046:228::o;14279:184::-;-1:-1:-1;;;14328:1:16;14321:88;14428:4;14425:1;14418:15;14452:4;14449:1;14442:15;14468:120;14508:1;14534;14524:35;;14539:18;;:::i;:::-;-1:-1:-1;14573:9:16;;14468:120::o;20273:125::-;20313:4;20341:1;20338;20335:8;20332:34;;;20346:18;;:::i;:::-;-1:-1:-1;20383:9:16;;20273:125::o;20403:128::-;20443:3;20474:1;20470:6;20467:1;20464:13;20461:39;;;20480:18;;:::i;:::-;-1:-1:-1;20516:9:16;;20403:128::o;24089:276::-;24220:3;24258:6;24252:13;24274:53;24320:6;24315:3;24308:4;24300:6;24296:17;24274:53;:::i;:::-;24343:16;;;;;24089:276;-1:-1:-1;;24089:276:16:o;24370:1097::-;24455:12;;24420:3;;24510:1;24530:18;;;;24583;;;;24610:61;;24664:4;24656:6;24652:17;24642:27;;24610:61;24690:2;24738;24730:6;24727:14;24707:18;24704:38;24701:218;;;-1:-1:-1;;;24772:1:16;24765:88;24876:4;24873:1;24866:15;24904:4;24901:1;24894:15;24701:218;24935:18;24962:162;;;;25138:1;25133:328;;;;24928:533;;24962:162;-1:-1:-1;;24999:9:16;24995:82;24990:3;24983:95;25107:6;25102:3;25098:16;25091:23;;24962:162;;25133:328;25164:5;25161:1;25154:16;25211:2;25208:1;25198:16;25236:1;25250:165;25264:6;25261:1;25258:13;25250:165;;;25342:14;;25329:11;;;25322:35;25385:16;;;;25279:10;;25250:165;;;25254:3;;25444:6;25439:3;25435:16;25428:23;;24928:533;;;;;;;24370:1097;;;;:::o;25472:376::-;25648:3;25676:38;25710:3;25702:6;25676:38;:::i;:::-;25743:6;25737:13;25759:52;25804:6;25800:2;25793:4;25785:6;25781:17;25759:52;:::i;:::-;25827:15;;25472:376;-1:-1:-1;;;;25472:376:16:o;25853:640::-;26133:3;26171:6;26165:13;26187:53;26233:6;26228:3;26221:4;26213:6;26209:17;26187:53;:::i;:::-;26303:13;;26262:16;;;;26325:57;26303:13;26262:16;26359:4;26347:17;;26325:57;:::i;:::-;26447:10;26404:20;;26433:25;;;26485:1;26474:13;;25853:640;-1:-1:-1;;;;25853:640:16:o;26498:519::-;26775:3;26803:38;26837:3;26829:6;26803:38;:::i;:::-;26861:5;26857:2;26850:17;26896:6;26890:13;26912:60;26965:6;26961:1;26957:2;26953:10;26946:4;26938:6;26934:17;26912:60;:::i;:::-;26992:15;27009:1;26988:23;;26498:519;-1:-1:-1;;;;26498:519:16:o;27022:796::-;27385:66;27380:3;27373:79;27482:66;27477:2;27472:3;27468:12;27461:88;27355:3;27578:6;27572:13;27594:60;27647:6;27642:2;27637:3;27633:12;27628:2;27620:6;27616:15;27594:60;:::i;:::-;27718:66;27713:2;27673:16;;;;27705:11;;;27698:87;-1:-1:-1;27809:2:16;27801:11;;27022:796;-1:-1:-1;27022:796:16:o;28103:2110::-;28936:3;28974:6;28968:13;28990:53;29036:6;29031:3;29024:4;29016:6;29012:17;28990:53;:::i;:::-;29106:13;;29065:16;;;;29128:57;29106:13;29065:16;29162:4;29150:17;;29128:57;:::i;:::-;29250:66;29207:20;;29236:81;;;29342:13;;29364:68;29342:13;29416:4;29405:16;;;;29386:17;;29364:68;:::i;:::-;29502:66;29451:20;;29495:4;29487:13;;29480:89;;;;29598:66;29593:2;29585:11;;29578:87;29694:66;29689:2;29681:11;;29674:87;29790:66;29785:2;29777:11;;29770:87;29887:66;29881:3;29873:12;;29866:88;29984:66;29978:3;29970:12;;29963:88;30081:66;30075:3;30067:12;;30060:88;27900:66;30202:3;30194:12;;27888:79;27997:66;27983:12;;;27976:88;28080:12;;;30164:43;30157:50;28103:2110;-1:-1:-1;;;;;;28103:2110:16:o;30218:341::-;30481:9;30476:3;30469:22;30451:3;30507:46;30550:1;30545:3;30541:11;30533:6;30507:46;:::i;30564:512::-;30758:4;-1:-1:-1;;;;;30868:2:16;30860:6;30856:15;30845:9;30838:34;30920:2;30912:6;30908:15;30903:2;30892:9;30888:18;30881:43;;30960:6;30955:2;30944:9;30940:18;30933:34;31003:3;30998:2;30987:9;30983:18;30976:31;31024:46;31065:3;31054:9;31050:19;31042:6;31024:46;:::i;31081:249::-;31150:6;31203:2;31191:9;31182:7;31178:23;31174:32;31171:52;;;31219:1;31216;31209:12;31171:52;31251:9;31245:16;31270:30;31294:5;31270:30;:::i;31335:2685::-;32885:3;32880;32873:16;32918:66;32914:1;32909:3;32905:11;32898:87;32855:3;33004:46;33047:1;33042:3;33038:11;33030:6;33004:46;:::i;:::-;33069:66;33155:2;33151;33144:14;33186:66;33182:1;33178:2;33174:10;33167:86;33272:46;33314:2;33310;33306:11;33298:6;33272:46;:::i;:::-;33262:56;;33338:2;33334;33327:14;33369:66;33365:1;33361:2;33357:10;33350:86;33455:46;33497:2;33493;33489:11;33481:6;33455:46;:::i;:::-;33445:56;;33521:4;33517:2;33510:16;33554:66;33550:1;33546:2;33542:10;33535:86;33640:46;33682:2;33678;33674:11;33666:6;33640:46;:::i;:::-;33695:14;;;33737:66;33733:1;33725:10;;33718:86;33630:56;-1:-1:-1;33823:46:16;33865:2;33857:11;;33849:6;33823:46;:::i;:::-;33889:66;33878:78;;33984:3;33980:1;33972:10;;33965:23;34012:1;34004:10;;31335:2685;-1:-1:-1;;;;;;;;31335:2685:16:o;34025:112::-;34057:1;34083;34073:35;;34088:18;;:::i;:::-;-1:-1:-1;34122:9:16;;34025:112::o;34524:418::-;34786:3;34781;34774:16;34756:3;34819:6;34813:13;34835:61;34889:6;34885:1;34880:3;34876:11;34869:4;34861:6;34857:17;34835:61;:::i;:::-;34916:16;;;;34934:1;34912:24;;34524:418;-1:-1:-1;;34524:418:16:o;34947:419::-;35209:4;35204:3;35197:17;35179:3;35243:6;35237:13;35259:61;35313:6;35309:1;35304:3;35300:11;35293:4;35285:6;35281:17;35259:61;:::i;:::-;35340:16;;;;35358:1;35336:24;;34947:419;-1:-1:-1;;34947:419:16:o;35371:418::-;35633:3;35628;35621:16;35603:3;35666:6;35660:13;35682:61;35736:6;35732:1;35727:3;35723:11;35716:4;35708:6;35704:17;35682:61;:::i;35794:184::-;-1:-1:-1;;;35843:1:16;35836:88;35943:4;35940:1;35933:15;35967:4;35964:1;35957:15

Swarm Source

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